mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Add TyCtxt::is_lang_item
This commit is contained in:
parent
f8e5660532
commit
d5c48ebc71
@ -23,6 +23,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_lang_item(self, def_id: DefId, lang_item: LangItem) -> bool {
|
||||||
|
self.lang_items().get(lang_item) == Some(def_id)
|
||||||
|
}
|
||||||
|
|
||||||
/// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits,
|
/// Given a [`DefId`] of one of the [`Fn`], [`FnMut`] or [`FnOnce`] traits,
|
||||||
/// returns a corresponding [`ty::ClosureKind`].
|
/// returns a corresponding [`ty::ClosureKind`].
|
||||||
/// For any other [`DefId`] return `None`.
|
/// For any other [`DefId`] return `None`.
|
||||||
|
@ -945,7 +945,7 @@ fn visit_instance_use<'tcx>(
|
|||||||
// be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
|
// be lowered in codegen to nothing or a call to panic_nounwind. So if we encounter any
|
||||||
// of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
|
// of those intrinsics, we need to include a mono item for panic_nounwind, else we may try to
|
||||||
// codegen a call to that function without generating code for the function itself.
|
// codegen a call to that function without generating code for the function itself.
|
||||||
let def_id = tcx.lang_items().get(LangItem::PanicNounwind).unwrap();
|
let def_id = tcx.require_lang_item(LangItem::PanicNounwind, None);
|
||||||
let panic_instance = Instance::mono(tcx, def_id);
|
let panic_instance = Instance::mono(tcx, def_id);
|
||||||
if should_codegen_locally(tcx, panic_instance) {
|
if should_codegen_locally(tcx, panic_instance) {
|
||||||
output.push(create_fn_mono_item(tcx, panic_instance, source));
|
output.push(create_fn_mono_item(tcx, panic_instance, source));
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Code shared by trait and projection goals for candidate assembly.
|
//! Code shared by trait and projection goals for candidate assembly.
|
||||||
|
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
|
use rustc_hir::LangItem;
|
||||||
use rustc_infer::infer::InferCtxt;
|
use rustc_infer::infer::InferCtxt;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
@ -481,7 +482,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
candidates: &mut Vec<Candidate<'tcx>>,
|
candidates: &mut Vec<Candidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
let tcx = self.interner();
|
let tcx = self.interner();
|
||||||
let lang_items = tcx.lang_items();
|
|
||||||
let trait_def_id = goal.predicate.trait_def_id(tcx);
|
let trait_def_id = goal.predicate.trait_def_id(tcx);
|
||||||
|
|
||||||
// N.B. When assembling built-in candidates for lang items that are also
|
// N.B. When assembling built-in candidates for lang items that are also
|
||||||
@ -497,43 +497,43 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
G::consider_auto_trait_candidate(self, goal)
|
G::consider_auto_trait_candidate(self, goal)
|
||||||
} else if tcx.trait_is_alias(trait_def_id) {
|
} else if tcx.trait_is_alias(trait_def_id) {
|
||||||
G::consider_trait_alias_candidate(self, goal)
|
G::consider_trait_alias_candidate(self, goal)
|
||||||
} else if lang_items.sized_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Sized) {
|
||||||
G::consider_builtin_sized_candidate(self, goal)
|
G::consider_builtin_sized_candidate(self, goal)
|
||||||
} else if lang_items.copy_trait() == Some(trait_def_id)
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Copy)
|
||||||
|| lang_items.clone_trait() == Some(trait_def_id)
|
|| tcx.is_lang_item(trait_def_id, LangItem::Clone)
|
||||||
{
|
{
|
||||||
G::consider_builtin_copy_clone_candidate(self, goal)
|
G::consider_builtin_copy_clone_candidate(self, goal)
|
||||||
} else if lang_items.pointer_like() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::PointerLike) {
|
||||||
G::consider_builtin_pointer_like_candidate(self, goal)
|
G::consider_builtin_pointer_like_candidate(self, goal)
|
||||||
} else if lang_items.fn_ptr_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::FnPtrTrait) {
|
||||||
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
|
G::consider_builtin_fn_ptr_trait_candidate(self, goal)
|
||||||
} else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) {
|
} else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) {
|
||||||
G::consider_builtin_fn_trait_candidates(self, goal, kind)
|
G::consider_builtin_fn_trait_candidates(self, goal, kind)
|
||||||
} else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) {
|
} else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) {
|
||||||
G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
|
G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
|
||||||
} else if lang_items.async_fn_kind_helper() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncFnKindHelper) {
|
||||||
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
|
G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
|
||||||
} else if lang_items.tuple_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Tuple) {
|
||||||
G::consider_builtin_tuple_candidate(self, goal)
|
G::consider_builtin_tuple_candidate(self, goal)
|
||||||
} else if lang_items.pointee_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) {
|
||||||
G::consider_builtin_pointee_candidate(self, goal)
|
G::consider_builtin_pointee_candidate(self, goal)
|
||||||
} else if lang_items.future_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Future) {
|
||||||
G::consider_builtin_future_candidate(self, goal)
|
G::consider_builtin_future_candidate(self, goal)
|
||||||
} else if lang_items.iterator_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Iterator) {
|
||||||
G::consider_builtin_iterator_candidate(self, goal)
|
G::consider_builtin_iterator_candidate(self, goal)
|
||||||
} else if lang_items.fused_iterator_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::FusedIterator) {
|
||||||
G::consider_builtin_fused_iterator_candidate(self, goal)
|
G::consider_builtin_fused_iterator_candidate(self, goal)
|
||||||
} else if lang_items.async_iterator_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncIterator) {
|
||||||
G::consider_builtin_async_iterator_candidate(self, goal)
|
G::consider_builtin_async_iterator_candidate(self, goal)
|
||||||
} else if lang_items.coroutine_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) {
|
||||||
G::consider_builtin_coroutine_candidate(self, goal)
|
G::consider_builtin_coroutine_candidate(self, goal)
|
||||||
} else if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) {
|
||||||
G::consider_builtin_discriminant_kind_candidate(self, goal)
|
G::consider_builtin_discriminant_kind_candidate(self, goal)
|
||||||
} else if lang_items.async_destruct_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) {
|
||||||
G::consider_builtin_async_destruct_candidate(self, goal)
|
G::consider_builtin_async_destruct_candidate(self, goal)
|
||||||
} else if lang_items.destruct_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::Destruct) {
|
||||||
G::consider_builtin_destruct_candidate(self, goal)
|
G::consider_builtin_destruct_candidate(self, goal)
|
||||||
} else if lang_items.transmute_trait() == Some(trait_def_id) {
|
} else if tcx.is_lang_item(trait_def_id, LangItem::TransmuteTrait) {
|
||||||
G::consider_builtin_transmute_candidate(self, goal)
|
G::consider_builtin_transmute_candidate(self, goal)
|
||||||
} else {
|
} else {
|
||||||
Err(NoSolution)
|
Err(NoSolution)
|
||||||
@ -543,7 +543,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
|
|
||||||
// There may be multiple unsize candidates for a trait with several supertraits:
|
// There may be multiple unsize candidates for a trait with several supertraits:
|
||||||
// `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
|
// `trait Foo: Bar<A> + Bar<B>` and `dyn Foo: Unsize<dyn Bar<_>>`
|
||||||
if lang_items.unsize_trait() == Some(trait_def_id) {
|
if tcx.is_lang_item(trait_def_id, LangItem::Unsize) {
|
||||||
candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal));
|
candidates.extend(G::consider_structural_builtin_unsize_candidates(self, goal));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,9 +392,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||||||
output_coroutine_ty,
|
output_coroutine_ty,
|
||||||
coroutine_return_ty,
|
coroutine_return_ty,
|
||||||
}| {
|
}| {
|
||||||
let lang_items = tcx.lang_items();
|
let (projection_term, term) = if tcx
|
||||||
let (projection_term, term) = if Some(goal.predicate.def_id())
|
.is_lang_item(goal.predicate.def_id(), LangItem::CallOnceFuture)
|
||||||
== lang_items.call_once_future()
|
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
ty::AliasTerm::new(
|
ty::AliasTerm::new(
|
||||||
@ -404,7 +403,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||||||
),
|
),
|
||||||
output_coroutine_ty.into(),
|
output_coroutine_ty.into(),
|
||||||
)
|
)
|
||||||
} else if Some(goal.predicate.def_id()) == lang_items.call_ref_future() {
|
} else if tcx.is_lang_item(goal.predicate.def_id(), LangItem::CallRefFuture) {
|
||||||
(
|
(
|
||||||
ty::AliasTerm::new(
|
ty::AliasTerm::new(
|
||||||
tcx,
|
tcx,
|
||||||
@ -417,7 +416,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||||||
),
|
),
|
||||||
output_coroutine_ty.into(),
|
output_coroutine_ty.into(),
|
||||||
)
|
)
|
||||||
} else if Some(goal.predicate.def_id()) == lang_items.async_fn_once_output() {
|
} else if tcx.is_lang_item(goal.predicate.def_id(), LangItem::AsyncFnOnceOutput)
|
||||||
|
{
|
||||||
(
|
(
|
||||||
ty::AliasTerm::new(
|
ty::AliasTerm::new(
|
||||||
tcx,
|
tcx,
|
||||||
@ -719,10 +719,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||||||
|
|
||||||
let coroutine = args.as_coroutine();
|
let coroutine = args.as_coroutine();
|
||||||
|
|
||||||
let lang_items = tcx.lang_items();
|
let term = if tcx.is_lang_item(goal.predicate.def_id(), LangItem::CoroutineReturn) {
|
||||||
let term = if Some(goal.predicate.def_id()) == lang_items.coroutine_return() {
|
|
||||||
coroutine.return_ty().into()
|
coroutine.return_ty().into()
|
||||||
} else if Some(goal.predicate.def_id()) == lang_items.coroutine_yield() {
|
} else if tcx.is_lang_item(goal.predicate.def_id(), LangItem::CoroutineYield) {
|
||||||
coroutine.yield_ty().into()
|
coroutine.yield_ty().into()
|
||||||
} else {
|
} else {
|
||||||
bug!(
|
bug!(
|
||||||
|
@ -802,14 +802,13 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// The type must be `Sized` to be unsized.
|
// The type must be `Sized` to be unsized.
|
||||||
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
|
ecx.add_goal(
|
||||||
ecx.add_goal(
|
GoalSource::ImplWhereBound,
|
||||||
GoalSource::ImplWhereBound,
|
goal.with(
|
||||||
goal.with(tcx, ty::TraitRef::new(tcx, sized_def_id, [a_ty])),
|
tcx,
|
||||||
);
|
ty::TraitRef::new(tcx, tcx.require_lang_item(LangItem::Sized, None), [a_ty]),
|
||||||
} else {
|
),
|
||||||
return Err(NoSolution);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// The type must outlive the lifetime of the `dyn` we're unsizing into.
|
// The type must outlive the lifetime of the `dyn` we're unsizing into.
|
||||||
ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
|
ecx.add_goal(GoalSource::Misc, goal.with(tcx, ty::OutlivesPredicate(a_ty, b_region)));
|
||||||
@ -991,7 +990,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
tcx,
|
tcx,
|
||||||
ty::TraitRef::new(
|
ty::TraitRef::new(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.lang_items().unsize_trait().unwrap(),
|
tcx.require_lang_item(LangItem::Unsize, None),
|
||||||
[a_tail_ty, b_tail_ty],
|
[a_tail_ty, b_tail_ty],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1034,7 +1033,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
tcx,
|
tcx,
|
||||||
ty::TraitRef::new(
|
ty::TraitRef::new(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.lang_items().unsize_trait().unwrap(),
|
tcx.require_lang_item(LangItem::Unsize, None),
|
||||||
[a_last_ty, b_last_ty],
|
[a_last_ty, b_last_ty],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1076,7 +1075,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
|||||||
// takes precedence over the structural auto trait candidate being
|
// takes precedence over the structural auto trait candidate being
|
||||||
// assembled.
|
// assembled.
|
||||||
ty::Coroutine(def_id, _)
|
ty::Coroutine(def_id, _)
|
||||||
if Some(goal.predicate.def_id()) == self.interner().lang_items().unpin_trait() =>
|
if self.interner().is_lang_item(goal.predicate.def_id(), LangItem::Unpin) =>
|
||||||
{
|
{
|
||||||
match self.interner().coroutine_movability(def_id) {
|
match self.interner().coroutine_movability(def_id) {
|
||||||
Movability::Static => Some(Err(NoSolution)),
|
Movability::Static => Some(Err(NoSolution)),
|
||||||
|
@ -338,7 +338,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||||||
let make_freeze_obl = |ty| {
|
let make_freeze_obl = |ty| {
|
||||||
let trait_ref = ty::TraitRef::new(
|
let trait_ref = ty::TraitRef::new(
|
||||||
tcx,
|
tcx,
|
||||||
tcx.lang_items().freeze_trait().unwrap(),
|
tcx.require_lang_item(LangItem::Freeze, None),
|
||||||
[ty::GenericArg::from(ty)],
|
[ty::GenericArg::from(ty)],
|
||||||
);
|
);
|
||||||
Obligation::with_depth(
|
Obligation::with_depth(
|
||||||
|
Loading…
Reference in New Issue
Block a user