Skip to content

Commit

Permalink
Fix $obj.Some::Role::meth(...).
Browse files Browse the repository at this point in the history
Previously, it did not convey the correct self, since it relied on the
punning mechanism, which must invoke on the pun. Now it's fixed to do
the right thing.
  • Loading branch information
jnthn committed Jan 9, 2013
1 parent af76e6d commit b22982b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
14 changes: 13 additions & 1 deletion src/Perl6/Metamodel/ClassHOW.pm
Expand Up @@ -21,6 +21,7 @@ class Perl6::Metamodel::ClassHOW
{
has @!roles;
has @!role_typecheck_list;
has @!concretizations;
has @!fallbacks;
has $!composed;

Expand Down Expand Up @@ -87,7 +88,9 @@ class Perl6::Metamodel::ClassHOW
my $r := @roles_to_compose.pop();
@!roles[+@!roles] := $r;
@!role_typecheck_list[+@!role_typecheck_list] := $r;
@ins_roles.push($r.HOW.specialize($r, $obj))
my $ins := $r.HOW.specialize($r, $obj);
@ins_roles.push($ins);
nqp::push(@!concretizations, [$r, $ins]);
}
self.compute_mro($obj); # to the best of our knowledge, because the role applier wants it.
RoleToClassApplier.apply($obj, @ins_roles);
Expand Down Expand Up @@ -185,6 +188,15 @@ class Perl6::Metamodel::ClassHOW
@!role_typecheck_list
}

method concretization($obj, $ptype) {
for @!concretizations {
if pir::perl6_decontainerize__PP($_[0]) =:= pir::perl6_decontainerize__PP($ptype) {
return $_[1];
}
}
nqp::die("No concretization found for " ~ $ptype.HOW.name($ptype));
}

method is_composed($obj) {
$!composed
}
Expand Down
13 changes: 13 additions & 0 deletions src/Perl6/Metamodel/MROBasedMethodDispatch.pm
Expand Up @@ -18,6 +18,19 @@ role Perl6::Metamodel::MROBasedMethodDispatch {
nqp::null();
}

method find_method_qualified($obj, $qtype, $name) {
if $qtype.HOW.archetypes.parametric && nqp::can(self, 'concretization') {
# Resolve it via the concrete form of this parametric.
my $conc := self.concretization($obj, $qtype);
$conc.HOW.method_table($conc){$name}
}
else {
# Non-parametric, so just locate it from the already concrete
# type (or fallback to this if no .concretization on ourself).
nqp::findmethod($qtype, $name)
}
}

method publish_method_cache($obj) {
# Walk MRO and add methods to cache, unless another method
# lower in the class hierarchy "shadowed" it.
Expand Down
2 changes: 1 addition & 1 deletion src/core/Mu.pm
Expand Up @@ -315,7 +315,7 @@ my class Mu {

).throw;
}
nqp::findmethod($type, $name)(SELF, |c)
self.HOW.find_method_qualified(self, $type, $name)(SELF, |c)
}

method dispatch:<!>(Mu \SELF: $name, Mu $type, |c) is rw is hidden_from_backtrace {
Expand Down

0 comments on commit b22982b

Please sign in to comment.