Skip to content
Permalink
Browse files

[6.d] Set non-DefiniteHOW default default for DefiniteHOWs

Per 6.d-prep[^1]: On :U/:D type constrained variables, params, attributes,
and parametarized Arrays/Hashes, use the base type as the default
default in 6.d instead of continuing to use the uninitializeable
DefiniteHOW as the type, which prevents use of `.=` and other constructs.

Fixes R#1493. Does not address enums, which is currently blocked by R#2297

[1] https://github.com/perl6/6.d-prep/blob/dffa2642419a0f481591b9b64b602bfc4c4eb66b/TODO/FEATURES.md#make-default-defaults-for-definitehows-be-normal-types
[2] #1493
[3] #2297
  • Loading branch information...
zoffixznet committed Sep 20, 2018
1 parent 1ff9fa3 commit 38b198c9928580ad9d9ff48c12c7205fbe2e8ec1
Showing with 29 additions and 11 deletions.
  1. +8 −4 src/Perl6/Actions.nqp
  2. +12 −3 src/Perl6/World.nqp
  3. +9 −4 src/core/Exception.pm6
@@ -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;
@@ -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.
@@ -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 {

0 comments on commit 38b198c

Please sign in to comment.
You can’t perform that action at this time.