Skip to content

Commit

Permalink
Add a few more tests, comments
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Sep 25, 2024
1 parent 149bd87 commit c591475
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_hir_analysis/src/collect/item_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.
31 changes: 31 additions & 0 deletions tests/ui/associated-type-bounds/nested-gat-projection.rs
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit c591475

Please sign in to comment.