diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2021-02-18 16:57:34 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-18 16:57:34 +0100 |
| commit | 66211f6657971bdaf18996400435b6a416aa3343 (patch) | |
| tree | fc0bfa6c8cf3b7c7344a4373cab51d2947a6dc5e /src | |
| parent | 55ab2e38797ad1661ff4cfa95074a3d81636fde0 (diff) | |
| parent | eeb82e45fe42ec77efd99b706f96b3e66bcfb524 (diff) | |
Rollup merge of #82066 - matthewjasper:trait-ref-fix, r=jackh726
Ensure valid TraitRefs are created for GATs This fixes `ProjectionTy::trait_ref` to use the correct substs. Places that need all of the substs have been updated to not use `trait_ref`. r? ````@jackh726````
Diffstat (limited to 'src')
14 files changed, 300 insertions, 76 deletions
diff --git a/src/test/pretty/gat-bounds.rs b/src/test/pretty/gat-bounds.rs index 789e4bc80ac..8877c6cc992 100644 --- a/src/test/pretty/gat-bounds.rs +++ b/src/test/pretty/gat-bounds.rs @@ -13,4 +13,6 @@ impl X for () { type Y<T> where Self: Sized = u32; } +fn f<T: X<Y<()> = i32>>() {} + fn main() { } diff --git a/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs new file mode 100644 index 00000000000..36db3d1bb9e --- /dev/null +++ b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.rs @@ -0,0 +1,17 @@ +// Test that correct syntax is used in suggestion to constrain associated type + +#![feature(generic_associated_types)] +//~^ WARNING the feature `generic_associated_types` is incomplete + +trait X { + type Y<T>; +} + +fn f<T: X>(a: T::Y<i32>) { + //~^ HELP consider constraining the associated type `<T as X>::Y<i32>` to `Vec<i32>` + //~| SUGGESTION Y<i32> = Vec<i32>> + let b: Vec<i32> = a; + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr new file mode 100644 index 00000000000..ecf559d9e94 --- /dev/null +++ b/src/test/ui/generic-associated-types/constraint-assoc-type-suggestion.stderr @@ -0,0 +1,27 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/constraint-assoc-type-suggestion.rs:3:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information + +error[E0308]: mismatched types + --> $DIR/constraint-assoc-type-suggestion.rs:13:23 + | +LL | let b: Vec<i32> = a; + | -------- ^ expected struct `Vec`, found associated type + | | + | expected due to this + | + = note: expected struct `Vec<i32>` + found associated type `<T as X>::Y<i32>` +help: consider constraining the associated type `<T as X>::Y<i32>` to `Vec<i32>` + | +LL | fn f<T: X<Y<i32> = Vec<i32>>>(a: T::Y<i32>) { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs new file mode 100644 index 00000000000..8094450e5e1 --- /dev/null +++ b/src/test/ui/generic-associated-types/generic-associated-type-bounds.rs @@ -0,0 +1,35 @@ +// run-pass + +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +pub trait X { + type Y<'a>; + fn m(&self) -> Self::Y<'_>; +} + +impl X for () { + type Y<'a> = &'a (); + + fn m(&self) -> Self::Y<'_> { + self + } +} + +fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &() { + x.m() +} + +fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &() { + x.m() +} + +fn h(x: &()) -> &() { + x.m() +} + +fn main() { + f(&()); + g(&()); + h(&()); +} diff --git a/src/test/ui/generic-associated-types/issue-76535.rs b/src/test/ui/generic-associated-types/issue-76535.rs index 2b4757d8d15..5e73a882986 100644 --- a/src/test/ui/generic-associated-types/issue-76535.rs +++ b/src/test/ui/generic-associated-types/issue-76535.rs @@ -1,11 +1,11 @@ #![feature(generic_associated_types)] - //~^ WARNING the feature +//~^ WARNING the feature pub trait SubTrait {} pub trait SuperTrait { type SubType<'a>: SubTrait; - //~^ ERROR missing generics for associated + //~^ ERROR missing generics for associated fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; } @@ -36,6 +36,4 @@ impl SuperTrait for SuperStruct { fn main() { let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); - //~^ ERROR the trait - //~| ERROR the trait } diff --git a/src/test/ui/generic-associated-types/issue-76535.stderr b/src/test/ui/generic-associated-types/issue-76535.stderr index ce4875af9c0..17661e0d90a 100644 --- a/src/test/ui/generic-associated-types/issue-76535.stderr +++ b/src/test/ui/generic-associated-types/issue-76535.stderr @@ -23,41 +23,6 @@ help: use angle brackets to add missing lifetime argument LL | type SubType<'a><'a>: SubTrait; | ^^^^ -error[E0038]: the trait `SuperTrait` cannot be made into an object - --> $DIR/issue-76535.rs:38:14 - | -LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object - | - = help: consider moving `get_sub` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/issue-76535.rs:10:37 - | -LL | pub trait SuperTrait { - | ---------- this trait cannot be made into an object... -... -LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; - | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type - -error[E0038]: the trait `SuperTrait` cannot be made into an object - --> $DIR/issue-76535.rs:38:57 - | -LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object - | - = help: consider moving `get_sub` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/issue-76535.rs:10:37 - | -LL | pub trait SuperTrait { - | ---------- this trait cannot be made into an object... -... -LL | fn get_sub<'a>(&'a mut self) -> Self::SubType<'a>; - | ^^^^^^^^^^^^^^^^^ ...because method `get_sub` references the `Self` type in its return type - = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>` for `Box<SuperStruct>` - = note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>` - -error: aborting due to 3 previous errors; 1 warning emitted +error: aborting due to previous error; 1 warning emitted -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/issue-79422.rs b/src/test/ui/generic-associated-types/issue-79422.rs index 26b38430dd9..aeb33ca5464 100644 --- a/src/test/ui/generic-associated-types/issue-79422.rs +++ b/src/test/ui/generic-associated-types/issue-79422.rs @@ -19,7 +19,7 @@ impl<'a, T> RefCont<'a, T> for Box<T> { trait MapLike<K, V> { type VRefCont<'a>: RefCont<'a, V>; - //~^ ERROR missing generics + //~^ ERROR missing generics fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>; } @@ -42,6 +42,5 @@ impl<K, V: Default> MapLike<K, V> for Source { fn main() { let m = Box::new(std::collections::BTreeMap::<u8, u8>::new()) as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>; - //~^ ERROR the trait - //~^^^ ERROR the trait + //~^^ ERROR type mismatch resolving } diff --git a/src/test/ui/generic-associated-types/issue-79422.stderr b/src/test/ui/generic-associated-types/issue-79422.stderr index d2e12962715..a119bff03e2 100644 --- a/src/test/ui/generic-associated-types/issue-79422.stderr +++ b/src/test/ui/generic-associated-types/issue-79422.stderr @@ -14,41 +14,17 @@ help: use angle brackets to add missing lifetime argument LL | type VRefCont<'a><'a>: RefCont<'a, V>; | ^^^^ -error[E0038]: the trait `MapLike` cannot be made into an object - --> $DIR/issue-79422.rs:44:12 - | -LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object - | - = help: consider moving `get` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/issue-79422.rs:23:38 - | -LL | trait MapLike<K, V> { - | ------- this trait cannot be made into an object... -... -LL | fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type - -error[E0038]: the trait `MapLike` cannot be made into an object +error[E0271]: type mismatch resolving `<BTreeMap<u8, u8> as MapLike<u8, u8>>::VRefCont<'static> == (dyn RefCont<'_, u8> + 'static)` --> $DIR/issue-79422.rs:43:13 | LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` cannot be made into an object - | - = help: consider moving `get` to another trait -note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> - --> $DIR/issue-79422.rs:23:38 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn RefCont`, found reference | -LL | trait MapLike<K, V> { - | ------- this trait cannot be made into an object... -... -LL | fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `get` references the `Self` type in its return type - = note: required because of the requirements on the impl of `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>` for `Box<BTreeMap<u8, u8>>` - = note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>` + = note: expected trait object `(dyn RefCont<'_, u8> + 'static)` + found reference `&'static u8` + = note: required for the cast to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0038, E0107. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0107, E0271. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs new file mode 100644 index 00000000000..2de4c7b8492 --- /dev/null +++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs @@ -0,0 +1,35 @@ +// Test that the predicate printed in an unresolved method error prints the +// generics for a generic associated type. + +#![feature(generic_associated_types)] +//~^ WARNING the feature `generic_associated_types` is incomplete +//~| NOTE `#[warn(incomplete_features)]` on by default +//~| NOTE see issue #44265 + +trait X { + type Y<T>; +} + +trait M { + fn f(&self) {} +} + +impl<T: X<Y<i32> = i32>> M for T {} + +struct S; +//~^ NOTE method `f` not found for this +//~| NOTE doesn't satisfy `<S as X>::Y<i32> = i32` +//~| NOTE doesn't satisfy `S: M` + +impl X for S { + type Y<T> = bool; +} + +fn f(a: S) { + a.f(); + //~^ ERROR the method `f` exists for struct `S`, but its trait bounds were not satisfied + //~| NOTE method cannot be called on `S` due to unsatisfied trait bounds + //~| NOTE the following trait bounds were not satisfied: +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr new file mode 100644 index 00000000000..c94155d13c3 --- /dev/null +++ b/src/test/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr @@ -0,0 +1,29 @@ +warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/method-unsatified-assoc-type-predicate.rs:4:12 + | +LL | #![feature(generic_associated_types)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information + +error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied + --> $DIR/method-unsatified-assoc-type-predicate.rs:29:7 + | +LL | struct S; + | --------- + | | + | method `f` not found for this + | doesn't satisfy `<S as X>::Y<i32> = i32` + | doesn't satisfy `S: M` +... +LL | a.f(); + | ^ method cannot be called on `S` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `<S as X>::Y<i32> = i32` + which is required by `S: M` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs new file mode 100644 index 00000000000..0024e127a98 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.rs @@ -0,0 +1,36 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +pub trait X { + type Y<'a>; + fn m(&self) -> Self::Y<'_>; +} + +impl X for () { + type Y<'a> = &'a (); + + fn m(&self) -> Self::Y<'_> { + self + } +} + +fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () { + x.m() + //~^ ERROR explicit lifetime required +} + +fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () { + x.m() + //~^ ERROR explicit lifetime required +} + +fn h(x: &()) -> &'static () { + x.m() + //~^ ERROR explicit lifetime required +} + +fn main() { + f(&()); + g(&()); + h(&()); +} diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr new file mode 100644 index 00000000000..13b765dfa57 --- /dev/null +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr @@ -0,0 +1,27 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/projection-type-lifetime-mismatch.rs:18:5 + | +LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () { + | ------------------------------- help: add explicit lifetime `'static` to the type of `x`: `&'static impl for<'a> X<Y<'a> = &'a ()>` +LL | x.m() + | ^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/projection-type-lifetime-mismatch.rs:23:5 + | +LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () { + | -- help: add explicit lifetime `'static` to the type of `x`: `&'static T` +LL | x.m() + | ^^^^^ lifetime `'static` required + +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/projection-type-lifetime-mismatch.rs:28:5 + | +LL | fn h(x: &()) -> &'static () { + | --- help: add explicit lifetime `'static` to the type of `x`: `&'static ()` +LL | x.m() + | ^^^^^ lifetime `'static` required + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs new file mode 100644 index 00000000000..7bcc7ba752a --- /dev/null +++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.rs @@ -0,0 +1,28 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +pub trait X { + type Y<'a: 'static>; + //~^ WARNING unnecessary lifetime parameter +} + +impl X for () { + type Y<'a> = &'a (); +} + +struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> { + f: <T as X>::Y<'a>, + //~^ ERROR lifetime bound not satisfied +} + +struct C<'a, T: X> { + f: <T as X>::Y<'a>, + //~^ ERROR lifetime bound not satisfied +} + +struct D<'a> { + f: <() as X>::Y<'a>, + //~^ ERROR lifetime bound not satisfied +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr new file mode 100644 index 00000000000..1c81d33ccfe --- /dev/null +++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr @@ -0,0 +1,50 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/unsatified-item-lifetime-bound.rs:5:12 + | +LL | type Y<'a: 'static>; + | ^^^^^^^^^^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +error[E0478]: lifetime bound not satisfied + --> $DIR/unsatified-item-lifetime-bound.rs:14:8 + | +LL | f: <T as X>::Y<'a>, + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined on the struct at 13:10 + --> $DIR/unsatified-item-lifetime-bound.rs:13:10 + | +LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error[E0478]: lifetime bound not satisfied + --> $DIR/unsatified-item-lifetime-bound.rs:19:8 + | +LL | f: <T as X>::Y<'a>, + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined on the struct at 18:10 + --> $DIR/unsatified-item-lifetime-bound.rs:18:10 + | +LL | struct C<'a, T: X> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error[E0478]: lifetime bound not satisfied + --> $DIR/unsatified-item-lifetime-bound.rs:24:8 + | +LL | f: <() as X>::Y<'a>, + | ^^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'a` as defined on the struct at 23:10 + --> $DIR/unsatified-item-lifetime-bound.rs:23:10 + | +LL | struct D<'a> { + | ^^ + = note: but lifetime parameter must outlive the static lifetime + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0478`. |
