# New Ticket Created by  "Carl Mäsak" 
# Please include the string:  [perl #123583]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=123583 >


<masak> here: https://gist.github.com/masak/406d687c3e4e0684c013

Inlined here for your benefit:

$ cat X.pm
enum X is export <A B>;
$ cat Y.pm
enum Y is export <B W>;
$ perl6 -I. -e 'use X; use Y'
===SORRY!===
Merging GLOBAL symbols failed: duplicate definition of symbol B

<masak> by my reading of S12, this should work, but then you're not
allowed to refer to just `B`; you have to say `X::B` or `Y::B`.
<masak> (and if you also import a `sub B { ... }` from somewhere, it
takes precedence and "un-poisons" the slot for itself)
<moritz> that takes slot &B
<masak> no doubt -- but I'm talking about what happens when you write
`B` in code after that.
<masak> if the sub has been imported, that's a call to `&B`.
<moritz> that should resolve to &B, yes
* moritz skims S12
<masak> but if it hasn't, then it's still a compile-time error,
because it's not clear if you're referring to `X::B` or `Y::B`.
<moritz> Since there is an enum C<OK>, the function C<OK> may only be
<moritz> called using parentheses, never in list operator form.
<moritz> so you'd be able to call B() when the B slot is poisoned, but
not just 'B args', iiuc
<moritz> ah yes
<moritz> "If there is
<moritz> a collision on two enum values that cancels them both, the function
<moritz> still may only be called with parentheses, since the enum key
<moritz> is "poisoned"."
<masak> right.
<masak> that's the only reference to the concept of poisoning I've found.
<masak> it mentions the effect in passing, but it's pretty clear about it.
* masak submits rakudobug
<moritz> masak: S12 doesn't talk about in which circumstances
poisoning, so I'd assume it happens everywhere
<moritz> so, also in importation/exportation
<masak> moritz: ah, you mean between any two imported symbols?
<masak> moritz: that's very possible.
<moritz> masak: no
<masak> moritz: but enum values are a bit special in that they're
essentially short-form aliases for their real unambiguous names.
<masak> moritz: like, `True` is short for `Bool::True`.
<moritz> yes
<moritz> masak: I mean between two imported enum items vs. two
declared-here enum items
<masak> moritz: oh, that's entirely possible, yes.
<masak> moritz: though I could equally well argue that the
declared-here enum value takes precedence...
<moritz> with "everywhere" I meant "at declaration and at {ex,im}portation"
<masak> declaring something feels like much more of a "conscious act"
than importation.
<masak> like, you might not know you're importing a `B`, but you
definitely know you're declaring one!

To summarize: the error message "Merging GLOBAL symbols failed:
duplicate definition of symbol B" on importing Y.pm is wrong. That
should work without an error. Referring to `B` after that in code
should be a (compile-time) error, though. This is the "poisoning"
effect referred to by S12.

The rest of the discussion is pertinent, but doesn't figure in the
closability of this ticket.

Reply via email to