1
Fork 0

Prevent the creation of TraitRef without dedicated methods

This commit is contained in:
Oli Scherer 2022-12-13 11:18:58 +00:00
parent a5cd3bde95
commit 6af3638709
9 changed files with 44 additions and 47 deletions

View file

@ -570,7 +570,7 @@ fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {
assoc_item, assoc_item,
assoc_item, assoc_item,
default.span, 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),
); );
} }
_ => {} _ => {}

View file

@ -160,7 +160,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
// instead of requiring an additional `+ 'a`. // instead of requiring an additional `+ 'a`.
match pred.kind().skip_binder() { match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate { ty::PredicateKind::Clause(ty::Clause::Trait(ty::TraitPredicate {
trait_ref: ty::TraitRef { def_id: _, substs }, trait_ref: ty::TraitRef { def_id: _, substs, .. },
constness: _, constness: _,
polarity: _, polarity: _,
})) => { })) => {

View file

@ -13,7 +13,7 @@ use rustc_hir_analysis::astconv::AstConv;
use rustc_infer::infer; use rustc_infer::infer;
use rustc_infer::traits::{self, StatementAsExpression}; use rustc_infer::traits::{self, StatementAsExpression};
use rustc_middle::lint::in_external_macro; 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_session::errors::ExprParenthesesNeeded;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use rustc_span::Span; 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 // Check that we're in fact trying to clone into the expected type
&& self.can_coerce(*pointee_ty, expected_ty) && self.can_coerce(*pointee_ty, expected_ty)
// And the expected type doesn't implement `Clone` // And the expected type doesn't implement `Clone`
&& !self.predicate_must_hold_considering_regions(&traits::Obligation { && !self.predicate_must_hold_considering_regions(&traits::Obligation::new(
cause: traits::ObligationCause::dummy(), self.tcx,
param_env: self.param_env, traits::ObligationCause::dummy(),
recursion_depth: 0, self.param_env,
predicate: ty::Binder::dummy(ty::TraitRef { ty::Binder::dummy(self.tcx.mk_trait_ref(
def_id: clone_trait_did, clone_trait_did,
substs: self.tcx.mk_substs([expected_ty.into()].iter()), [expected_ty],
}) )),
.without_const() ))
.to_predicate(self.tcx),
})
{ {
diag.span_note( diag.span_note(
callee_expr.span, callee_expr.span,

View file

@ -226,13 +226,11 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
false false
}; };
let expected_trait_ref = self.cx.resolve_vars_if_possible(ty::TraitRef { let expected_trait_ref = self
def_id: trait_def_id,
substs: expected_substs,
});
let actual_trait_ref = self
.cx .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) // Search the expected and actual trait references to see (a)
// whether the sub/sup placeholders appear in them (sometimes // whether the sub/sup placeholders appear in them (sometimes

View file

@ -322,7 +322,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id))) Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else { } else {
let substs = relate_substs(relation, a.substs, b.substs)?; 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))
} }
} }
} }

View file

@ -816,11 +816,14 @@ impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> {
pub struct TraitRef<'tcx> { pub struct TraitRef<'tcx> {
pub def_id: DefId, pub def_id: DefId,
pub substs: SubstsRef<'tcx>, 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> { impl<'tcx> TraitRef<'tcx> {
pub fn new(def_id: DefId, substs: SubstsRef<'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 { 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 { ty::Binder::dummy(TraitRef {
def_id, def_id,
substs: InternalSubsts::identity_for_item(tcx, 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>, substs: SubstsRef<'tcx>,
) -> ty::TraitRef<'tcx> { ) -> ty::TraitRef<'tcx> {
let defs = tcx.generics_of(trait_id); 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_def_id = self.trait_def_id(tcx);
let trait_generics = tcx.generics_of(trait_def_id); let trait_generics = tcx.generics_of(trait_def_id);
( (
ty::TraitRef { tcx.mk_trait_ref(trait_def_id, self.substs.truncate_to(tcx, trait_generics)),
def_id: trait_def_id,
substs: self.substs.truncate_to(tcx, trait_generics),
},
&self.substs[trait_generics.count()..], &self.substs[trait_generics.count()..],
) )
} }
@ -1211,7 +1216,7 @@ impl<'tcx> AliasTy<'tcx> {
/// as well. /// as well.
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> { pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
let def_id = self.trait_def_id(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> { pub fn self_ty(&self) -> Ty<'tcx> {

View file

@ -110,26 +110,25 @@ where
V: DefIdVisitor<'tcx> + ?Sized, V: DefIdVisitor<'tcx> + ?Sized,
{ {
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> { 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())?; 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) } 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> { fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
let tcx = self.def_id_visitor.tcx(); let tcx = self.def_id_visitor.tcx();
let (trait_ref, assoc_substs) = if tcx.def_kind(projection.def_id) let (trait_ref, assoc_substs) =
!= DefKind::ImplTraitPlaceholder if tcx.def_kind(projection.def_id) != DefKind::ImplTraitPlaceholder {
{ projection.trait_ref_and_own_substs(tcx)
projection.trait_ref_and_own_substs(tcx) } else {
} else { // HACK(RPITIT): Remove this when RPITITs are lowered to regular assoc tys
// 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 def_id = tcx.impl_trait_in_trait_parent(projection.def_id); let trait_generics = tcx.generics_of(def_id);
let trait_generics = tcx.generics_of(def_id); (
( tcx.mk_trait_ref(def_id, projection.substs.truncate_to(tcx, trait_generics)),
ty::TraitRef { def_id, substs: projection.substs.truncate_to(tcx, trait_generics) }, &projection.substs[trait_generics.count()..],
&projection.substs[trait_generics.count()..], )
) };
};
self.visit_trait(trait_ref)?; self.visit_trait(trait_ref)?;
if self.def_id_visitor.shallow() { if self.def_id_visitor.shallow() {
ControlFlow::CONTINUE ControlFlow::CONTINUE

View file

@ -703,9 +703,7 @@ fn receiver_is_dispatchable<'tcx>(
} }
}); });
ty::Binder::dummy(ty::TraitRef { def_id: unsize_did, substs }) ty::Binder::dummy(tcx.mk_trait_ref(unsize_did, substs)).to_predicate(tcx)
.without_const()
.to_predicate(tcx)
}; };
let caller_bounds: Vec<Predicate<'tcx>> = let caller_bounds: Vec<Predicate<'tcx>> =

View file

@ -1309,8 +1309,7 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
let trait_substs = let trait_substs =
obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id)); obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
// FIXME(named-returns): Binders // FIXME(named-returns): Binders
let trait_predicate = let trait_predicate = ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, trait_substs));
ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs });
let _ = selcx.infcx.commit_if_ok(|_| { let _ = selcx.infcx.commit_if_ok(|_| {
match selcx.select(&obligation.with(tcx, trait_predicate)) { match selcx.select(&obligation.with(tcx, trait_predicate)) {