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:
parent
f6d23413c3
commit
38bd8081b7
18 changed files with 234 additions and 178 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue