-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loop label hides variables with same name #12512
Comments
Oh dear, this is bad. #12488 claims its first victim. |
I think this should be as "simple" as making sure the renaming for lifetime variables only renames lifetime variables, and then the renaming for local variables only renaming non-lifetime-idents. |
Some discussions on IRC:
|
@huonw, it is more complicated. In token level, a label is a This really is the identity (no pun intended) crisis for poor labels. |
Well, what I said would semantically be a fix; it might not correspond exactly to how the code is structured in the compiler at the moment (one way would be detecting whether you're rewriting a |
That's exactly what annoys me now. Given the recursive nature of AST traversing, it is not clear how to distinguish one modification from another. (In the end, they are all |
You could lift the renaming up one level, so it happens in Or, add a "ident source" field to enum IdentSource {
PathSegment,
TypeParam,
Lifetime,
LoopLabel,
} and then adjusting the folder to pass this down into each (Also rather ugly, but probably less error prone.) |
Will it be sufficient to also address your concern about hygienic lifetimes? |
I guess it will, if support for hygienic lifetimes is added. |
To be honest I feel a bit unsettled. It looks like a typical impedance mismatch somewhere in the parsing pipeline although I couldn't really put my finger on it, yet. |
(Hm, I guess such a fine-grained |
Then it won't be able to handle label vs. true lifetime if we are to add hygienic lifetimes. |
I think that's a fundamental problem that we can't solve; but, in any case, it doesn't seem unreasonable for all |
How about pub struct Ident {
name: Name,
ctxt: SyntaxContext,
kind: IdentKind
}
pub enum IdentKind {
PlainIdent,
LifetimeIdent
} Will this somehow intervene with codegen, which I haven't had a chance to look into? |
That makes every |
Another (hopefully better) idea. There are two separated concerns here, AST shape and hygiene. They are orthogonal to each other so we treat them as such. Keep current AST nodes intact but make pub enum IdentKind {
PlainIdent,
LifetimeIdent
}
mtwt_resolve(...) => mtwt_resolve(..., IdentKind)
new_rename(...) => new_rename(..., IdentLind)
new_mark(...) => new_mark(..., IdentKind) Implementation-wise, we simply have multiple |
@edwardw I guess that might work, but it seems like you still end with things being renamed incorrectly. However, you have more experience than me of the implementation of hygiene, so if you think it might work, experiment away. |
A concrete example of value and lifetime names interacting (just of the top of my head). If we had a "lifetime shorthand" syntax that allowed converting fn foo<'a>(x: &'a Foo) -> &'a Bar { ... } into fn foo(x: &Foo) -> &'x Bar { ... } presumably the variable and lifetime would need renaming together. |
Nominating. |
Maintains two renaming tables, one for regular idents and one for lifetime idents (a loop label is of lifetime kind) so that let bindings and loop labels with same name won't clash. Closes rust-lang#12512.
Bump, we still need to make a decision about this. |
Loop-label hygiene has actually been filed before: #9171 (not closing either of these as dupes, since this bug isn't actually about loop hygiene directly, e.g. one way to stop this being confusing would be a compiler error about labels and variables sharing a name). |
Is there a nice summary of the status of both this issue and #12563? Both have quite long conversations which seem to go into much detail, and it would be nice to see a more concise description of what's going on. |
(My) SummaryWhy is this issue happening?The hygienic label works by renaming itself with respect to its lexical scope. The renaming of a label needs to be propagated into its loop body for What #12563 has proposed#12563 tried to add namespaces to renaming operation so that label and normal identifier won't collide. jbclements' concern and suggestion@jbclements claims that such behavior may very well be what we want. By hardcoding namespace, we may restrict the ability of macro expansion. He then suggests to have one flat namespace as-is but try to distinguish them 'symbolically', i.e. label not only has |
Assigning 1.0, P-backcompat-lang. |
Could we arrange a video call on this topic? I think it might clarify things. |
@jbclements I imagine such a thing could be done, though I would not be the one to arrange it. You may want to send an email with perhaps a suggestion of whom to include on the call? (Also, I'm still curious to know the original motivation for your suggestion that we make lifetimes Names instead of Idents, I haven't been able the determine the motivation for that.) |
I hadn't made them hygienic, so I thought we might as well clean that up and just make them Names. If we're going to make them hygienic, though, I cheerfully retract that suggestion entirely. |
@jbclements ah, i see the light: we hadn't had the necessary machinery to support them as properly hygienic, so it was misleading to classify them as Idents, okay. But yes, I think we should go the other direction and make them properly hygienic idents. Okay okay. |
Now the hygienic label has been documented: PR 13106. It would be better if we could decide what to do about this bug. |
the leading quote part of the identifier for the purposes of hygiene. This adopts @jbclements' solution to rust-lang#14539. I'm not sure if this is a breaking change or not. Closes rust-lang#12512. [breaking-change]
This compiled as of yesterday, but no longer does:
Renaming either the label or the variable fixes the error.
cc @edwardw
The text was updated successfully, but these errors were encountered: