Skip to content

Commit

Permalink
Make has Str $.a = 42 a compile time failure
Browse files Browse the repository at this point in the history
- adapts default BUILDPLAN logic to perform some type tests
- adds X::TypeCheck::Attribute::Default class
- adds X::TypeCheck::Attribute::Default stub for setting compilation
  • Loading branch information
lizmat committed Jan 28, 2020
1 parent 14abd58 commit d8e859d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 1 deletion.
37 changes: 36 additions & 1 deletion src/Perl6/Metamodel/BUILDPLAN.nqp
Expand Up @@ -124,12 +124,47 @@ role Perl6::Metamodel::BUILDPLAN {
for @attrs {
if nqp::can($_, 'build') {
my $default := $_.build;
my int $primspec := nqp::objprimspec($_.type);
my $type := $_.type;
my int $primspec := nqp::objprimspec($type);
#?if js
my int $is_oversized_int := $primspec == 4 || $primspec == 5;
$primspec := $is_oversized_int ?? 0 !! $primspec;
#?endif

# compile check constants for correct type
if nqp::isconcrete($default) {
if $default.HOW.name($default) eq 'Method' {
# cannot typecheck code to be run later
}
elsif $primspec {
# add typecheck on natives
}
elsif nqp::istype($default,$type) {
# type checks out ok
}
elsif nqp::istype($type,$*W.find_symbol(["Associative"])) {
# cannot do type checks on associatives
}
elsif nqp::istype(
$type,
my $Positional := $*W.find_symbol(["Positional"])
) && nqp::istype($default,$Positional.of) {
# type of positional checks out ok
}
else {
# constant value did not typecheck ok
my $typecheck := $*W.find_symbol(["X","TypeCheck","Attribute","Default"]);
if nqp::can($typecheck,'new') {
$typecheck.new(
operation => $_.is_bound ?? 'bind' !! 'assign',
name => $_.name,
got => $default,
expected => $type,
).throw;
}
}

# all ok, push the action
nqp::push(@plan,[
($primspec || !$_.is_bound ?? 4 + $primspec !! 14),
$obj,
Expand Down
9 changes: 9 additions & 0 deletions src/core.c/Exception.pm6
Expand Up @@ -2367,6 +2367,15 @@ my class X::TypeCheck::Argument is X::TypeCheck {
}
}

my class X::TypeCheck::Attribute::Default is X::TypeCheck does X::Comp {
has str $.name;
has $.operation;
method message {
self.priors() ~
"Can never $.operation default value $.gotn to attribute '$.name', it expects: $.expectedn"
}
}

my class X::TypeCheck::Splice is X::TypeCheck does X::Comp {
has $.action;
method message {
Expand Down
1 change: 1 addition & 0 deletions src/core.c/core_prologue.pm6
Expand Up @@ -26,6 +26,7 @@ my class WhateverCode { ... }
my class X::Attribute::Required { ... }
my class X::Numeric::Overflow { ... }
my class X::Numeric::Underflow { ... }
my class X::TypeCheck::Attribute::Default { ... }

# Stub these or we can't use any sigil other than $.
my role Positional { ... }
Expand Down

0 comments on commit d8e859d

Please sign in to comment.