{"atom":"regression/definiteness-types-and-runtime-classes","family":"regression","slug":"definiteness-types-and-runtime-classes","header":{"atom":"regression/definiteness-types-and-runtime-classes","kind":"whole-program — a minimal repro, not yet reduced to an atom","source":"curated"},"axes":null,"cols":null,"engines":["rakudo-2026.07","rakupp-3.14.0"],"kinds":["ref","pp"],"defFrom":"rakupp:t/regression/definiteness-types-and-runtime-classes.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/definiteness-types-and-runtime-classes.grid"],"records":[["0001","","# Regression: the type SMILEY as a first-class type, and creating a class at\n# runtime through the metamodel.\n#   * `Foo:D` / `Foo:U` in TERM position parsed and then threw the smiley away,\n#     so the constraint existed only inside a signature. It rides on the type\n#     value now, which is what lets `.^name` report it, smartmatch test\n#     definedness alongside the type, and `.^base_type` strip it back off.\n#   * `Metamodel::ClassHOW.new_type(:name, :ver, :auth)` registers a class the\n#     same way a declared one is registered, so `.^add_method` and `.new` work on\n#     it afterwards.\n#   * the HOW spellings take the type as their FIRST argument\n#     (`$t.HOW.add_method($t, …)`) where `.^` passes it implicitly. Forwarding\n#     them is named to the MOP operations explicitly: a metaclass also answers\n#     ORDINARY methods (`.isa`, `.gist`), and forwarding those to their argument\n#     cut S24-testing/1-basic.t from 39 emitted tests to 15 — which is why the\n#     forwarding is an allow-list rather than \"anything with a type argument\".\n# Contract: exit 0 + last line PASS.\nmy @fail;\nsub check($got, $want, $what) { @fail.push(\"$what: got $got want $want\") unless $got eq $want }\n\n# the smiley is part of the type\ncheck(Any:D.^name, 'Any:D', 'a defined-only type names itself');\ncheck(Any:U.^name, 'Any:U', 'and a type-object-only one');\ncheck(Any:_.^name, 'Any',   'the explicit any-definiteness smiley adds nothing');\ncheck(Int:D.^name, 'Int:D', 'it works on any type');\ncheck(Any:D.^base_type.^name, 'Any', 'base_type strips it');\ncheck(Int:D.^base_type.^name, 'Int', 'for any type');\ncheck(Any.^name,   'Any',   'a plain type object is unaffected');\n\n# smartmatch tests definedness as well as type\ncheck((Any     ~~ Any:D).gist, 'False', 'a type object is not defined');\ncheck((Any     ~~ Any:U).gist, 'True',  'but it is a type object');\ncheck((Any     ~~ Any:_).gist, 'True',  'and matches either way');\ncheck((Any.new ~~ Any:D).gist, 'True',  'an instance is defined');\ncheck((Any.new ~~ Any:U).gist, 'False', 'and is not a type object');\ncheck((Any.new ~~ Any:_).gist, 'True',  'and matches either way too');\ncheck((5   ~~ Int:D).gist,     'True',  'a defined int');\ncheck((Int ~~ Int:D).gist,     'False', 'an undefined one');\ncheck((5   ~~ Str:D).gist,     'False', 'the type still has to match');\n# the signature form, which already worked, keeps working\nsub takes-defined(Int:D $x) { $x }\ncheck(takes-defined(3),                 '3',     'a defined argument binds');\ncheck((try takes-defined(Int)).defined, 'False', 'an undefined one does not');\nmy Int:D $constrained = 5;\ncheck($constrained, '5', 'a constrained container holds a value');\n\n# a class made at runtime\nmy $type = Metamodel::ClassHOW.new_type(name => \"NewType\", ver => v0.0.1, auth => 'github:raku');\ncheck($type.^name, 'NewType', 'the new type is named');\n$type.HOW.add_method($type, \"hey\", method { 'Hey' });\ncheck($type.hey, 'Hey', 'a method added through the HOW is callable on the type');\n$type.HOW.compose($type);\ncheck($type.new.hey, 'Hey', 'and on an instance');\n# a metaclass still answers its OWN ordinary methods rather than forwarding them\ncheck(Int.HOW.^name.contains('ClassHOW'), 'True', 'a metaclass answers its own meta-methods');\ncheck(Int.^name, 'Int', 'and the ordinary meta-methods are unaffected');\n\nif @fail { note \"FAILED: @fail.join('; ')\"; say 'FAIL' } else { say 'PASS' }","output PASS","a",["PASS","PASS"],0,[["budget","20s"]]]]}