diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index 817b4070754..4acc7451a21 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -1205,16 +1205,27 @@ pub fn check_type_bounds<'tcx>( // ParamEnv for normalization specifically. let normalize_param_env = { let mut predicates = param_env.caller_bounds().iter().collect::>(); - predicates.push( - ty::Binder::dummy(ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { - item_def_id: trait_ty.def_id, - substs: rebased_substs, - }, - ty: impl_ty_value, - }) - .to_predicate(tcx), - ); + match impl_ty_value.kind() { + ty::Projection(proj) + if proj.item_def_id == trait_ty.def_id && proj.substs == rebased_substs => + { + // Don't include this predicate if the projected type is + // exactly the same as the projection. This can occur in + // (somewhat dubious) code like this: + // + // impl X for T where T: X { type Y = ::Y; } + } + _ => predicates.push( + ty::Binder::dummy(ty::ProjectionPredicate { + projection_ty: ty::ProjectionTy { + item_def_id: trait_ty.def_id, + substs: rebased_substs, + }, + ty: impl_ty_value, + }) + .to_predicate(tcx), + ), + }; ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing) };