-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
From<Local> for Global
with non_local_definitions
lint
#124557
Comments
I don't think this is a false-positive. The presence or absence of the #[derive(Default)]
struct A;
fn _foo() {
struct B;
impl From<B> for A { // without this impl, this code compiles fine
fn from(b: B) -> A {
todo!()
}
}
}
fn main() {
let _ = A::from(Default::default()); // but with it, this line errors with an ambiguity error
}
Obviously this example is a bit silly, it could be made more complex cases with generic functions and what not. But it already demonstrate the effect of the @rustbot labels -needs-triage +C-discussion +T-compiler |
I would argue that your modified example shouldn't be an error in the first place. From a human perspective, there is no ambiguity in A::from's use in main because B not being in scope, it can't be From'ed from. |
I agree with you, having local (for human) definitions have a global effect is unexpected and goes against expectation. That is what RFC 3373: Avoid non-local definitions in functions is about, warning slowly but surely against those cases, so we can at some point turn them into errors. |
Here is an un-modified example demonstrating the global effect of your struct A;
fn foo() {
struct B;
impl From<B> for A { // with this impl, this code below doesn't compile anymore
fn from(b: B) -> A {
todo!()
}
}
}
fn bar<T: From<U>, U>() {}
fn main() {
bar::<A, _>(); // without the impl, this would compile fine, but with it it's a ambiguity error
// therefore the impl is not local and has a global effect
} |
What I'm saying is that it's an ambiguity error because rustc currently makes it one, but it doesn't have to be one. |
How is the ambiguity error avoidable? Ignoring the local impl entirely would be incorrect as there are cases where the local impl is the only applicable impl. For those cases ignoring the local impl would be a breaking change. For example: trait MyFrom<T> {}
struct A;
fn foo() {
struct B;
impl MyFrom<B> for A {}
}
fn bar<T: From<U>, U>() {}
fn main() {
bar::<A, _>();
} which is basically #124557 (comment) except without the |
As was said in the thread, this isn't a false positive. Closing. |
There's another
false positive:The error shown is:
Originally posted by @glandium in #124396 (comment)
The text was updated successfully, but these errors were encountered: