diff options
| author | Michael Goulet <michael@errs.io> | 2024-09-21 14:32:36 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-09-25 13:13:04 -0400 |
| commit | c5914753ad438fe53c3b97a079b595136dc862c9 (patch) | |
| tree | 811e417bea4339564c4479a8113e84fb48db9ff7 | |
| parent | 149bd877de8c84870c303399e62770cf2a72fcf7 (diff) | |
| download | rust-c5914753ad438fe53c3b97a079b595136dc862c9.tar.gz rust-c5914753ad438fe53c3b97a079b595136dc862c9.zip | |
Add a few more tests, comments
4 files changed, 81 insertions, 0 deletions
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 39b697bbfc1..7557219aaa6 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -173,6 +173,12 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>( )) } +/// Given some where clause like `for<'b, 'c> <Self as Trait<'a_identity>>::Gat<'b>: Bound<'c>`, +/// the mapping will map `'b` back to the GAT's `'b_identity`. Then we need to compress the +/// remaining bound var `'c` to index 0. +/// +/// This folder gives us: `for<'c> <Self as Trait<'a_identity>>::Gat<'b_identity>: Bound<'c>`, +/// which is sufficient for an item bound for `Gat`, since all of the GAT's args are identity. struct MapAndCompressBoundVars<'tcx> { tcx: TyCtxt<'tcx>, /// How deep are we? Makes sure we don't touch the vars of nested binders. diff --git a/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.rs b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.rs new file mode 100644 index 00000000000..eb616631d1d --- /dev/null +++ b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.rs @@ -0,0 +1,28 @@ +// Demonstrates a mostly-theoretical inference guidance now that we turn the where +// clause on `Trait` into an item bound, given that we prefer item bounds somewhat +// greedily in trait selection. + +trait Bound<T> {} +impl<T, U> Bound<T> for U {} + +trait Trait +where + <<Self as Trait>::Assoc as Other>::Assoc: Bound<u32>, +{ + type Assoc: Other; +} + +trait Other { + type Assoc; +} + +fn impls_trait<T: Bound<U>, U>() -> Vec<U> { vec![] } + +fn foo<T: Trait>() { + let mut vec_u = impls_trait::<<<T as Trait>::Assoc as Other>::Assoc, _>(); + vec_u.sort(); + drop::<Vec<u8>>(vec_u); + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.stderr b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.stderr new file mode 100644 index 00000000000..c77400f3822 --- /dev/null +++ b/tests/ui/associated-type-bounds/nested-associated-type-bound-incompleteness.stderr @@ -0,0 +1,16 @@ +error[E0308]: mismatched types + --> $DIR/nested-associated-type-bound-incompleteness.rs:24:21 + | +LL | drop::<Vec<u8>>(vec_u); + | --------------- ^^^^^ expected `Vec<u8>`, found `Vec<u32>` + | | + | arguments to this function are incorrect + | + = note: expected struct `Vec<u8>` + found struct `Vec<u32>` +note: function defined here + --> $SRC_DIR/core/src/mem/mod.rs:LL:COL + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-type-bounds/nested-gat-projection.rs b/tests/ui/associated-type-bounds/nested-gat-projection.rs new file mode 100644 index 00000000000..ad37da9ed19 --- /dev/null +++ b/tests/ui/associated-type-bounds/nested-gat-projection.rs @@ -0,0 +1,31 @@ +//@ check-pass + +trait Trait +where + for<'a> Self::Gat<'a>: OtherTrait, + for<'a, 'b, 'c> <Self::Gat<'a> as OtherTrait>::OtherGat<'b>: HigherRanked<'c>, +{ + type Gat<'a>; +} + +trait OtherTrait { + type OtherGat<'b>; +} + +trait HigherRanked<'c> {} + +fn lower_ranked<T: for<'b, 'c> OtherTrait<OtherGat<'b>: HigherRanked<'c>>>() {} + +fn higher_ranked<T: Trait>() +where + for<'a> T::Gat<'a>: OtherTrait, + for<'a, 'b, 'c> <T::Gat<'a> as OtherTrait>::OtherGat<'b>: HigherRanked<'c>, +{ +} + +fn test<T: Trait>() { + lower_ranked::<T::Gat<'_>>(); + higher_ranked::<T>(); +} + +fn main() {} |
