Switch next solver to use a specific associated type for trait def id

The compiler just puts `DefId` in there, but rust-analyzer uses different types for each kind of item.
This commit is contained in:
Chayim Refael Friedman 2025-08-14 06:19:51 +03:00
parent f6d23413c3
commit 38bd8081b7
18 changed files with 234 additions and 178 deletions

View file

@ -52,7 +52,7 @@ use rustc_session::{Limit, Session};
use rustc_span::def_id::{CRATE_DEF_ID, DefPathHash, StableCrateId};
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
use rustc_type_ir::TyKind::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::lang_items::{SolverLangItem, SolverTraitLangItem};
pub use rustc_type_ir::lift::Lift;
use rustc_type_ir::{
CollectAndApply, Interner, TypeFlags, TypeFoldable, WithCachedTypeInfo, elaborate, search_graph,
@ -93,6 +93,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type DefId = DefId;
type LocalDefId = LocalDefId;
type TraitId = DefId;
type Span = Span;
type GenericArgs = ty::GenericArgsRef<'tcx>;
@ -483,20 +484,32 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
!self.codegen_fn_attrs(def_id).target_features.is_empty()
}
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
self.require_lang_item(trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
fn require_lang_item(self, lang_item: SolverLangItem) -> DefId {
self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
}
fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
}
fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool {
self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
}
fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
}
fn is_default_trait(self, def_id: DefId) -> bool {
self.is_default_trait(def_id)
}
fn as_lang_item(self, def_id: DefId) -> Option<TraitSolverLangItem> {
lang_item_to_trait_lang_item(self.lang_items().from_def_id(def_id)?)
fn as_lang_item(self, def_id: DefId) -> Option<SolverLangItem> {
lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
}
fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
}
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
@ -727,16 +740,19 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
}
macro_rules! bidirectional_lang_item_map {
($($name:ident),+ $(,)?) => {
fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
(
$solver_ty:ident, $to_solver:ident, $from_solver:ident;
$($name:ident),+ $(,)?
) => {
fn $from_solver(lang_item: $solver_ty) -> LangItem {
match lang_item {
$(TraitSolverLangItem::$name => LangItem::$name,)+
$($solver_ty::$name => LangItem::$name,)+
}
}
fn lang_item_to_trait_lang_item(lang_item: LangItem) -> Option<TraitSolverLangItem> {
fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
Some(match lang_item {
$(LangItem::$name => TraitSolverLangItem::$name,)+
$(LangItem::$name => $solver_ty::$name,)+
_ => return None,
})
}
@ -744,40 +760,50 @@ macro_rules! bidirectional_lang_item_map {
}
bidirectional_lang_item_map! {
SolverLangItem, lang_item_to_solver_lang_item, solver_lang_item_to_lang_item;
// tidy-alphabetical-start
AsyncFnKindUpvars,
AsyncFnOnceOutput,
CallOnceFuture,
CallRefFuture,
CoroutineReturn,
CoroutineYield,
DynMetadata,
FutureOutput,
Metadata,
Option,
Poll,
// tidy-alphabetical-end
}
bidirectional_lang_item_map! {
SolverTraitLangItem, lang_item_to_solver_trait_lang_item, solver_trait_lang_item_to_lang_item;
// tidy-alphabetical-start
AsyncFn,
AsyncFnKindHelper,
AsyncFnKindUpvars,
AsyncFnMut,
AsyncFnOnce,
AsyncFnOnceOutput,
AsyncIterator,
BikeshedGuaranteedNoDrop,
CallOnceFuture,
CallRefFuture,
Clone,
Copy,
Coroutine,
CoroutineReturn,
CoroutineYield,
Destruct,
DiscriminantKind,
Drop,
DynMetadata,
Fn,
FnMut,
FnOnce,
FnPtrTrait,
FusedIterator,
Future,
FutureOutput,
Iterator,
MetaSized,
Metadata,
Option,
PointeeSized,
PointeeTrait,
Poll,
Sized,
TransmuteTrait,
Tuple,

View file

@ -295,7 +295,7 @@ where
ControlFlow::Break(OrphanCheckEarlyExit::UncoveredTyParam(ty))
}
fn def_id_is_local(&mut self, def_id: I::DefId) -> bool {
fn def_id_is_local(&mut self, def_id: impl DefId<I>) -> bool {
match self.in_crate {
InCrate::Local { .. } => def_id.is_local(),
InCrate::Remote => false,

View file

@ -7,7 +7,7 @@ use std::ops::ControlFlow;
use derive_where::derive_where;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::search_graph::CandidateHeadUsages;
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::{
@ -54,7 +54,7 @@ where
fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self;
fn trait_def_id(self, cx: I) -> I::DefId;
fn trait_def_id(self, cx: I) -> I::TraitId;
/// Consider a clause, which consists of a "assumption" and some "requirements",
/// to satisfy a goal. If the requirements hold, then attempt to satisfy our
@ -516,80 +516,80 @@ where
} else if cx.trait_is_alias(trait_def_id) {
G::consider_trait_alias_candidate(self, goal)
} else {
match cx.as_lang_item(trait_def_id) {
Some(TraitSolverLangItem::Sized) => {
match cx.as_trait_lang_item(trait_def_id) {
Some(SolverTraitLangItem::Sized) => {
G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::Sized)
}
Some(TraitSolverLangItem::MetaSized) => {
Some(SolverTraitLangItem::MetaSized) => {
G::consider_builtin_sizedness_candidates(self, goal, SizedTraitKind::MetaSized)
}
Some(TraitSolverLangItem::PointeeSized) => {
Some(SolverTraitLangItem::PointeeSized) => {
unreachable!("`PointeeSized` is removed during lowering");
}
Some(TraitSolverLangItem::Copy | TraitSolverLangItem::Clone) => {
Some(SolverTraitLangItem::Copy | SolverTraitLangItem::Clone) => {
G::consider_builtin_copy_clone_candidate(self, goal)
}
Some(TraitSolverLangItem::Fn) => {
Some(SolverTraitLangItem::Fn) => {
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::Fn)
}
Some(TraitSolverLangItem::FnMut) => {
Some(SolverTraitLangItem::FnMut) => {
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::FnMut)
}
Some(TraitSolverLangItem::FnOnce) => {
Some(SolverTraitLangItem::FnOnce) => {
G::consider_builtin_fn_trait_candidates(self, goal, ty::ClosureKind::FnOnce)
}
Some(TraitSolverLangItem::AsyncFn) => {
Some(SolverTraitLangItem::AsyncFn) => {
G::consider_builtin_async_fn_trait_candidates(self, goal, ty::ClosureKind::Fn)
}
Some(TraitSolverLangItem::AsyncFnMut) => {
Some(SolverTraitLangItem::AsyncFnMut) => {
G::consider_builtin_async_fn_trait_candidates(
self,
goal,
ty::ClosureKind::FnMut,
)
}
Some(TraitSolverLangItem::AsyncFnOnce) => {
Some(SolverTraitLangItem::AsyncFnOnce) => {
G::consider_builtin_async_fn_trait_candidates(
self,
goal,
ty::ClosureKind::FnOnce,
)
}
Some(TraitSolverLangItem::FnPtrTrait) => {
Some(SolverTraitLangItem::FnPtrTrait) => {
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
}
Some(TraitSolverLangItem::AsyncFnKindHelper) => {
Some(SolverTraitLangItem::AsyncFnKindHelper) => {
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
}
Some(TraitSolverLangItem::Tuple) => G::consider_builtin_tuple_candidate(self, goal),
Some(TraitSolverLangItem::PointeeTrait) => {
Some(SolverTraitLangItem::Tuple) => G::consider_builtin_tuple_candidate(self, goal),
Some(SolverTraitLangItem::PointeeTrait) => {
G::consider_builtin_pointee_candidate(self, goal)
}
Some(TraitSolverLangItem::Future) => {
Some(SolverTraitLangItem::Future) => {
G::consider_builtin_future_candidate(self, goal)
}
Some(TraitSolverLangItem::Iterator) => {
Some(SolverTraitLangItem::Iterator) => {
G::consider_builtin_iterator_candidate(self, goal)
}
Some(TraitSolverLangItem::FusedIterator) => {
Some(SolverTraitLangItem::FusedIterator) => {
G::consider_builtin_fused_iterator_candidate(self, goal)
}
Some(TraitSolverLangItem::AsyncIterator) => {
Some(SolverTraitLangItem::AsyncIterator) => {
G::consider_builtin_async_iterator_candidate(self, goal)
}
Some(TraitSolverLangItem::Coroutine) => {
Some(SolverTraitLangItem::Coroutine) => {
G::consider_builtin_coroutine_candidate(self, goal)
}
Some(TraitSolverLangItem::DiscriminantKind) => {
Some(SolverTraitLangItem::DiscriminantKind) => {
G::consider_builtin_discriminant_kind_candidate(self, goal)
}
Some(TraitSolverLangItem::Destruct) => {
Some(SolverTraitLangItem::Destruct) => {
G::consider_builtin_destruct_candidate(self, goal)
}
Some(TraitSolverLangItem::TransmuteTrait) => {
Some(SolverTraitLangItem::TransmuteTrait) => {
G::consider_builtin_transmute_candidate(self, goal)
}
Some(TraitSolverLangItem::BikeshedGuaranteedNoDrop) => {
Some(SolverTraitLangItem::BikeshedGuaranteedNoDrop) => {
G::consider_builtin_bikeshed_guaranteed_no_drop_candidate(self, goal)
}
_ => Err(NoSolution),
@ -600,7 +600,7 @@ where
// There may be multiple unsize candidates for a trait with several supertraits:
// `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
if cx.is_lang_item(trait_def_id, TraitSolverLangItem::Unsize) {
if cx.is_trait_lang_item(trait_def_id, SolverTraitLangItem::Unsize) {
candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal));
}
}

View file

@ -4,7 +4,7 @@
use derive_where::derive_where;
use rustc_type_ir::data_structures::HashMap;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::lang_items::{SolverLangItem, SolverTraitLangItem};
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::solve::inspect::ProbeKind;
use rustc_type_ir::{
@ -454,7 +454,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
nested.push(
ty::TraitRef::new(
cx,
cx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper),
cx.require_trait_lang_item(SolverTraitLangItem::AsyncFnKindHelper),
[kind_ty, Ty::from_closure_kind(cx, goal_kind)],
)
.upcast(cx),
@ -496,7 +496,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
let args = args.as_closure();
let bound_sig = args.sig();
let sig = bound_sig.skip_binder();
let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future);
let future_trait_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Future);
// `Closure`s only implement `AsyncFn*` when their return type
// implements `Future`.
let mut nested = vec![
@ -514,7 +514,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
}
} else {
let async_fn_kind_trait_def_id =
cx.require_lang_item(TraitSolverLangItem::AsyncFnKindHelper);
cx.require_trait_lang_item(SolverTraitLangItem::AsyncFnKindHelper);
// When we don't know the closure kind (and therefore also the closure's upvars,
// which are computed at the same time), we must delay the computation of the
// generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait
@ -532,7 +532,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
);
}
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
let future_output_def_id = cx.require_lang_item(SolverLangItem::FutureOutput);
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
@ -581,13 +581,13 @@ fn fn_item_to_async_callable<I: Interner>(
bound_sig: ty::Binder<I, ty::FnSig<I>>,
) -> Result<(ty::Binder<I, AsyncCallableRelevantTypes<I>>, Vec<I::Predicate>), NoSolution> {
let sig = bound_sig.skip_binder();
let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future);
let future_trait_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Future);
// `FnDef` and `FnPtr` only implement `AsyncFn*` when their
// return type implements `Future`.
let nested = vec![
bound_sig.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()])).upcast(cx),
];
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
let future_output_def_id = cx.require_lang_item(SolverLangItem::FutureOutput);
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
@ -633,7 +633,7 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
args: ty::CoroutineClosureArgs<I>,
sig: ty::CoroutineClosureSignature<I>,
) -> I::Ty {
let upvars_projection_def_id = cx.require_lang_item(TraitSolverLangItem::AsyncFnKindUpvars);
let upvars_projection_def_id = cx.require_lang_item(SolverLangItem::AsyncFnKindUpvars);
let tupled_upvars_ty = Ty::new_projection(
cx,
upvars_projection_def_id,
@ -732,7 +732,7 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
cx: I,
self_ty: I::Ty,
) -> Result<Vec<ty::TraitRef<I>>, NoSolution> {
let destruct_def_id = cx.require_lang_item(TraitSolverLangItem::Destruct);
let destruct_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Destruct);
match self_ty.kind() {
// `ManuallyDrop` is trivially `[const] Destruct` as we do not run any drop glue on it.
@ -751,7 +751,7 @@ pub(in crate::solve) fn const_conditions_for_destruct<I: Interner>(
Some(AdtDestructorKind::NotConst) => return Err(NoSolution),
// `Drop` impl exists, and it's const. Require `Ty: [const] Drop` to hold.
Some(AdtDestructorKind::Const) => {
let drop_def_id = cx.require_lang_item(TraitSolverLangItem::Drop);
let drop_def_id = cx.require_trait_lang_item(SolverTraitLangItem::Drop);
let drop_trait_ref = ty::TraitRef::new(cx, drop_def_id, [self_ty]);
const_conditions.push(drop_trait_ref);
}
@ -869,7 +869,7 @@ where
// FIXME(associated_const_equality): Also add associated consts to
// the requirements here.
for associated_type_def_id in cx.associated_type_def_ids(trait_ref.def_id) {
for associated_type_def_id in cx.associated_type_def_ids(trait_ref.def_id.into()) {
// associated types that require `Self: Sized` do not show up in the built-in
// implementation of `Trait for dyn Trait`, and can be dropped here.
if cx.generics_require_sized_self(associated_type_def_id) {

View file

@ -3,7 +3,7 @@
use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::solve::inspect::ProbeKind;
use rustc_type_ir::{self as ty, Interner, TypingMode, elaborate};
@ -33,7 +33,7 @@ where
self.with_replaced_self_ty(cx, self_ty)
}
fn trait_def_id(self, _: I) -> I::DefId {
fn trait_def_id(self, _: I) -> I::TraitId {
self.def_id()
}
@ -237,7 +237,7 @@ where
// A built-in `Fn` impl only holds if the output is sized.
// (FIXME: technically we only need to check this if the type is a fn ptr...)
let output_is_sized_pred = inputs_and_output.map_bound(|(_, output)| {
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
});
let requirements = cx
.const_conditions(def_id)

View file

@ -130,7 +130,7 @@ where
}
}
fn compute_dyn_compatible_goal(&mut self, trait_def_id: I::DefId) -> QueryResult<I> {
fn compute_dyn_compatible_goal(&mut self, trait_def_id: I::TraitId) -> QueryResult<I> {
if self.cx().trait_is_dyn_compatible(trait_def_id) {
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} else {

View file

@ -5,7 +5,7 @@ mod opaque_types;
use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::lang_items::{SolverLangItem, SolverTraitLangItem};
use rustc_type_ir::solve::SizedTraitKind;
use rustc_type_ir::{self as ty, Interner, NormalizesTo, PredicateKind, Upcast as _};
use tracing::instrument;
@ -103,7 +103,7 @@ where
self.with_replaced_self_ty(cx, self_ty)
}
fn trait_def_id(self, cx: I) -> I::DefId {
fn trait_def_id(self, cx: I) -> I::TraitId {
self.trait_def_id(cx)
}
@ -456,7 +456,7 @@ where
// A built-in `Fn` impl only holds if the output is sized.
// (FIXME: technically we only need to check this if the type is a fn ptr...)
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
});
let pred = tupled_inputs_and_output
@ -503,7 +503,11 @@ where
// (FIXME: technically we only need to check this if the type is a fn ptr...)
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output_ty])
ty::TraitRef::new(
cx,
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
[output_ty],
)
},
);
@ -515,7 +519,7 @@ where
coroutine_return_ty,
}| {
let (projection_term, term) = if cx
.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallOnceFuture)
.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallOnceFuture)
{
(
ty::AliasTerm::new(
@ -526,7 +530,7 @@ where
output_coroutine_ty.into(),
)
} else if cx
.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CallRefFuture)
.is_lang_item(goal.predicate.def_id(), SolverLangItem::CallRefFuture)
{
(
ty::AliasTerm::new(
@ -540,10 +544,9 @@ where
),
output_coroutine_ty.into(),
)
} else if cx.is_lang_item(
goal.predicate.def_id(),
TraitSolverLangItem::AsyncFnOnceOutput,
) {
} else if cx
.is_lang_item(goal.predicate.def_id(), SolverLangItem::AsyncFnOnceOutput)
{
(
ty::AliasTerm::new(
cx,
@ -637,7 +640,7 @@ where
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution> {
let cx = ecx.cx();
let metadata_def_id = cx.require_lang_item(TraitSolverLangItem::Metadata);
let metadata_def_id = cx.require_lang_item(SolverLangItem::Metadata);
assert_eq!(metadata_def_id, goal.predicate.def_id());
let metadata_ty = match goal.predicate.self_ty().kind() {
ty::Bool
@ -664,7 +667,7 @@ where
ty::Str | ty::Slice(_) => Ty::new_usize(cx),
ty::Dynamic(_, _, ty::Dyn) => {
let dyn_metadata = cx.require_lang_item(TraitSolverLangItem::DynMetadata);
let dyn_metadata = cx.require_lang_item(SolverLangItem::DynMetadata);
cx.type_of(dyn_metadata)
.instantiate(cx, &[I::GenericArg::from(goal.predicate.self_ty())])
}
@ -678,7 +681,7 @@ where
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let sized_predicate = ty::TraitRef::new(
cx,
cx.require_lang_item(TraitSolverLangItem::Sized),
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
[I::GenericArg::from(goal.predicate.self_ty())],
);
ecx.add_goal(GoalSource::Misc, goal.with(cx, sized_predicate));
@ -821,10 +824,10 @@ where
// coroutine yield ty `Poll<Option<I>>`.
let wrapped_expected_ty = Ty::new_adt(
cx,
cx.adt_def(cx.require_lang_item(TraitSolverLangItem::Poll)),
cx.adt_def(cx.require_lang_item(SolverLangItem::Poll)),
cx.mk_args(&[Ty::new_adt(
cx,
cx.adt_def(cx.require_lang_item(TraitSolverLangItem::Option)),
cx.adt_def(cx.require_lang_item(SolverLangItem::Option)),
cx.mk_args(&[expected_ty.into()]),
)
.into()]),
@ -853,10 +856,9 @@ where
let coroutine = args.as_coroutine();
let term = if cx.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CoroutineReturn)
{
let term = if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CoroutineReturn) {
coroutine.return_ty().into()
} else if cx.is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::CoroutineYield) {
} else if cx.is_lang_item(goal.predicate.def_id(), SolverLangItem::CoroutineYield) {
coroutine.yield_ty().into()
} else {
panic!("unexpected associated item `{:?}` for `{self_ty:?}`", goal.predicate.def_id())
@ -983,13 +985,13 @@ where
target_container_def_id: I::DefId,
) -> Result<I::GenericArgs, NoSolution> {
let cx = self.cx();
Ok(if target_container_def_id == impl_trait_ref.def_id {
Ok(if target_container_def_id == impl_trait_ref.def_id.into() {
// Default value from the trait definition. No need to rebase.
goal.predicate.alias.args
} else if target_container_def_id == impl_def_id {
// Same impl, no need to fully translate, just a rebase from
// the trait is sufficient.
goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id, impl_args)
goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id.into(), impl_args)
} else {
let target_args = self.fresh_args_for_item(target_container_def_id);
let target_trait_ref =
@ -1004,7 +1006,7 @@ where
.iter_instantiated(cx, target_args)
.map(|pred| goal.with(cx, pred)),
);
goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id, target_args)
goal.predicate.alias.args.rebase_onto(cx, impl_trait_ref.def_id.into(), target_args)
})
}
}

View file

@ -3,7 +3,7 @@
use rustc_type_ir::data_structures::IndexSet;
use rustc_type_ir::fast_reject::DeepRejectCtxt;
use rustc_type_ir::inherent::*;
use rustc_type_ir::lang_items::TraitSolverLangItem;
use rustc_type_ir::lang_items::SolverTraitLangItem;
use rustc_type_ir::solve::{CanonicalResponse, SizedTraitKind};
use rustc_type_ir::{
self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
@ -39,7 +39,7 @@ where
self.with_replaced_self_ty(cx, self_ty)
}
fn trait_def_id(self, _: I) -> I::DefId {
fn trait_def_id(self, _: I) -> I::TraitId {
self.def_id()
}
@ -131,8 +131,8 @@ where
) -> Result<(), NoSolution> {
fn trait_def_id_matches<I: Interner>(
cx: I,
clause_def_id: I::DefId,
goal_def_id: I::DefId,
clause_def_id: I::TraitId,
goal_def_id: I::TraitId,
polarity: PredicatePolarity,
) -> bool {
clause_def_id == goal_def_id
@ -141,8 +141,8 @@ where
//
// `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
|| (polarity == PredicatePolarity::Positive
&& cx.is_lang_item(clause_def_id, TraitSolverLangItem::Sized)
&& cx.is_lang_item(goal_def_id, TraitSolverLangItem::MetaSized))
&& cx.is_trait_lang_item(clause_def_id, SolverTraitLangItem::Sized)
&& cx.is_trait_lang_item(goal_def_id, SolverTraitLangItem::MetaSized))
}
if let Some(trait_clause) = assumption.as_trait_clause()
@ -177,8 +177,8 @@ where
// are syntactic sugar for a lack of bounds so don't need this.
// We don't need to check polarity, `fast_reject_assumption` already rejected non-`Positive`
// polarity `Sized` assumptions as matching non-`Positive` `MetaSized` goals.
if ecx.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::MetaSized)
&& ecx.cx().is_lang_item(trait_clause.def_id(), TraitSolverLangItem::Sized)
if ecx.cx().is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::MetaSized)
&& ecx.cx().is_trait_lang_item(trait_clause.def_id(), SolverTraitLangItem::Sized)
{
let meta_sized_clause =
trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
@ -263,7 +263,7 @@ where
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let nested_obligations = cx
.predicates_of(goal.predicate.def_id())
.predicates_of(goal.predicate.def_id().into())
.iter_instantiated(cx, goal.predicate.trait_ref.args)
.map(|p| goal.with(cx, p));
// While you could think of trait aliases to have a single builtin impl
@ -372,7 +372,7 @@ where
// A built-in `Fn` impl only holds if the output is sized.
// (FIXME: technically we only need to check this if the type is a fn ptr...)
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output])
});
let pred = tupled_inputs_and_output
@ -414,7 +414,7 @@ where
|AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
ty::TraitRef::new(
cx,
cx.require_lang_item(TraitSolverLangItem::Sized),
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
[output_coroutine_ty],
)
},
@ -757,7 +757,7 @@ where
cx,
ty::TraitRef::new(
cx,
cx.require_lang_item(TraitSolverLangItem::Copy),
cx.require_trait_lang_item(SolverTraitLangItem::Copy),
[ty],
),
),
@ -857,7 +857,7 @@ where
fn trait_predicate_with_def_id<I: Interner>(
cx: I,
clause: ty::Binder<I, ty::TraitPredicate<I>>,
did: I::DefId,
did: I::TraitId,
) -> I::Clause {
clause
.map_bound(|c| TraitPredicate {
@ -956,7 +956,11 @@ where
GoalSource::ImplWhereBound,
goal.with(
cx,
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [a_ty]),
ty::TraitRef::new(
cx,
cx.require_trait_lang_item(SolverTraitLangItem::Sized),
[a_ty],
),
),
);
@ -981,7 +985,7 @@ where
// We may upcast to auto traits that are either explicitly listed in
// the object type's bounds, or implied by the principal trait ref's
// supertraits.
let a_auto_traits: IndexSet<I::DefId> = a_data
let a_auto_traits: IndexSet<I::TraitId> = a_data
.auto_traits()
.into_iter()
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
@ -1143,7 +1147,7 @@ where
cx,
ty::TraitRef::new(
cx,
cx.require_lang_item(TraitSolverLangItem::Unsize),
cx.require_trait_lang_item(SolverTraitLangItem::Unsize),
[a_tail_ty, b_tail_ty],
),
),
@ -1208,7 +1212,9 @@ where
// takes precedence over the structural auto trait candidate being
// assembled.
ty::Coroutine(def_id, _)
if self.cx().is_lang_item(goal.predicate.def_id(), TraitSolverLangItem::Unpin) =>
if self
.cx()
.is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::Unpin) =>
{
match self.cx().coroutine_movability(def_id) {
Movability::Static => Some(Err(NoSolution)),

View file

@ -4,7 +4,7 @@ use smallvec::smallvec;
use crate::data_structures::HashSet;
use crate::inherent::*;
use crate::lang_items::TraitSolverLangItem;
use crate::lang_items::SolverTraitLangItem;
use crate::outlives::{Component, push_outlives_components};
use crate::{self as ty, Interner, Upcast as _};
@ -140,7 +140,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
// is present.
if self.elaborate_sized == ElaborateSized::No
&& let Some(did) = clause.as_trait_clause().map(|c| c.def_id())
&& self.cx.is_lang_item(did, TraitSolverLangItem::Sized)
&& self.cx.is_trait_lang_item(did, SolverTraitLangItem::Sized)
{
return;
}
@ -166,7 +166,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
// Get predicates implied by the trait, or only super predicates if we only care about self predicates.
match self.mode {
Filter::All => self.extend_deduped(
cx.explicit_implied_predicates_of(data.def_id())
cx.explicit_implied_predicates_of(data.def_id().into())
.iter_identity()
.enumerate()
.map(map_to_child_clause),
@ -181,13 +181,15 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
}
// `T: [const] Trait` implies `T: [const] Supertrait`.
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
elaboratable.child(
trait_ref
.to_host_effect_clause(cx, data.constness)
.instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)),
)
}),
cx.explicit_implied_const_bounds(data.def_id().into()).iter_identity().map(
|trait_ref| {
elaboratable.child(
trait_ref
.to_host_effect_clause(cx, data.constness)
.instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)),
)
},
),
),
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
// We know that `T: 'a` for some type `T`. We can
@ -312,8 +314,8 @@ impl<I: Interner, O: Elaboratable<I>> Iterator for Elaborator<I, O> {
/// and to make size estimates for vtable layout computation.
pub fn supertrait_def_ids<I: Interner>(
cx: I,
trait_def_id: I::DefId,
) -> impl Iterator<Item = I::DefId> {
trait_def_id: I::TraitId,
) -> impl Iterator<Item = I::TraitId> {
let mut set = HashSet::default();
let mut stack = vec![trait_def_id];

View file

@ -38,7 +38,7 @@ pub enum TypeError<I: Interner> {
Sorts(ExpectedFound<I::Ty>),
ArgumentSorts(ExpectedFound<I::Ty>, usize),
Traits(ExpectedFound<I::DefId>),
Traits(ExpectedFound<I::TraitId>),
VariadicMismatch(ExpectedFound<bool>),
/// Instantiating a type variable with the given type would have

View file

@ -130,7 +130,7 @@ pub fn simplify_type<I: Interner>(
ty::RawPtr(_, mutbl) => Some(SimplifiedType::Ptr(mutbl)),
ty::Dynamic(trait_info, ..) => match trait_info.principal_def_id() {
Some(principal_def_id) if !cx.trait_is_auto(principal_def_id) => {
Some(SimplifiedType::Trait(principal_def_id))
Some(SimplifiedType::Trait(principal_def_id.into()))
}
_ => Some(SimplifiedType::MarkerTraitObject),
},

View file

@ -649,11 +649,11 @@ pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
pub trait BoundExistentialPredicates<I: Interner>:
Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
{
fn principal_def_id(self) -> Option<I::DefId>;
fn principal_def_id(self) -> Option<I::TraitId>;
fn principal(self) -> Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>;
fn auto_traits(self) -> impl IntoIterator<Item = I::DefId>;
fn auto_traits(self) -> impl IntoIterator<Item = I::TraitId>;
fn projection_bounds(
self,

View file

@ -8,7 +8,7 @@ use rustc_index::bit_set::DenseBitSet;
use crate::fold::TypeFoldable;
use crate::inherent::*;
use crate::ir_print::IrPrint;
use crate::lang_items::TraitSolverLangItem;
use crate::lang_items::{SolverLangItem, SolverTraitLangItem};
use crate::relate::Relate;
use crate::solve::{CanonicalInput, ExternalConstraintsData, PredefinedOpaquesData, QueryResult};
use crate::visit::{Flags, TypeVisitable};
@ -38,6 +38,13 @@ pub trait Interner:
type DefId: DefId<Self>;
type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
/// A `DefId` of a trait.
///
/// In rustc this is just a `DefId`, but rust-analyzer uses different types for different items.
///
/// Note: The `TryFrom<DefId>` always succeeds (in rustc), so don't use it to check if some `DefId`
/// is a trait!
type TraitId: DefId<Self> + Into<Self::DefId> + TryFrom<Self::DefId, Error: std::fmt::Debug>;
type Span: Span<Self>;
type GenericArgs: GenericArgs<Self>;
@ -271,7 +278,7 @@ pub trait Interner:
fn explicit_super_predicates_of(
self,
def_id: Self::DefId,
def_id: Self::TraitId,
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
fn explicit_implied_predicates_of(
@ -302,19 +309,25 @@ pub trait Interner:
fn has_target_features(self, def_id: Self::DefId) -> bool;
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId;
fn require_lang_item(self, lang_item: SolverLangItem) -> Self::DefId;
fn is_lang_item(self, def_id: Self::DefId, lang_item: TraitSolverLangItem) -> bool;
fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> Self::TraitId;
fn is_default_trait(self, def_id: Self::DefId) -> bool;
fn is_lang_item(self, def_id: Self::DefId, lang_item: SolverLangItem) -> bool;
fn as_lang_item(self, def_id: Self::DefId) -> Option<TraitSolverLangItem>;
fn is_trait_lang_item(self, def_id: Self::TraitId, lang_item: SolverTraitLangItem) -> bool;
fn is_default_trait(self, def_id: Self::TraitId) -> bool;
fn as_lang_item(self, def_id: Self::DefId) -> Option<SolverLangItem>;
fn as_trait_lang_item(self, def_id: Self::TraitId) -> Option<SolverTraitLangItem>;
fn associated_type_def_ids(self, def_id: Self::DefId) -> impl IntoIterator<Item = Self::DefId>;
fn for_each_relevant_impl(
self,
trait_def_id: Self::DefId,
trait_def_id: Self::TraitId,
self_ty: Self::Ty,
f: impl FnMut(Self::DefId),
);
@ -329,20 +342,20 @@ pub trait Interner:
fn impl_polarity(self, impl_def_id: Self::DefId) -> ty::ImplPolarity;
fn trait_is_auto(self, trait_def_id: Self::DefId) -> bool;
fn trait_is_auto(self, trait_def_id: Self::TraitId) -> bool;
fn trait_is_coinductive(self, trait_def_id: Self::DefId) -> bool;
fn trait_is_coinductive(self, trait_def_id: Self::TraitId) -> bool;
fn trait_is_alias(self, trait_def_id: Self::DefId) -> bool;
fn trait_is_alias(self, trait_def_id: Self::TraitId) -> bool;
fn trait_is_dyn_compatible(self, trait_def_id: Self::DefId) -> bool;
fn trait_is_dyn_compatible(self, trait_def_id: Self::TraitId) -> bool;
fn trait_is_fundamental(self, def_id: Self::DefId) -> bool;
fn trait_is_fundamental(self, def_id: Self::TraitId) -> bool;
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::DefId) -> bool;
fn trait_may_be_implemented_via_object(self, trait_def_id: Self::TraitId) -> bool;
/// Returns `true` if this is an `unsafe trait`.
fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool;
fn trait_is_unsafe(self, trait_def_id: Self::TraitId) -> bool;
fn is_impl_trait_in_trait(self, def_id: Self::DefId) -> bool;

View file

@ -1,40 +1,46 @@
/// Lang items used by the new trait solver. This can be mapped to whatever internal
/// representation of `LangItem`s used in the underlying compiler implementation.
pub enum TraitSolverLangItem {
pub enum SolverLangItem {
// tidy-alphabetical-start
AsyncFnKindUpvars,
AsyncFnOnceOutput,
CallOnceFuture,
CallRefFuture,
CoroutineReturn,
CoroutineYield,
DynMetadata,
FutureOutput,
Metadata,
Option,
Poll,
// tidy-alphabetical-end
}
pub enum SolverTraitLangItem {
// tidy-alphabetical-start
AsyncFn,
AsyncFnKindHelper,
AsyncFnKindUpvars,
AsyncFnMut,
AsyncFnOnce,
AsyncFnOnceOutput,
AsyncIterator,
BikeshedGuaranteedNoDrop,
CallOnceFuture,
CallRefFuture,
Clone,
Copy,
Coroutine,
CoroutineReturn,
CoroutineYield,
Destruct,
DiscriminantKind,
Drop,
DynMetadata,
Fn,
FnMut,
FnOnce,
FnPtrTrait,
FusedIterator,
Future,
FutureOutput,
Iterator,
MetaSized,
Metadata,
Option,
PointeeSized,
PointeeTrait,
Poll,
Sized,
TransmuteTrait,
Tuple,

View file

@ -58,7 +58,7 @@ where
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
)]
pub struct TraitRef<I: Interner> {
pub def_id: I::DefId,
pub def_id: I::TraitId,
pub args: I::GenericArgs,
/// This field exists to prevent the creation of `TraitRef` without
/// calling [`TraitRef::new_from_args`].
@ -68,32 +68,32 @@ pub struct TraitRef<I: Interner> {
impl<I: Interner> Eq for TraitRef<I> {}
impl<I: Interner> TraitRef<I> {
pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
interner.debug_assert_args_compatible(trait_def_id, args);
pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
interner.debug_assert_args_compatible(trait_def_id.into(), args);
Self { def_id: trait_def_id, args, _use_trait_ref_new_instead: () }
}
pub fn new(
interner: I,
trait_def_id: I::DefId,
trait_def_id: I::TraitId,
args: impl IntoIterator<Item: Into<I::GenericArg>>,
) -> Self {
let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
Self::new_from_args(interner, trait_def_id, args)
}
pub fn from_assoc(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
let generics = interner.generics_of(trait_id);
pub fn from_assoc(interner: I, trait_id: I::TraitId, args: I::GenericArgs) -> TraitRef<I> {
let generics = interner.generics_of(trait_id.into());
TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
}
/// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
/// are the parameters defined on trait.
pub fn identity(interner: I, def_id: I::DefId) -> TraitRef<I> {
pub fn identity(interner: I, def_id: I::TraitId) -> TraitRef<I> {
TraitRef::new_from_args(
interner,
def_id,
I::GenericArgs::identity_for_item(interner, def_id),
I::GenericArgs::identity_for_item(interner, def_id.into()),
)
}
@ -116,7 +116,7 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
self.map_bound_ref(|tr| tr.self_ty())
}
pub fn def_id(&self) -> I::DefId {
pub fn def_id(&self) -> I::TraitId {
self.skip_binder().def_id
}
@ -155,7 +155,7 @@ impl<I: Interner> TraitPredicate<I> {
}
}
pub fn def_id(self) -> I::DefId {
pub fn def_id(self) -> I::TraitId {
self.trait_ref.def_id
}
@ -165,7 +165,7 @@ impl<I: Interner> TraitPredicate<I> {
}
impl<I: Interner> ty::Binder<I, TraitPredicate<I>> {
pub fn def_id(self) -> I::DefId {
pub fn def_id(self) -> I::TraitId {
// Ok to skip binder since trait `DefId` does not care about regions.
self.skip_binder().def_id()
}
@ -285,7 +285,7 @@ pub enum ExistentialPredicate<I: Interner> {
/// E.g., `Iterator::Item = T`.
Projection(ExistentialProjection<I>),
/// E.g., `Send`.
AutoTrait(I::DefId),
AutoTrait(I::TraitId),
}
impl<I: Interner> Eq for ExistentialPredicate<I> {}
@ -301,13 +301,14 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
self.rebind(p.with_self_ty(cx, self_ty)).upcast(cx)
}
ExistentialPredicate::AutoTrait(did) => {
let generics = cx.generics_of(did);
let generics = cx.generics_of(did.into());
let trait_ref = if generics.count() == 1 {
ty::TraitRef::new(cx, did, [self_ty])
} else {
// If this is an ill-formed auto trait, then synthesize
// new error args for the missing generics.
let err_args = GenericArgs::extend_with_error(cx, did, &[self_ty.into()]);
let err_args =
GenericArgs::extend_with_error(cx, did.into(), &[self_ty.into()]);
ty::TraitRef::new_from_args(cx, did, err_args)
};
self.rebind(trait_ref).upcast(cx)
@ -330,7 +331,7 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)
)]
pub struct ExistentialTraitRef<I: Interner> {
pub def_id: I::DefId,
pub def_id: I::TraitId,
pub args: I::GenericArgs,
/// This field exists to prevent the creation of `ExistentialTraitRef` without
/// calling [`ExistentialTraitRef::new_from_args`].
@ -340,14 +341,14 @@ pub struct ExistentialTraitRef<I: Interner> {
impl<I: Interner> Eq for ExistentialTraitRef<I> {}
impl<I: Interner> ExistentialTraitRef<I> {
pub fn new_from_args(interner: I, trait_def_id: I::DefId, args: I::GenericArgs) -> Self {
interner.debug_assert_existential_args_compatible(trait_def_id, args);
pub fn new_from_args(interner: I, trait_def_id: I::TraitId, args: I::GenericArgs) -> Self {
interner.debug_assert_existential_args_compatible(trait_def_id.into(), args);
Self { def_id: trait_def_id, args, _use_existential_trait_ref_new_instead: () }
}
pub fn new(
interner: I,
trait_def_id: I::DefId,
trait_def_id: I::TraitId,
args: impl IntoIterator<Item: Into<I::GenericArg>>,
) -> Self {
let args = interner.mk_args_from_iter(args.into_iter().map(Into::into));
@ -378,7 +379,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
}
impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
pub fn def_id(&self) -> I::DefId {
pub fn def_id(&self) -> I::TraitId {
self.skip_binder().def_id
}
@ -439,7 +440,7 @@ impl<I: Interner> ExistentialProjection<I> {
let def_id = interner.parent(self.def_id);
let args_count = interner.generics_of(def_id).count() - 1;
let args = interner.mk_args(&self.args.as_slice()[..args_count]);
ExistentialTraitRef { def_id, args, _use_existential_trait_ref_new_instead: () }
ExistentialTraitRef::new_from_args(interner, def_id.try_into().unwrap(), args)
}
pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
@ -675,7 +676,7 @@ impl<I: Interner> AliasTerm<I> {
)
}
pub fn trait_def_id(self, interner: I) -> I::DefId {
pub fn trait_def_id(self, interner: I) -> I::TraitId {
assert!(
matches!(
self.kind(interner),
@ -683,7 +684,7 @@ impl<I: Interner> AliasTerm<I> {
),
"expected a projection"
);
interner.parent(self.def_id)
interner.parent(self.def_id).try_into().unwrap()
}
/// Extracts the underlying trait reference and own args from this projection.
@ -787,7 +788,7 @@ impl<I: Interner> ProjectionPredicate<I> {
}
}
pub fn trait_def_id(self, interner: I) -> I::DefId {
pub fn trait_def_id(self, interner: I) -> I::TraitId {
self.projection_term.trait_def_id(interner)
}
@ -799,7 +800,7 @@ impl<I: Interner> ProjectionPredicate<I> {
impl<I: Interner> ty::Binder<I, ProjectionPredicate<I>> {
/// Returns the `DefId` of the trait of the associated item being projected.
#[inline]
pub fn trait_def_id(&self, cx: I) -> I::DefId {
pub fn trait_def_id(&self, cx: I) -> I::TraitId {
self.skip_binder().projection_term.trait_def_id(cx)
}
@ -847,7 +848,7 @@ impl<I: Interner> NormalizesTo<I> {
Self { alias: self.alias.with_replaced_self_ty(interner, self_ty), ..self }
}
pub fn trait_def_id(self, interner: I) -> I::DefId {
pub fn trait_def_id(self, interner: I) -> I::TraitId {
self.alias.trait_def_id(interner)
}
@ -884,13 +885,13 @@ impl<I: Interner> HostEffectPredicate<I> {
Self { trait_ref: self.trait_ref.with_replaced_self_ty(interner, self_ty), ..self }
}
pub fn def_id(self) -> I::DefId {
pub fn def_id(self) -> I::TraitId {
self.trait_ref.def_id
}
}
impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
pub fn def_id(self) -> I::DefId {
pub fn def_id(self) -> I::TraitId {
// Ok to skip binder since trait `DefId` does not care about regions.
self.skip_binder().def_id()
}

View file

@ -68,7 +68,7 @@ pub enum PredicateKind<I: Interner> {
Clause(ClauseKind<I>),
/// Trait must be dyn-compatible.
DynCompatible(I::DefId),
DynCompatible(I::TraitId),
/// `T1 <: T2`
///

View file

@ -7,7 +7,7 @@ use derive_where::derive_where;
use rustc_macros::{Decodable_NoContext, Encodable_NoContext, HashStable_NoContext};
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
use crate::lang_items::TraitSolverLangItem;
use crate::lang_items::SolverTraitLangItem;
use crate::search_graph::PathKind;
use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
@ -386,10 +386,10 @@ pub enum SizedTraitKind {
impl SizedTraitKind {
/// Returns `DefId` of corresponding language item.
pub fn require_lang_item<I: Interner>(self, cx: I) -> I::DefId {
cx.require_lang_item(match self {
SizedTraitKind::Sized => TraitSolverLangItem::Sized,
SizedTraitKind::MetaSized => TraitSolverLangItem::MetaSized,
pub fn require_lang_item<I: Interner>(self, cx: I) -> I::TraitId {
cx.require_trait_lang_item(match self {
SizedTraitKind::Sized => SolverTraitLangItem::Sized,
SizedTraitKind::MetaSized => SolverTraitLangItem::MetaSized,
})
}
}

View file

@ -8,7 +8,7 @@ extern crate rustc_type_ir;
use rustc_type_ir::Interner;
fn foo<I: Interner>(cx: I, did: I::DefId) {
fn foo<I: Interner>(cx: I, did: I::TraitId) {
let _ = cx.trait_is_unsafe(did);
//~^ ERROR do not use `rustc_type_ir::Interner` or `rustc_type_ir::InferCtxtLike` unless you're inside of the trait solver
}