-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
In Context::LookupUnqualifiedName(), prefer lexical result over non lexical result #4574
Conversation
This feels like a behavior change, but I'm having trouble coming up with a test case, so @zygoloid who put this together. |
Note, it may be correct even if it's a behavior change -- but I think it changes behavior when there's a lexical result and later non-lexical scopes. The current code would look through the remaining non-lexical scopes first (starting with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would do the wrong thing for a case like:
fn F();
class C {
fn F() -> i32;
fn G() -> i32;
}
fn C.G() -> i32 {
return F();
}
Here, lexical lookup for F
finds package.F
, but the desired unqualified lookup result is instead C.F
.
If we don't already have a testcase like this, we should add one.
I've tried to reproduce this and failed so far (can't see a difference in behavior). fn F() {}
namespace N;
fn N.F() -> i32 { return 1; }
fn N.G() -> i32 { return F(); }
class C {
fn F() -> i32 { return 2; }
fn G() -> i32;
}
fn C.G() -> i32 {
return F();
}
fn Main() {
F();
var namespace_func_result: i32;
namespace_func_result = N.G();
var class_func_result: i32;
var class_instance: C;
class_func_result = class_instance.G();
} |
Oh, right: the outer name will need to come from a lexical scope for us to see a difference here. (Package scope is a non-lexical scope, so the example I mentioned and the namespace example won't be affected by this.) You would see a difference if a lexical scope encloses a non-lexical scope. Because we don't support local classes yet, I think that means the only way this is observable right now is if a non-lexical name shadows a generic parameter: class Class(F:! type) {
class Inner {
fn F() -> i32 { return 0; }
fn G() -> i32;
}
}
fn Class(F:! type).Inner.G() -> i32 { return F(); } ... which compiles prior to this change and is rejected afterwards. |
Thanks Richard! |
…on lexical scope over a lexical scope (carbon-language#4591) This adds missing test coverage. See discussion in carbon-language#4574.
No description provided.