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,
|
||||||
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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -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: _,
|
||||||
})) => {
|
})) => {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>> =
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue