Rollup merge of #57501 - petrochenkov:highvar, r=alexreg
High priority resolutions for associated variants In https://github.com/rust-lang/rust/pull/56225 variants were assigned lowest priority during name resolution to avoid crater run and potential breakage. This PR changes the rules to give variants highest priority instead. Some motivation: - If variants (and their constructors) are treated as associated items, then they are obviously *inherent* associated items since they don't come from traits. - Inherent associated items have higher priority during resolution than associated items from traits. - The reason is that there is a way to disambiguate in favor of trait items (`<Type as Trait>::Ambiguous`), but there's no way to disambiguate in favor of inherent items, so they became unusable in case of ambiguities if they have low priority. - It's technically problematic to fallback from associated types to anything until lazy normalization (?) is implemented. Crater found some regressions from this change, but they are all in type positions, e.g. ```rust fn f() -> Self::Ambiguos { ... } // Variant `Ambiguous` or associated type `Ambiguous`? ``` , so variants are not usable there right now, but they may become usable in the future if https://github.com/rust-lang/rfcs/pull/2593 is accepted. This PR keeps code like this successfully resolving, but introduces a future-compatibility lint `ambiguous_associated_items` that recommends rewriting it as `<Self as Trait>::Ambiguous`.
This commit is contained in:
commit
b941f290ac
11 changed files with 227 additions and 105 deletions
13
src/test/ui/type-alias-enum-variants-priority-2.rs
Normal file
13
src/test/ui/type-alias-enum-variants-priority-2.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#![feature(type_alias_enum_variants)]
|
||||
|
||||
enum E {
|
||||
V(u8)
|
||||
}
|
||||
|
||||
impl E {
|
||||
fn V() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
<E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
|
||||
}
|
||||
12
src/test/ui/type-alias-enum-variants-priority-2.stderr
Normal file
12
src/test/ui/type-alias-enum-variants-priority-2.stderr
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
error[E0061]: this function takes 1 parameter but 0 parameters were supplied
|
||||
--> $DIR/type-alias-enum-variants-priority-2.rs:12:5
|
||||
|
|
||||
LL | V(u8)
|
||||
| ----- defined here
|
||||
...
|
||||
LL | <E>::V(); //~ ERROR this function takes 1 parameter but 0 parameters were supplied
|
||||
| ^^^^^^^^ expected 1 parameter
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0061`.
|
||||
10
src/test/ui/type-alias-enum-variants-priority-3.rs
Normal file
10
src/test/ui/type-alias-enum-variants-priority-3.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#![feature(type_alias_enum_variants)]
|
||||
|
||||
enum E {
|
||||
V
|
||||
}
|
||||
|
||||
fn check() -> <E>::V {}
|
||||
//~^ ERROR expected type, found variant `V`
|
||||
|
||||
fn main() {}
|
||||
8
src/test/ui/type-alias-enum-variants-priority-3.stderr
Normal file
8
src/test/ui/type-alias-enum-variants-priority-3.stderr
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
error: expected type, found variant `V`
|
||||
--> $DIR/type-alias-enum-variants-priority-3.rs:7:15
|
||||
|
|
||||
LL | fn check() -> <E>::V {}
|
||||
| ^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
20
src/test/ui/type-alias-enum-variants-priority.rs
Normal file
20
src/test/ui/type-alias-enum-variants-priority.rs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#![feature(type_alias_enum_variants)]
|
||||
#![deny(ambiguous_associated_items)]
|
||||
|
||||
enum E {
|
||||
V
|
||||
}
|
||||
|
||||
trait Tr {
|
||||
type V;
|
||||
fn f() -> Self::V;
|
||||
}
|
||||
|
||||
impl Tr for E {
|
||||
type V = u8;
|
||||
fn f() -> Self::V { 0 }
|
||||
//~^ ERROR ambiguous associated item
|
||||
//~| WARN this was previously accepted
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
26
src/test/ui/type-alias-enum-variants-priority.stderr
Normal file
26
src/test/ui/type-alias-enum-variants-priority.stderr
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
error: ambiguous associated item
|
||||
--> $DIR/type-alias-enum-variants-priority.rs:15:15
|
||||
|
|
||||
LL | fn f() -> Self::V { 0 }
|
||||
| ^^^^^^^ help: use fully-qualified syntax: `<E as Trait>::V`
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/type-alias-enum-variants-priority.rs:2:9
|
||||
|
|
||||
LL | #![deny(ambiguous_associated_items)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
|
||||
note: `V` could refer to variant defined here
|
||||
--> $DIR/type-alias-enum-variants-priority.rs:5:5
|
||||
|
|
||||
LL | V
|
||||
| ^
|
||||
note: `V` could also refer to associated type defined here
|
||||
--> $DIR/type-alias-enum-variants-priority.rs:9:5
|
||||
|
|
||||
LL | type V;
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue