Skip to content

Instantly share code, notes, and snippets.

@zoffixznet
Created September 20, 2018 18:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoffixznet/0c6a46a1e658179fded379855fe4412c to your computer and use it in GitHub Desktop.
Save zoffixznet/0c6a46a1e658179fded379855fe4412c to your computer and use it in GitHub Desktop.
diff --git a/src/Perl6/Actions.nqp b/src/Perl6/Actions.nqp
index 303c0f5..720bc17 100644
--- a/src/Perl6/Actions.nqp
+++ b/src/Perl6/Actions.nqp
@@ -3572,7 +3572,7 @@ class Perl6::Actions is HLL::Actions does STDActions {
}
elsif $<initializer><sym> eq '.=' {
my $type := nqp::defined($*OFTYPE)
- ?? $*OFTYPE.ast !! $*W.find_symbol: ['Any'];
+ ?? $*W.maybe-definite-how-base($*OFTYPE.ast) !! $*W.find_symbol: ['Any'];
my $dot_equals := $initast;
$dot_equals.unshift(QAST::WVal.new(:value($type)));
$dot_equals.returns($type);
@@ -3723,7 +3723,7 @@ class Perl6::Actions is HLL::Actions does STDActions {
$init-qast.unshift:
QAST::WVal.new: value => nqp::defined($*OFTYPE)
- ?? $*OFTYPE.ast !! $*W.find_symbol: ['Mu']
+ ?? $*W.maybe-definite-how-base($*OFTYPE.ast) !! $*W.find_symbol: ['Mu']
if $<term_init><sym> eq '.=';
my $qast;
@@ -5324,9 +5324,13 @@ class Perl6::Actions is HLL::Actions does STDActions {
my $Mu := $W.find_symbol: ['Mu'];
my $type := nqp::defined($*OFTYPE) ?? $*OFTYPE.ast !! $Mu;
if $<initializer><sym> eq '.=' {
- $value_ast.unshift(QAST::WVal.new(:value($type)));
+ my $init-type := $*W.maybe-definite-how-base: $type;
+ $value_ast.unshift: QAST::WVal.new: :value($init-type);
+ $value_ast.returns: $init-type;
+ }
+ else {
+ $value_ast.returns($type);
}
- $value_ast.returns($type);
my $con_block := $W.pop_lexpad();
my $value;
@@ -5344,7 +5348,7 @@ class Perl6::Actions is HLL::Actions does STDActions {
nqp::istype($value, $expected)
|| $W.throw: $/, 'X::TypeCheck', :operation(
"constant declaration of " ~ ($name || '<anon>')
- ), :$expected, :got($W.find_symbol: [$value.HOW.name: $value]);
+ ), :$expected, :got($value);
}
sub check-type-maybe-coerce($meth, $expected) {
unless nqp::istype($value, $expected) {
diff --git a/src/Perl6/World.nqp b/src/Perl6/World.nqp
index 13911c8..c4034b3 100644
--- a/src/Perl6/World.nqp
+++ b/src/Perl6/World.nqp
@@ -1661,7 +1661,7 @@ class Perl6::World is HLL::World {
%info<bind_constraint> := self.parameterize_type_with_args($/,
%info<bind_constraint>, [$vtype], nqp::hash());
%info<value_type> := $vtype;
- %info<default_value> := $vtype;
+ %info<default_value> := self.maybe-definite-how-base: $vtype;
}
else {
%info<container_type> := %info<container_base>;
@@ -1728,7 +1728,8 @@ class Perl6::World is HLL::World {
%info<bind_constraint> := self.parameterize_type_with_args($/,
%info<bind_constraint>, @value_type, nqp::hash());
%info<value_type> := @value_type[0];
- %info<default_value> := @value_type[0];
+ %info<default_value>
+ := self.maybe-definite-how-base: @value_type[0];
}
else {
%info<container_type> := %info<container_base>;
@@ -1769,7 +1770,8 @@ class Perl6::World is HLL::World {
if @value_type {
%info<bind_constraint> := @value_type[0];
%info<value_type> := @value_type[0];
- %info<default_value> := @value_type[0];
+ %info<default_value>
+ := self.maybe-definite-how-base: @value_type[0];
}
else {
%info<bind_constraint> := self.find_symbol(['Mu'], :setting-only);
@@ -1780,6 +1782,13 @@ class Perl6::World is HLL::World {
}
%info
}
+ method maybe-definite-how-base ($v) {
+ # returns the value itself, unless it's a DefiniteHOW, in which case,
+ # it returns its base type. Behaviour available in 6.d and later only.
+ ! $*W.lang-ver-before('d') && nqp::eqaddr($v.HOW,
+ $*W.find_symbol: ['Metamodel','DefiniteHOW'], :setting-only
+ ) ?? $v.HOW.base_type: $v !! $v
+ }
# Installs one of the magical lexicals ($_, $/ and $!). Uses a cache to
# avoid massive duplication of containers and container descriptors.
diff --git a/src/core/Exception.pm6 b/src/core/Exception.pm6
index 19241d2..c391d33 100644
--- a/src/core/Exception.pm6
+++ b/src/core/Exception.pm6
@@ -2289,11 +2289,16 @@ my class X::TypeCheck::Assignment is X::TypeCheck {
method message {
my $to = $.symbol.defined && $.symbol ne '$'
?? " to $.symbol" !! "";
- my $expected = $.expected =:= $.got
- ?? "expected type $.expectedn cannot be itself " ~
- "(perhaps Nil was assigned to a :D which had no default?)"
+ my $is-itself := $.expected =:= $.got;
+ my $expected = $is-itself
+ ?? "expected type $.expectedn cannot be itself"
!! "expected $.expectedn but got $.gotn";
- self.priors() ~ "Type check failed in assignment$to; $expected";
+ my $maybe-Nil := $is-itself
+ || nqp::istype($.expected.HOW, Metamodel::DefiniteHOW)
+ && $.expected.^base_type =:= $.got
+ ?? ' (perhaps Nil was assigned to a :D which had no default?)' !! '';
+
+ self.priors() ~ "Type check failed in assignment$to; $expected$maybe-Nil"
}
}
my class X::TypeCheck::Argument is X::TypeCheck {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment