about summary refs log tree commit diff
diff options
context:
space:
mode:
authorjackh726 <jack.huey@umassmed.edu>2021-08-23 16:39:11 -0400
committerjackh726 <jack.huey@umassmed.edu>2021-08-23 17:53:16 -0400
commitb0170779f5c6e9705658cda1b02cf1fd1a925205 (patch)
tree18c8d16c0ba375ae93e436bb973ae44473785ce9
parent6df6eb8ae8358ebab76fcfa35ac7cc41e18a2560 (diff)
downloadrust-b0170779f5c6e9705658cda1b02cf1fd1a925205.tar.gz
rust-b0170779f5c6e9705658cda1b02cf1fd1a925205.zip
Add comment and extra test
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs28
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-2.rs20
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr10
-rw-r--r--src/test/ui/generic-associated-types/issue-87429-specialization.stderr8
4 files changed, 58 insertions, 8 deletions
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index b95cbd9025c..c384e0dcb2c 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -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 {
diff --git a/src/test/ui/generic-associated-types/issue-87429-2.rs b/src/test/ui/generic-associated-types/issue-87429-2.rs
new file mode 100644
index 00000000000..d35bb098abd
--- /dev/null
+++ b/src/test/ui/generic-associated-types/issue-87429-2.rs
@@ -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() {}
diff --git a/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
index 8f031c76183..01cb0bfc72c 100644
--- a/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
+++ b/src/test/ui/generic-associated-types/issue-87429-associated-type-default.stderr
@@ -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
 
diff --git a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
index 05d40f9e7cc..87bd35f5878 100644
--- a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
+++ b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr
@@ -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