about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_typeck/check/compare_method.rs53
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs2
-rw-r--r--src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr24
3 files changed, 25 insertions, 54 deletions
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index fac87866b80..bf415406675 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -6,15 +6,14 @@ use rustc_hir::{GenericParamKind, ImplItemKind, TraitItemKind};
 use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
 use rustc_middle::ty;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
+use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::util::ExplicitSelf;
-use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt, WithConstness};
+use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
 use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
 
 use super::{potentially_plural_count, FnCtxt, Inherited};
-use std::iter;
 
 /// Checks that a method from an impl conforms to the signature of
 /// the same method as declared in the trait.
@@ -1240,22 +1239,6 @@ fn compare_projection_bounds<'tcx>(
         ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing, None)
     };
 
-    // Map the predicate from the trait to the corresponding one for the impl.
-    // For example:
-    //
-    // trait X<A> { type Y<'a>: PartialEq<A> } impl X for T { type Y<'a> = &'a S; }
-    // impl<'x> X<&'x u32> for () { type Y<'c> = &'c u32; }
-    //
-    // For the `for<'a> <<Self as X<A>>::Y<'a>: PartialEq<A>` bound, this
-    // function would translate and partially normalize
-    // `[<Self as X<A>>::Y<'a>, A]` to `[&'a u32, &'x u32]`.
-    let translate_predicate_substs = move |predicate_substs: SubstsRef<'tcx>| {
-        tcx.mk_substs(
-            iter::once(impl_ty_value.into())
-                .chain(predicate_substs[1..].iter().map(|s| s.subst(tcx, rebased_substs))),
-        )
-    };
-
     tcx.infer_ctxt().enter(move |infcx| {
         let inh = Inherited::new(infcx, impl_ty.def_id.expect_local());
         let infcx = &inh.infcx;
@@ -1270,39 +1253,10 @@ fn compare_projection_bounds<'tcx>(
         );
 
         let predicates = tcx.projection_predicates(trait_ty.def_id);
-
         debug!("compare_projection_bounds: projection_predicates={:?}", predicates);
 
         for predicate in predicates {
-            let concrete_ty_predicate = match predicate.kind() {
-                ty::PredicateKind::Trait(poly_tr, c) => poly_tr
-                    .map_bound(|tr| {
-                        let trait_substs = translate_predicate_substs(tr.trait_ref.substs);
-                        ty::TraitRef { def_id: tr.def_id(), substs: trait_substs }
-                    })
-                    .with_constness(*c)
-                    .to_predicate(tcx),
-                ty::PredicateKind::Projection(poly_projection) => poly_projection
-                    .map_bound(|projection| {
-                        let projection_substs =
-                            translate_predicate_substs(projection.projection_ty.substs);
-                        ty::ProjectionPredicate {
-                            projection_ty: ty::ProjectionTy {
-                                substs: projection_substs,
-                                item_def_id: projection.projection_ty.item_def_id,
-                            },
-                            ty: projection.ty.subst(tcx, rebased_substs),
-                        }
-                    })
-                    .to_predicate(tcx),
-                ty::PredicateKind::TypeOutlives(poly_outlives) => poly_outlives
-                    .map_bound(|outlives| {
-                        ty::OutlivesPredicate(impl_ty_value, outlives.1.subst(tcx, rebased_substs))
-                    })
-                    .to_predicate(tcx),
-                _ => bug!("unexepected projection predicate kind: `{:?}`", predicate),
-            };
-
+            let concrete_ty_predicate = predicate.subst(tcx, rebased_substs);
             debug!("compare_projection_bounds: concrete predicate = {:?}", concrete_ty_predicate);
 
             let traits::Normalized { value: normalized_predicate, obligations } = traits::normalize(
@@ -1311,7 +1265,6 @@ fn compare_projection_bounds<'tcx>(
                 normalize_cause.clone(),
                 &concrete_ty_predicate,
             );
-
             debug!("compare_projection_bounds: normalized predicate = {:?}", normalized_predicate);
 
             inh.register_predicates(obligations);
diff --git a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
index 7510c58d574..4831a8c63e8 100644
--- a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
+++ b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.rs
@@ -7,7 +7,7 @@ trait ATy {
 
 impl<'b> ATy for &'b () {
     type Item<'a> = &'b ();
-    //~^ ERROR does not fulfill the required lifetime
+    //~^ ERROR cannot infer an appropriate lifetime
 }
 
 trait StaticTy {
diff --git a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
index 5d612284a21..80f69becc2c 100644
--- a/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
+++ b/src/test/ui/generic-associated-types/unsatisfied-outlives-bound.stderr
@@ -1,14 +1,31 @@
-error[E0477]: the type `&'b ()` does not fulfill the required lifetime
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting requirements
   --> $DIR/unsatisfied-outlives-bound.rs:9:5
    |
 LL |     type Item<'a> = &'b ();
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: type must outlive the lifetime `'a` as defined on the associated item at 9:15
+note: first, the lifetime cannot outlive the lifetime `'b` as defined on the impl at 8:6...
+  --> $DIR/unsatisfied-outlives-bound.rs:8:6
+   |
+LL | impl<'b> ATy for &'b () {
+   |      ^^
+note: ...so that the types are compatible
+  --> $DIR/unsatisfied-outlives-bound.rs:9:5
+   |
+LL |     type Item<'a> = &'b ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `ATy`
+              found `ATy`
+note: but, the lifetime must be valid for the lifetime `'a` as defined on the associated item at 9:15...
   --> $DIR/unsatisfied-outlives-bound.rs:9:15
    |
 LL |     type Item<'a> = &'b ();
    |               ^^
+note: ...so that the type `&()` will meet its required lifetime bounds
+  --> $DIR/unsatisfied-outlives-bound.rs:9:5
+   |
+LL |     type Item<'a> = &'b ();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0477]: the type `&'a ()` does not fulfill the required lifetime
   --> $DIR/unsatisfied-outlives-bound.rs:18:5
@@ -20,4 +37,5 @@ LL |     type Item<'a> = &'a ();
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0477`.
+Some errors have detailed explanations: E0477, E0495.
+For more information about an error, try `rustc --explain E0477`.