Skip to content

Commit

Permalink
Add comment and extra test
Browse files Browse the repository at this point in the history
  • Loading branch information
jackh726 committed Aug 23, 2021
1 parent 6df6eb8 commit b017077
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 8 deletions.
28 changes: 27 additions & 1 deletion compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1240,9 +1240,35 @@ pub fn check_type_bounds<'tcx>(
// }
//
// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>
// - `impl_ty_substs` would be `[A, B, ^0.0]`
// - `impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
// - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
// the *trait* with the generic associated type parameters (as bound vars).
//
// A note regarding the use of bound vars here:
// Imagine as an example
// ```
// trait Family {
// type Member<C: Eq>;
// }
//
// impl Family for VecFamily {
// type Member<C: Eq> = i32;
// }
// ```
// Here, we would generate
// ```notrust
// forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) }
// ```
// when we really would like to generate
// ```notrust
// forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) :- Implemented(C: Eq) }
// ```
// But, this is probably fine, because although the first clause can be used with types C that
// do not implement Eq, for it to cause some kind of problem, there would have to be a
// VecFamily::Member<X> for some type X where !(X: Eq), that appears in the value of type
// Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing
// elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in
// the trait (notably, that X: Eq and T: Family).
let defs: &ty::Generics = tcx.generics_of(impl_ty.def_id);
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
if let Some(def_id) = defs.parent {
Expand Down
20 changes: 20 additions & 0 deletions src/test/ui/generic-associated-types/issue-87429-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Derived from `issue-87429`. A test that ensures that using bound vars in the
// predicates in the param env when checking that an associated type satisfies
// its bounds does not cause us to not be able to use the bounds on the parameters.

// check-pass

#![feature(generic_associated_types)]

trait Family {
type Member<'a, C: Eq>: for<'b> MyBound<'b, C>;
}

trait MyBound<'a, C> { }
impl<'a, C: Eq> MyBound<'a, C> for i32 { }

impl Family for () {
type Member<'a, C: Eq> = i32;
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ error[E0277]: can't compare `Foo` with `Foo`
--> $DIR/issue-87429-associated-type-default.rs:14:5
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
| ^^^^^^^^^^^^^^^^^-----------------------------------^^^^^^^
| | |
| | required by this bound in `Family2::Member`
| no implementation for `Foo == Foo`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Foo == Foo`
|
= help: the trait `PartialEq` is not implemented for `Foo`
note: required by a bound in `Family2::Member`
--> $DIR/issue-87429-associated-type-default.rs:14:22
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family2::Member`

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ LL | #![feature(specialization)]
error[E0277]: can't compare `Foo` with `Foo`
--> $DIR/issue-87429-specialization.rs:21:5
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
| ----------------------------------- required by this bound in `Family::Member`
...
LL | default type Member<'a> = Foo;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Foo == Foo`
|
= help: the trait `PartialEq` is not implemented for `Foo`
note: required by a bound in `Family::Member`
--> $DIR/issue-87429-specialization.rs:8:22
|
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member`

error: aborting due to previous error; 1 warning emitted

Expand Down

0 comments on commit b017077

Please sign in to comment.