Add a helper for replacing the self type in trait refs
This commit is contained in:
parent
6f77c97b38
commit
19a1192d42
5 changed files with 15 additions and 29 deletions
|
@ -539,11 +539,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
.subst_iter_copied(self.tcx, substs)
|
.subst_iter_copied(self.tcx, substs)
|
||||||
{
|
{
|
||||||
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
|
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Trait(mut trait_pred) => {
|
ty::PredicateKind::Trait(trait_pred) => {
|
||||||
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
|
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
|
||||||
trait_pred.trait_ref.substs =
|
ty::PredicateKind::Trait(trait_pred.with_self_type(self.tcx, ty))
|
||||||
self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]);
|
|
||||||
ty::PredicateKind::Trait(trait_pred)
|
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(mut proj_pred) => {
|
ty::PredicateKind::Projection(mut proj_pred) => {
|
||||||
assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
|
assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
|
||||||
|
|
|
@ -852,6 +852,10 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||||
|
Self { trait_ref: self.trait_ref.with_self_type(tcx, self_ty), ..self }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn def_id(self) -> DefId {
|
pub fn def_id(self) -> DefId {
|
||||||
self.trait_ref.def_id
|
self.trait_ref.def_id
|
||||||
}
|
}
|
||||||
|
|
|
@ -811,6 +811,10 @@ impl<'tcx> TraitRef<'tcx> {
|
||||||
TraitRef { def_id, substs }
|
TraitRef { def_id, substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||||
|
tcx.mk_trait_ref(self.def_id, self_ty, &self.substs[1..])
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
|
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
|
||||||
/// are the parameters defined on trait.
|
/// are the parameters defined on trait.
|
||||||
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
|
pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> {
|
||||||
|
|
|
@ -998,13 +998,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
if trait_predicate.skip_binder().self_ty().is_never()
|
if trait_predicate.skip_binder().self_ty().is_never()
|
||||||
&& self.fallback_has_occurred
|
&& self.fallback_has_occurred
|
||||||
{
|
{
|
||||||
let predicate = trait_predicate.map_bound(|mut trait_pred| {
|
let predicate = trait_predicate.map_bound(|trait_pred| {
|
||||||
trait_pred.trait_ref = self.tcx.mk_trait_ref(
|
trait_pred.with_self_type(self.tcx, self.tcx.mk_unit())
|
||||||
trait_pred.trait_ref.def_id,
|
|
||||||
self.tcx.mk_unit(),
|
|
||||||
&trait_pred.trait_ref.substs[1..],
|
|
||||||
);
|
|
||||||
trait_pred
|
|
||||||
});
|
});
|
||||||
let unit_obligation = obligation.with(tcx, predicate);
|
let unit_obligation = obligation.with(tcx, predicate);
|
||||||
if self.predicate_may_hold(&unit_obligation) {
|
if self.predicate_may_hold(&unit_obligation) {
|
||||||
|
@ -2026,14 +2021,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
|
||||||
) -> PredicateObligation<'tcx> {
|
) -> PredicateObligation<'tcx> {
|
||||||
let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate {
|
let trait_pred = trait_ref_and_ty
|
||||||
trait_ref: self.tcx.mk_trait_ref(
|
.map_bound(|(tr, new_self_ty)| tr.with_self_type(self.tcx, new_self_ty));
|
||||||
tr.trait_ref.def_id,
|
|
||||||
*new_self_ty,
|
|
||||||
&tr.trait_ref.substs[1..],
|
|
||||||
),
|
|
||||||
..*tr
|
|
||||||
});
|
|
||||||
|
|
||||||
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
|
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,6 @@ pub(crate) fn update<'tcx, T>(
|
||||||
{
|
{
|
||||||
let new_self_ty = infcx.tcx.types.unit;
|
let new_self_ty = infcx.tcx.types.unit;
|
||||||
|
|
||||||
let trait_ref = infcx.tcx.mk_trait_ref(
|
|
||||||
tpred.trait_ref.def_id,
|
|
||||||
new_self_ty, &tpred.trait_ref.substs[1..],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Then construct a new obligation with Self = () added
|
// Then construct a new obligation with Self = () added
|
||||||
// to the ParamEnv, and see if it holds.
|
// to the ParamEnv, and see if it holds.
|
||||||
let o = obligation.with(infcx.tcx,
|
let o = obligation.with(infcx.tcx,
|
||||||
|
@ -31,11 +26,7 @@ pub(crate) fn update<'tcx, T>(
|
||||||
.kind()
|
.kind()
|
||||||
.rebind(
|
.rebind(
|
||||||
// (*) binder moved here
|
// (*) binder moved here
|
||||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
ty::PredicateKind::Trait(tpred.with_self_type(infcx.tcx, new_self_ty))
|
||||||
trait_ref,
|
|
||||||
constness: tpred.constness,
|
|
||||||
polarity: tpred.polarity,
|
|
||||||
})
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue