Skip Menu |
Report information
Id: 124226
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: masak <cmasak [at] gmail.com>
Cc:
AdminCc:

Severity: (no value)
Tag: Bug
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: [BUG] Opportunity to catch syntactically detectable calls to attribute-accessing methods on type objects in Rakudo
To: rakudobug [...] perl.org
Date: Wed, 1 Apr 2015 22:19:12 +0200
From: Carl Mäsak <cmasak [...] gmail.com>
Download (untitled) / with headers
text/plain 2.4k
<[Tux]> m: class C { has Int $!x; method foo { ($!x, my $b) = (1,2);}};C.foo 19:45 <+camelia> rakudo-moar 6caf1d: OUTPUT«Cannot look up attributes in a type object␤ in method foo [...] <[Tux]> is that explainable? <masak> you're calling C.foo, the .foo method on the type object C <masak> the type object doesn't really properly have an $!x <masak> m: class C { has Int $!x; method foo { ($!x, my $b) = (1,2);}}; C.new.foo <camelia> rakudo-moar 6caf1d: ( no output ) <masak> that works. <TimToady> "Cannot look up attributes in a type object" is an implementor-centric error message, not a user-centric one <Juerd> TimToady: "Instance attribute used in non-instance method call"? :) <masak> TimToady: actually, that error message could fail statically in this case. <masak> since C is already resolved at compile time. <masak> no need to make it survive until runtime and then fail. [...] <masak> no-one else liked the idea of statically erroring out with "call will never work" for the C.foo case where C is already statically resolved? <nine_> masak: I do <Juerd> masak: Could work, but can't methods be marked as instance-only? <nine_> masak: the earlier errors are reported the better <PerlJam> masak: How does the compiler decide that it will never work? and when? <Juerd> Because then, any use of $!foo could simply mark the method as instance-only <Juerd> And the error message could be simpler. <Juerd> "Method foo can only be called on an instance of C, not on C itself." <PerlJam> (compiler hints)++ if we can reasonably have them. <PerlJam> I guess, if you declare the sig right, all the info is easy to get at. But without that, it seems like a bit of guessing for the compiler to do it. <masak> PerlJam: compiler sees the call C.foo, and has already set a flag that the foo method in class C accesses an attribute. boom. * masak submits rakudobug <Juerd> "Method foo can only be called on an instance of C, not on C itself, because C.foo accesses instance attribute $!x." <masak> neat. +1 <PerlJam> masak: flagging methods like that seems like quite a bit of bookkeeping for marginal benefit. <masak> really? seems worth it to me... <masak> it's a small hash somewhere in the compiler. <masak> %accattr<C.foo> = True; <Juerd> It could be a boolean flag (instance-only) and an array of further explanations <[Coke]> masak: I think you mean a compile-time static check, not a static static check. ;) <masak> [Coke]: yes. thank you. I meant... that, what you said.
Still reproducible (2017.11,HEAD(e5b660e))

On 2015-04-01 13:19:33, masak wrote:
Show quoted text
> <[Tux]> m: class C { has Int $!x; method foo { ($!x, my $b) =
> (1,2);}};C.foo
> 19:45 <+camelia> rakudo-moar 6caf1d: OUTPUT«Cannot look up attributes
> in a type object␤ in method foo [...]
> <[Tux]> is that explainable?
> <masak> you're calling C.foo, the .foo method on the type object C
> <masak> the type object doesn't really properly have an $!x
> <masak> m: class C { has Int $!x; method foo { ($!x, my $b) =
> (1,2);}}; C.new.foo
> <camelia> rakudo-moar 6caf1d: ( no output )
> <masak> that works.
> <TimToady> "Cannot look up attributes in a type object" is an
> implementor-centric error message, not a user-centric one
> <Juerd> TimToady: "Instance attribute used in non-instance method
> call"? :)
> <masak> TimToady: actually, that error message could fail statically
> in this case.
> <masak> since C is already resolved at compile time.
> <masak> no need to make it survive until runtime and then fail.
> [...]
> <masak> no-one else liked the idea of statically erroring out with
> "call will never work" for the C.foo case where C is already
> statically resolved?
> <nine_> masak: I do
> <Juerd> masak: Could work, but can't methods be marked as instance-
> only?
> <nine_> masak: the earlier errors are reported the better
> <PerlJam> masak: How does the compiler decide that it will never work?
> and when?
> <Juerd> Because then, any use of $!foo could simply mark the method as
> instance-only
> <Juerd> And the error message could be simpler.
> <Juerd> "Method foo can only be called on an instance of C, not on C
> itself."
> <PerlJam> (compiler hints)++ if we can reasonably have them.
> <PerlJam> I guess, if you declare the sig right, all the info is easy
> to get at. But without that, it seems like a bit of guessing for the
> compiler to do it.
> <masak> PerlJam: compiler sees the call C.foo, and has already set a
> flag that the foo method in class C accesses an attribute. boom.
> * masak submits rakudobug
> <Juerd> "Method foo can only be called on an instance of C, not on C
> itself, because C.foo accesses instance attribute $!x."
> <masak> neat. +1
> <PerlJam> masak: flagging methods like that seems like quite a bit of
> bookkeeping for marginal benefit.
> <masak> really? seems worth it to me...
> <masak> it's a small hash somewhere in the compiler.
> <masak> %accattr<C.foo> = True;
> <Juerd> It could be a boolean flag (instance-only) and an array of
> further explanations
> <[Coke]> masak: I think you mean a compile-time static check, not a
> static static check. ;)
> <masak> [Coke]: yes. thank you. I meant... that, what you said.




This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org