Skip to content

Commit

Permalink
Make EnumType($mixin-value) work again
Browse files Browse the repository at this point in the history
Fixes S12-enums/pseudo-functional.t broken by previous commits.

The idea is that if an enum is mixed into a value then for any
`EnumType(value)` case we first try to pull out the enum from the mixin
and use it.
  • Loading branch information
vrurg committed Dec 21, 2020
1 parent bcb9a2c commit e44b524
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/Perl6/Metamodel/EnumHOW.nqp
Expand Up @@ -92,7 +92,7 @@ class Perl6::Metamodel::EnumHOW
}
nqp::existskey(%!value_to_enum, $value)
?? %!value_to_enum{$value}
!! $obj.WHAT;
!! nqp::null()
}

method enum_value_list($obj) {
Expand Down
32 changes: 23 additions & 9 deletions src/core.c/Enumeration.pm6
@@ -1,3 +1,4 @@
my class X::Enum::NoValue {...};
# Method that we have on enumeration types.
my role Enumeration {
has $.key;
Expand Down Expand Up @@ -32,18 +33,31 @@ my role Enumeration {

multi method ACCEPTS(::?CLASS:D: ::?CLASS:D \v) { self === v }

method !FROM-VALUE(|) {
my $x := nqp::atpos(nqp::p6argvmarray(), 1).AT-POS(0);
nqp::istype($x, ::?CLASS)
?? $x
!! self.^enum_from_value($x)
method !FROM-VALUE(Mu \val) {
my $res := Nil;
my $dcval := nqp::decont(val);
# If value is a mixin of enum try to pull out the mixed in value first
if $dcval.^is_mixin {
my $attr_name := '$!' ~ self.^name;
if $dcval.^has_attribute($attr_name) {
my $mixin_value := nqp::getattr($dcval, $dcval.WHAT, $attr_name);
return $mixin_value if nqp::istype($mixin_value, ::?CLASS);
}
}
if nqp::istype($dcval, ::?CLASS) {
$res := $dcval;
}
elsif nqp::isconcrete($dcval) {
$res := self.^enum_from_value($dcval);
}
$res // Failure.new(X::Enum::NoValue.new(:type(self.WHAT), :value($dcval)))
}

proto method CALL-ME(|) {*}
multi method CALL-ME(|c) { self!FROM-VALUE(|c) }
proto method CALL-ME(Mu) {*}
multi method CALL-ME(Mu \val) { self!FROM-VALUE(val) }

proto method COERCE(|) {*}
multi method COERCE(|c) { self!FROM-VALUE(|c) }
proto method COERCE(Mu) {*}
multi method COERCE(Mu \val) { self!FROM-VALUE(val) }

method pred(::?CLASS:D:) {
nqp::getattr_i(self,::?CLASS,'$!index')
Expand Down
4 changes: 2 additions & 2 deletions src/core.c/Exception.pm6
Expand Up @@ -2773,10 +2773,10 @@ my class X::Numeric::Confused is Exception {
}

my class X::Enum::NoValue is Exception {
has Mu $.enum is required;
has Mu $.type is required;
has $.value is required;
method message {
"No value '" ~ $!value ~ "' found in enum " ~ $!enum.^name
"No value '" ~ $!value ~ "' found in enum " ~ $!type.^name
}
}

Expand Down

0 comments on commit e44b524

Please sign in to comment.