diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index ef5d8f925cf..36ae5d67f57 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -547,10 +547,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::PredicateKind::Clause(ty::Clause::Projection(mut proj_pred)) => { assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty); - proj_pred.projection_ty.substs = self.tcx.mk_substs_trait( - ty, - proj_pred.projection_ty.substs.iter().skip(1), - ); + proj_pred = proj_pred.with_self_ty(self.tcx, ty); ty::PredicateKind::Clause(ty::Clause::Projection(proj_pred)) } _ => continue, diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index e6a0d7e60ca..40b2588388d 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1258,7 +1258,7 @@ impl<'tcx> LateContext<'tcx> { tcx.associated_items(trait_id) .find_by_name_and_kind(tcx, Ident::from_str(name), ty::AssocKind::Type, trait_id) .and_then(|assoc| { - let proj = tcx.mk_projection(assoc.def_id, tcx.mk_substs_trait(self_ty, [])); + let proj = tcx.mk_projection(assoc.def_id, [self_ty]); tcx.try_normalize_erasing_regions(self.param_env, proj).ok() }) } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fc7bdb55352..5ca5ec28321 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2598,7 +2598,11 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { + pub fn mk_projection( + self, + item_def_id: DefId, + substs: impl IntoIterator>>, + ) -> Ty<'tcx> { self.mk_ty(Alias(ty::Projection, self.mk_alias_ty(item_def_id, substs))) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 82b41ac1f7b..5232c1e1cc0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1050,6 +1050,18 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { } } +impl<'tcx> ProjectionPredicate<'tcx> { + pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + Self { + projection_ty: tcx.mk_alias_ty( + self.projection_ty.def_id, + [self_ty.into()].into_iter().chain(self.projection_ty.substs.iter().skip(1)), + ), + ..self + } + } +} + pub trait ToPolyTraitRef<'tcx> { fn to_poly_trait_ref(&self) -> PolyTraitRef<'tcx>; } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index ec84243fbeb..f8b55c86287 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -336,8 +336,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let substs = tcx.mk_substs_trait(self_ty, []); - let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs); + let sig = tcx.bound_fn_sig(def_id).subst(tcx, &[self_ty.into()]); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -573,9 +572,8 @@ fn build_call_shim<'tcx>( // Create substitutions for the `Self` and `Args` generic parameters of the shim body. let arg_tup = tcx.mk_tup(untuple_args.iter()); - let sig_substs = tcx.mk_substs_trait(ty, [ty::subst::GenericArg::from(arg_tup)]); - (Some(sig_substs), Some(untuple_args)) + (Some([ty.into(), arg_tup.into()]), Some(untuple_args)) } else { (None, None) }; @@ -586,7 +584,7 @@ fn build_call_shim<'tcx>( assert_eq!(sig_substs.is_some(), !instance.has_polymorphic_mir_body()); let mut sig = - if let Some(sig_substs) = sig_substs { sig.subst(tcx, sig_substs) } else { sig.0 }; + if let Some(sig_substs) = sig_substs { sig.subst(tcx, &sig_substs) } else { sig.0 }; if let CallKind::Indirect(fnty) = call_kind { // `sig` determines our local decls, and thus the callee type in the `Call` terminator. This diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index f2ee0387888..414aee0c434 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2975,7 +2975,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.mk_projection( item_def_id, // Future::Output has no substs - self.tcx.mk_substs_trait(trait_pred.self_ty(), []), + [trait_pred.self_ty()], ) }); let InferOk { value: projection_ty, .. } = diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index ea4bf42c515..2566d793d78 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -425,13 +425,8 @@ pub fn fully_solve_bound<'tcx>( bound: DefId, ) -> Vec> { let tcx = infcx.tcx; - let trait_ref = ty::TraitRef { def_id: bound, substs: tcx.mk_substs_trait(ty, []) }; - let obligation = Obligation { - cause, - recursion_depth: 0, - param_env, - predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), - }; + let trait_ref = tcx.mk_trait_ref(bound, [ty]); + let obligation = Obligation::new(tcx, cause, param_env, ty::Binder::dummy(trait_ref)); fully_solve_obligation(infcx, obligation) }