Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upDisallow methods from traits that are not in scope #31908
Conversation
rust-highfive
assigned
nikomatsakis
Feb 26, 2016
jseyfried
force-pushed the
jseyfried:disallow_shadowed_traits
branch
2 times, most recently
from
200383b
to
6dd4548
Feb 26, 2016
oli-obk
reviewed
Feb 26, 2016
| } | ||
| impl T for () {} | ||
|
|
||
| fn g<T>() { |
This comment has been minimized.
This comment has been minimized.
oli-obk
Feb 26, 2016
Contributor
to be fully consistent, we need to also update E0256 ("import T conflicts with type in this module"), because "use self::T;" will still work in the generic function g, but not in h.
jseyfried
force-pushed the
jseyfried:disallow_shadowed_traits
branch
from
6dd4548
to
bfa7fc4
Feb 26, 2016
This comment has been minimized.
This comment has been minimized.
|
Now that I see the impact, I have some concerns about both backwards compat, and that this might just not be the right rule. I hadn't fully considered that shadowing with any arbitrary type would rule out using the methods from a trait as well. For example, this change does not impact the iterator naming pattern, because we name the types Another example might be I've yet to come up with an actual problematic example, but at minimum a crater run seems worthwhile. |
This comment has been minimized.
This comment has been minimized.
|
Crater run executing. |
This comment has been minimized.
This comment has been minimized.
|
Crater run result: https://gist.github.com/nikomatsakis/23a0ed555ecf83287c25 5 regressions. |
This comment has been minimized.
This comment has been minimized.
|
Ok, I believe these are our options:
|
This comment has been minimized.
This comment has been minimized.
|
|
jseyfried
force-pushed the
jseyfried:disallow_shadowed_traits
branch
from
bfa7fc4
to
8774852
Mar 6, 2016
This comment has been minimized.
This comment has been minimized.
Having thought about this some more, I feel like this rule may in fact be the one that I find most intuitive. Admittedly, I argued the opposite in the past, but thinking about examples like this sort of changed my mind: fn foo<Default>(...) -> Default {
...
let x = SomeType::default();
...
} |
jseyfried
force-pushed the
jseyfried:disallow_shadowed_traits
branch
2 times, most recently
from
21ce5cb
to
d08b0c6
Mar 7, 2016
This comment has been minimized.
This comment has been minimized.
|
That example would still work since it uses UFCS, but your point stands. I updated this PR to use the compromise rule (i.e. allow traits from ancestor scopes). The only remaining regression is Thinking about this some more, I actually prefer this approach since I think we should consider the prelude not as something that gets imported into all* modules' scopes but instead as its own scope that is the parent of all modules' scopes. @nrc suggests this interpretation in his sets of scopes blog post. This interpretation would mean that we permanently treat the prelude like we currently treat all private imports; for example, we would never allow prelude-"imported" names to be used in a crate relative path or imported into another module. *except for |
This comment has been minimized.
This comment has been minimized.
I would not expect my example to work, even though it uses UFCS. The set of traits in scope for a UFCS call like
Hmm. I would find this a little surprising...
...but when you put it like that, it kind of makes sense. cc @rust-lang/lang, thoughts?
I think both @nrc and I would like to change "private imports" so that they behave precisely like all other items (e.g., |
This comment has been minimized.
This comment has been minimized.
|
ok, chatted briefly with @aturon on IRC, conclusion was that we should discuss again in the next @rust-lang/lang meeting :) |
nikomatsakis
added
the
I-nominated
label
Mar 8, 2016
This comment has been minimized.
This comment has been minimized.
Makes sense -- for some reason I thought the trait search only applied to non-UFCS methods.
As would @petrochenkov and I. I think the prelude should be treated differently from private imports (well, the prelude is already treated differently since it is shadowable by globs) in part because otherwise, mod foo {
pub type Result = ();
}
mod bar {
// use super::*; // uncommenting this line would import `Result` from `super`'s prelude ...
use foo::*;
fn f() -> Result { () } // ... making this an ambiguity error.
}It seems wrong for the prelude to be shadowable but for the names imported from another module's prelude to not be shadowable (and to shadow the original prelude). @petrochenkov also argues for treating the prelude differently in #31726. |
This comment has been minimized.
This comment has been minimized.
|
@jseyfried ok, I'm basically convinced that treating the prelude as a 'level above' in the scope makes sense. |
jseyfried
referenced this pull request
Mar 11, 2016
Merged
resolve: Refactor how the prelude is handled #32167
This comment has been minimized.
This comment has been minimized.
|
|
jseyfried
force-pushed the
jseyfried:disallow_shadowed_traits
branch
from
d08b0c6
to
f7cb841
Mar 14, 2016
jseyfried
added some commits
Mar 7, 2016
jseyfried
force-pushed the
jseyfried:disallow_shadowed_traits
branch
from
f7cb841
to
ed8a2e2
Mar 17, 2016
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis I amended this PR to treat the prelude as a level above in the scope hierarchy, i.e. to always allow prelude traits and only disallow shadowed glob-imported re-exports. |
jseyfried
closed this
Mar 18, 2016
jseyfried
deleted the
jseyfried:disallow_shadowed_traits
branch
Mar 18, 2016
jseyfried
restored the
jseyfried:disallow_shadowed_traits
branch
Mar 18, 2016
jseyfried
reopened this
Mar 18, 2016
aturon
added
the
T-lang
label
Mar 24, 2016
This comment has been minimized.
This comment has been minimized.
|
After discussing in @rust-lang/lang, decided to adopt this approach where prelude is a scope above the other scopes. Thanks @jseyfried for your patience as always! |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis no problem! This is ready to land pending your review (there's not much to review). After this lands, the rebase of #32167 will remove |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ @jseyfried heh, when I looked at the code this morning, I was a bit surprised -- I expected a bit more. Anyway, going to work hard on getting to your other PRs now! |
This comment has been minimized.
This comment has been minimized.
|
|
jseyfried commentedFeb 26, 2016
This PR only allows a trait method to be used if the trait is in scope (fixes #31379).
This is a [breaking-change]. For example, the following would break:
r? @nikomatsakis