Prevent the creation of TraitRef
without dedicated methods
This commit is contained in:
parent
a5cd3bde95
commit
6af3638709
9 changed files with 44 additions and 47 deletions
|
@ -570,7 +570,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
|
|||
assoc_item,
|
||||
assoc_item,
|
||||
default.span,
|
||||
ty::TraitRef { def_id: it.owner_id.to_def_id(), substs: trait_substs },
|
||||
tcx.mk_trait_ref(it.owner_id.to_def_id(), trait_substs),
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -160,7 +160,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
|||
// instead of requiring an additional `+ 'a`.
|
||||
match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef { def_id: _, substs },
|
||||
trait_ref: ty::TraitRef { def_id: _, substs, .. },
|
||||
constness: _,
|
||||
polarity: _,
|
||||
})) => {
|
||||
|
|
|
@ -13,7 +13,7 @@ use rustc_hir_analysis::astconv::AstConv;
|
|||
use rustc_infer::infer;
|
||||
use rustc_infer::traits::{self, StatementAsExpression};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::{self, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty};
|
||||
use rustc_middle::ty::{self, Binder, DefIdTree, IsSuggestable, Ty};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
|
@ -1277,17 +1277,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// Check that we're in fact trying to clone into the expected type
|
||||
&& self.can_coerce(*pointee_ty, expected_ty)
|
||||
// And the expected type doesn't implement `Clone`
|
||||
&& !self.predicate_must_hold_considering_regions(&traits::Obligation {
|
||||
cause: traits::ObligationCause::dummy(),
|
||||
param_env: self.param_env,
|
||||
recursion_depth: 0,
|
||||
predicate: ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: clone_trait_did,
|
||||
substs: self.tcx.mk_substs([expected_ty.into()].iter()),
|
||||
})
|
||||
.without_const()
|
||||
.to_predicate(self.tcx),
|
||||
})
|
||||
&& !self.predicate_must_hold_considering_regions(&traits::Obligation::new(
|
||||
self.tcx,
|
||||
traits::ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(self.tcx.mk_trait_ref(
|
||||
clone_trait_did,
|
||||
[expected_ty],
|
||||
)),
|
||||
))
|
||||
{
|
||||
diag.span_note(
|
||||
callee_expr.span,
|
||||
|
|
|
@ -226,13 +226,11 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
|
|||
false
|
||||
};
|
||||
|
||||
let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: expected_substs,
|
||||
});
|
||||
let actual_trait_ref = self
|
||||
let expected_trait_ref = self
|
||||
.cx
|
||||
.resolve_vars_if_possible(ty::TraitRef { def_id: trait_def_id, substs: actual_substs });
|
||||
.resolve_vars_if_possible(self.cx.tcx.mk_trait_ref(trait_def_id, expected_substs));
|
||||
let actual_trait_ref =
|
||||
self.cx.resolve_vars_if_possible(self.cx.tcx.mk_trait_ref(trait_def_id, actual_substs));
|
||||
|
||||
// Search the expected and actual trait references to see (a)
|
||||
// whether the sub/sup placeholders appear in them (sometimes
|
||||
|
|
|
@ -322,7 +322,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
|
|||
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
|
||||
} else {
|
||||
let substs = relate_substs(relation, a.substs, b.substs)?;
|
||||
Ok(ty::TraitRef { def_id: a.def_id, substs })
|
||||
Ok(relation.tcx().mk_trait_ref(a.def_id, substs))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -816,11 +816,14 @@ impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> {
|
|||
pub struct TraitRef<'tcx> {
|
||||
pub def_id: DefId,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
/// This field exists to prevent the creation of `TraitRef` without
|
||||
/// calling [TyCtxt::mk_trait_ref].
|
||||
_use_mk_trait_ref_instead: (),
|
||||
}
|
||||
|
||||
impl<'tcx> TraitRef<'tcx> {
|
||||
pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> TraitRef<'tcx> {
|
||||
TraitRef { def_id, substs }
|
||||
TraitRef { def_id, substs, _use_mk_trait_ref_instead: () }
|
||||
}
|
||||
|
||||
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||
|
@ -836,6 +839,7 @@ impl<'tcx> TraitRef<'tcx> {
|
|||
ty::Binder::dummy(TraitRef {
|
||||
def_id,
|
||||
substs: InternalSubsts::identity_for_item(tcx, def_id),
|
||||
_use_mk_trait_ref_instead: (),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -850,7 +854,11 @@ impl<'tcx> TraitRef<'tcx> {
|
|||
substs: SubstsRef<'tcx>,
|
||||
) -> ty::TraitRef<'tcx> {
|
||||
let defs = tcx.generics_of(trait_id);
|
||||
ty::TraitRef { def_id: trait_id, substs: tcx.intern_substs(&substs[..defs.params.len()]) }
|
||||
ty::TraitRef {
|
||||
def_id: trait_id,
|
||||
substs: tcx.intern_substs(&substs[..defs.params.len()]),
|
||||
_use_mk_trait_ref_instead: (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1194,10 +1202,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
let trait_def_id = self.trait_def_id(tcx);
|
||||
let trait_generics = tcx.generics_of(trait_def_id);
|
||||
(
|
||||
ty::TraitRef {
|
||||
def_id: trait_def_id,
|
||||
substs: self.substs.truncate_to(tcx, trait_generics),
|
||||
},
|
||||
tcx.mk_trait_ref(trait_def_id, self.substs.truncate_to(tcx, trait_generics)),
|
||||
&self.substs[trait_generics.count()..],
|
||||
)
|
||||
}
|
||||
|
@ -1211,7 +1216,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
/// as well.
|
||||
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
|
||||
let def_id = self.trait_def_id(tcx);
|
||||
ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, tcx.generics_of(def_id)) }
|
||||
tcx.mk_trait_ref(def_id, self.substs.truncate_to(tcx, tcx.generics_of(def_id)))
|
||||
}
|
||||
|
||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||
|
|
|
@ -110,26 +110,25 @@ where
|
|||
V: DefIdVisitor<'tcx> + ?Sized,
|
||||
{
|
||||
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||
let TraitRef { def_id, substs } = trait_ref;
|
||||
let TraitRef { def_id, substs, .. } = trait_ref;
|
||||
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path())?;
|
||||
if self.def_id_visitor.shallow() { ControlFlow::CONTINUE } else { substs.visit_with(self) }
|
||||
}
|
||||
|
||||
fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||
let tcx = self.def_id_visitor.tcx();
|
||||
let (trait_ref, assoc_substs) = if tcx.def_kind(projection.def_id)
|
||||
!= DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
projection.trait_ref_and_own_substs(tcx)
|
||||
} else {
|
||||
// HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
|
||||
let def_id = tcx.impl_trait_in_trait_parent(projection.def_id);
|
||||
let trait_generics = tcx.generics_of(def_id);
|
||||
(
|
||||
ty::TraitRef { def_id, substs: projection.substs.truncate_to(tcx, trait_generics) },
|
||||
&projection.substs[trait_generics.count()..],
|
||||
)
|
||||
};
|
||||
let (trait_ref, assoc_substs) =
|
||||
if tcx.def_kind(projection.def_id) != DefKind::ImplTraitPlaceholder {
|
||||
projection.trait_ref_and_own_substs(tcx)
|
||||
} else {
|
||||
// HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
|
||||
let def_id = tcx.impl_trait_in_trait_parent(projection.def_id);
|
||||
let trait_generics = tcx.generics_of(def_id);
|
||||
(
|
||||
tcx.mk_trait_ref(def_id, projection.substs.truncate_to(tcx, trait_generics)),
|
||||
&projection.substs[trait_generics.count()..],
|
||||
)
|
||||
};
|
||||
self.visit_trait(trait_ref)?;
|
||||
if self.def_id_visitor.shallow() {
|
||||
ControlFlow::CONTINUE
|
||||
|
|
|
@ -703,9 +703,7 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
}
|
||||
});
|
||||
|
||||
ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs })
|
||||
.without_const()
|
||||
.to_predicate(tcx)
|
||||
ty::Binder::dummy(tcx.mk_trait_ref(unsize_did, substs)).to_predicate(tcx)
|
||||
};
|
||||
|
||||
let caller_bounds: Vec<Predicate<'tcx>> =
|
||||
|
|
|
@ -1309,8 +1309,7 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
|||
let trait_substs =
|
||||
obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
|
||||
// FIXME(named-returns): Binders
|
||||
let trait_predicate =
|
||||
ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs });
|
||||
let trait_predicate = ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, trait_substs));
|
||||
|
||||
let _ = selcx.infcx.commit_if_ok(|_| {
|
||||
match selcx.select(&obligation.with(tcx, trait_predicate)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue