Avoid creating useless projection predicate

This commit is contained in:
Matthew Jasper 2020-09-07 09:38:09 +01:00
parent 27534b3932
commit 1db284ecb0
1 changed files with 21 additions and 10 deletions

View File

@ -1205,16 +1205,27 @@ pub fn check_type_bounds<'tcx>(
// ParamEnv for normalization specifically. // ParamEnv for normalization specifically.
let normalize_param_env = { let normalize_param_env = {
let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>(); let mut predicates = param_env.caller_bounds().iter().collect::<Vec<_>>();
predicates.push( match impl_ty_value.kind() {
ty::Binder::dummy(ty::ProjectionPredicate { ty::Projection(proj)
projection_ty: ty::ProjectionTy { if proj.item_def_id == trait_ty.def_id && proj.substs == rebased_substs =>
item_def_id: trait_ty.def_id, {
substs: rebased_substs, // Don't include this predicate if the projected type is
}, // exactly the same as the projection. This can occur in
ty: impl_ty_value, // (somewhat dubious) code like this:
}) //
.to_predicate(tcx), // impl<T> X for T where T: X { type Y = <T as X>::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) ty::ParamEnv::new(tcx.intern_predicates(&predicates), Reveal::UserFacing)
}; };