Skip to content

Commit b017077

Browse files
committed
Add comment and extra test
1 parent 6df6eb8 commit b017077

File tree

4 files changed

+58
-8
lines changed

4 files changed

+58
-8
lines changed

Diff for: compiler/rustc_typeck/src/check/compare_method.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -1240,9 +1240,35 @@ pub fn check_type_bounds<'tcx>(
12401240
// }
12411241
//
12421242
// - `impl_trait_ref` would be `<(A, B) as Foo<u32>>
1243-
// - `impl_ty_substs` would be `[A, B, ^0.0]`
1243+
// - `impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0)
12441244
// - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from
12451245
// the *trait* with the generic associated type parameters (as bound vars).
1246+
//
1247+
// A note regarding the use of bound vars here:
1248+
// Imagine as an example
1249+
// ```
1250+
// trait Family {
1251+
// type Member<C: Eq>;
1252+
// }
1253+
//
1254+
// impl Family for VecFamily {
1255+
// type Member<C: Eq> = i32;
1256+
// }
1257+
// ```
1258+
// Here, we would generate
1259+
// ```notrust
1260+
// forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) }
1261+
// ```
1262+
// when we really would like to generate
1263+
// ```notrust
1264+
// forall<C> { Normalize(<VecFamily as Family>::Member<C> => i32) :- Implemented(C: Eq) }
1265+
// ```
1266+
// But, this is probably fine, because although the first clause can be used with types C that
1267+
// do not implement Eq, for it to cause some kind of problem, there would have to be a
1268+
// VecFamily::Member<X> for some type X where !(X: Eq), that appears in the value of type
1269+
// Member<C: Eq> = .... That type would fail a well-formedness check that we ought to be doing
1270+
// elsewhere, which would check that any <T as Family>::Member<X> meets the bounds declared in
1271+
// the trait (notably, that X: Eq and T: Family).
12461272
let defs: &ty::Generics = tcx.generics_of(impl_ty.def_id);
12471273
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
12481274
if let Some(def_id) = defs.parent {
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Derived from `issue-87429`. A test that ensures that using bound vars in the
2+
// predicates in the param env when checking that an associated type satisfies
3+
// its bounds does not cause us to not be able to use the bounds on the parameters.
4+
5+
// check-pass
6+
7+
#![feature(generic_associated_types)]
8+
9+
trait Family {
10+
type Member<'a, C: Eq>: for<'b> MyBound<'b, C>;
11+
}
12+
13+
trait MyBound<'a, C> { }
14+
impl<'a, C: Eq> MyBound<'a, C> for i32 { }
15+
16+
impl Family for () {
17+
type Member<'a, C: Eq> = i32;
18+
}
19+
20+
fn main() {}

Diff for: src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ error[E0277]: can't compare `Foo` with `Foo`
22
--> $DIR/issue-87429-associated-type-default.rs:14:5
33
|
44
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
5-
| ^^^^^^^^^^^^^^^^^-----------------------------------^^^^^^^
6-
| | |
7-
| | required by this bound in `Family2::Member`
8-
| no implementation for `Foo == Foo`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Foo == Foo`
96
|
107
= help: the trait `PartialEq` is not implemented for `Foo`
8+
note: required by a bound in `Family2::Member`
9+
--> $DIR/issue-87429-associated-type-default.rs:14:22
10+
|
11+
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>> = Foo;
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family2::Member`
1113

1214
error: aborting due to previous error
1315

Diff for: src/test/ui/generic-associated-types/issue-87429-specialization.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ LL | #![feature(specialization)]
1111
error[E0277]: can't compare `Foo` with `Foo`
1212
--> $DIR/issue-87429-specialization.rs:21:5
1313
|
14-
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
15-
| ----------------------------------- required by this bound in `Family::Member`
16-
...
1714
LL | default type Member<'a> = Foo;
1815
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Foo == Foo`
1916
|
2017
= help: the trait `PartialEq` is not implemented for `Foo`
18+
note: required by a bound in `Family::Member`
19+
--> $DIR/issue-87429-specialization.rs:8:22
20+
|
21+
LL | type Member<'a>: for<'b> PartialEq<Self::Member<'b>>;
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Family::Member`
2123

2224
error: aborting due to previous error; 1 warning emitted
2325

0 commit comments

Comments
 (0)