Use is_lang_item more aggressively

This commit is contained in:
Michael Goulet 2024-06-14 14:46:32 -04:00
parent d5c48ebc71
commit 93ff86ed7c
44 changed files with 171 additions and 166 deletions

View File

@ -284,7 +284,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&& let CallKind::FnCall { fn_trait_id, self_ty } = kind
&& let ty::Param(_) = self_ty.kind()
&& ty == self_ty
&& Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait()
&& self.infcx.tcx.is_lang_item(fn_trait_id, LangItem::FnOnce)
{
// this is a type parameter `T: FnOnce()`, don't suggest `T: FnOnce() + Clone`.
true
@ -708,9 +708,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder()
&& pred.self_ty() == ty
{
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
if tcx.is_lang_item(pred.def_id(), LangItem::Fn) {
return Some(hir::Mutability::Not);
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
} else if tcx.is_lang_item(pred.def_id(), LangItem::FnMut) {
return Some(hir::Mutability::Mut);
}
}
@ -1832,7 +1832,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if let hir::ExprKind::MethodCall(..) = ex.kind
&& let Some(method_def_id) =
self.typeck_results.type_dependent_def_id(ex.hir_id)
&& self.tcx.lang_items().clone_trait() == Some(self.tcx.parent(method_def_id))
&& self.tcx.is_lang_item(self.tcx.parent(method_def_id), LangItem::Clone)
{
self.clones.push(ex);
}
@ -3159,8 +3159,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let is_format_arguments_item = if let Some(expr_ty) = expr_ty
&& let ty::Adt(adt, _) = expr_ty.kind()
{
self.infcx.tcx.lang_items().get(LangItem::FormatArguments)
== Some(adt.did())
self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments)
} else {
false
};

View File

@ -6,9 +6,9 @@ use crate::session_diagnostics::{
};
use rustc_errors::{Applicability, Diag};
use rustc_errors::{DiagCtxt, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::CoroutineKind;
use rustc_hir::{self as hir, LangItem};
use rustc_index::IndexSlice;
use rustc_infer::infer::BoundRegionConversionTime;
use rustc_infer::traits::SelectionError;
@ -116,7 +116,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{
if let ty::FnDef(id, _) = *const_.ty().kind() {
debug!("add_moved_or_invoked_closure_note: id={:?}", id);
if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() {
if self.infcx.tcx.is_lang_item(self.infcx.tcx.parent(id), LangItem::FnOnce) {
let closure = match args.first() {
Some(Spanned {
node: Operand::Copy(place) | Operand::Move(place), ..
@ -767,13 +767,12 @@ impl<'tcx> BorrowedContentSource<'tcx> {
ty::FnDef(def_id, args) => {
let trait_id = tcx.trait_of_item(def_id)?;
let lang_items = tcx.lang_items();
if Some(trait_id) == lang_items.deref_trait()
|| Some(trait_id) == lang_items.deref_mut_trait()
if tcx.is_lang_item(trait_id, LangItem::Deref)
|| tcx.is_lang_item(trait_id, LangItem::DerefMut)
{
Some(BorrowedContentSource::OverloadedDeref(args.type_at(0)))
} else if Some(trait_id) == lang_items.index_trait()
|| Some(trait_id) == lang_items.index_mut_trait()
} else if tcx.is_lang_item(trait_id, LangItem::Index)
|| tcx.is_lang_item(trait_id, LangItem::IndexMut)
{
Some(BorrowedContentSource::OverloadedIndex(args.type_at(0)))
} else {
@ -1041,7 +1040,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.unwrap_or_else(|| "value".to_owned());
match kind {
CallKind::FnCall { fn_trait_id, self_ty }
if Some(fn_trait_id) == self.infcx.tcx.lang_items().fn_once_trait() =>
if self.infcx.tcx.is_lang_item(fn_trait_id, LangItem::FnOnce) =>
{
err.subdiagnostic(
self.dcx(),
@ -1268,7 +1267,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let ty = moved_place.ty(self.body, tcx).ty;
if let ty::Adt(def, args) = ty.peel_refs().kind()
&& Some(def.did()) == tcx.lang_items().pin_type()
&& tcx.is_lang_item(def.did(), LangItem::Pin)
&& let ty::Ref(_, _, hir::Mutability::Mut) = args.type_at(0).kind()
&& let self_ty = self.infcx.instantiate_binder_with_fresh_vars(
fn_call_span,

View File

@ -4,6 +4,7 @@ use std::fmt::Write;
use cranelift_codegen::isa::CallConv;
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::LangItem;
use rustc_span::sym;
use rustc_target::asm::*;
use target_lexicon::BinaryFormat;
@ -927,7 +928,7 @@ fn call_inline_asm<'tcx>(
fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option<types::Type> {
match ty.kind() {
// Adapted from https://github.com/rust-lang/rust/blob/f3c66088610c1b80110297c2d9a8b5f9265b013f/compiler/rustc_hir_analysis/src/check/intrinsicck.rs#L136-L151
ty::Adt(adt, args) if Some(adt.did()) == fx.tcx.lang_items().maybe_uninit() => {
ty::Adt(adt, args) if fx.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
let fields = &adt.non_enum_variant().fields;
let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args);
let ty::Adt(ty, args) = ty.kind() else {

View File

@ -1,8 +1,8 @@
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem};
use rustc_index::bit_set::BitSet;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::ObligationCause;
@ -801,7 +801,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
// const-eval.
// const-eval of the `begin_panic` fn assumes the argument is `&str`
if Some(callee) == tcx.lang_items().begin_panic_fn() {
if tcx.is_lang_item(callee, LangItem::BeginPanic) {
match args[0].node.ty(&self.ccx.body.local_decls, tcx).kind() {
ty::Ref(_, ty, _) if ty.is_str() => return,
_ => self.check_op(ops::PanicNonStr),
@ -819,7 +819,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
}
if Some(callee) == tcx.lang_items().exchange_malloc_fn() {
if tcx.is_lang_item(callee, LangItem::ExchangeMalloc) {
self.check_op(ops::HeapAllocation);
return;
}

View File

@ -218,7 +218,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
} else {
let mut sugg = None;
if Some(trait_id) == ccx.tcx.lang_items().eq_trait() {
if ccx.tcx.is_lang_item(trait_id, LangItem::PartialEq) {
match (args[0].unpack(), args[1].unpack()) {
(GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty))
if self_ty == rhs_ty

View File

@ -230,7 +230,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
let def_id = instance.def_id();
if self.tcx.has_attr(def_id, sym::rustc_const_panic_str)
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
|| self.tcx.is_lang_item(def_id, LangItem::BeginPanic)
{
let args = self.copy_fn_args(args);
// &str or &&str
@ -245,7 +245,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
let span = self.find_closest_untracked_caller_location();
let (file, line, col) = self.location_triple_for_span(span);
return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
} else if Some(def_id) == self.tcx.lang_items().panic_fmt() {
} else if self.tcx.is_lang_item(def_id, LangItem::PanicFmt) {
// For panic_fmt, call const_panic_fmt instead.
let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None);
let new_instance = ty::Instance::expect_resolve(
@ -256,7 +256,7 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
);
return Ok(Some(new_instance));
} else if Some(def_id) == self.tcx.lang_items().align_offset_fn() {
} else if self.tcx.is_lang_item(def_id, LangItem::AlignOffset) {
let args = self.copy_fn_args(args);
// For align_offset, we replace the function call if the pointer has no address.
match self.align_offset(instance, &args, dest, ret)? {

View File

@ -53,7 +53,7 @@ impl<'tcx> Bounds<'tcx> {
span,
);
// FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands.
if tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
self.clauses.insert(0, clause);
} else {
self.clauses.push(clause);

View File

@ -1,6 +1,6 @@
use rustc_ast::InlineAsmTemplatePiece;
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::{self as hir, LangItem};
use rustc_middle::bug;
use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy};
use rustc_session::lint;
@ -134,7 +134,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
// `!` is allowed for input but not for output (issue #87802)
ty::Never if is_input => return None,
_ if ty.references_error() => return None,
ty::Adt(adt, args) if Some(adt.did()) == self.tcx.lang_items().maybe_uninit() => {
ty::Adt(adt, args) if self.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => {
let fields = &adt.non_enum_variant().fields;
let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args);
// FIXME: Are we just trying to map to the `T` in `MaybeUninit<T>`?

View File

@ -8,6 +8,7 @@
use crate::errors;
use rustc_errors::{codes::*, struct_span_code_err};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::LangItem;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_session::parse::feature_err;
@ -49,7 +50,7 @@ fn enforce_trait_manually_implementable(
) -> Result<(), ErrorGuaranteed> {
let impl_header_span = tcx.def_span(impl_def_id);
if tcx.lang_items().freeze_trait() == Some(trait_def_id) {
if tcx.is_lang_item(trait_def_id, LangItem::Freeze) {
if !tcx.features().freeze_impls {
feature_err(
&tcx.sess,
@ -75,7 +76,7 @@ fn enforce_trait_manually_implementable(
// Maintain explicit error code for `Unsize`, since it has a useful
// explanation about using `CoerceUnsized` instead.
if Some(trait_def_id) == tcx.lang_items().unsize_trait() {
if tcx.is_lang_item(trait_def_id, LangItem::Unsize) {
err.code(E0328);
}

View File

@ -5,9 +5,9 @@ use super::{Expectation, FnCtxt, TupleArgumentsFlag};
use crate::errors;
use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{self, CtorKind, Namespace, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem};
use rustc_hir_analysis::autoderef::Autoderef;
use rustc_infer::traits::ObligationCauseCode;
use rustc_infer::{
@ -41,7 +41,7 @@ pub fn check_legal_trait_for_method_call(
trait_id: DefId,
body_id: DefId,
) -> Result<(), ErrorGuaranteed> {
if tcx.lang_items().drop_trait() == Some(trait_id)
if tcx.is_lang_item(trait_id, LangItem::Drop)
&& tcx.lang_items().fallback_surface_drop_fn() != Some(body_id)
{
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {

View File

@ -3150,7 +3150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error.obligation.predicate.kind().skip_binder(),
) {
(ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)), _)
if self.tcx.lang_items().index_trait() == Some(predicate.trait_ref.def_id) =>
if self.tcx.is_lang_item(predicate.trait_ref.def_id, LangItem::Index) =>
{
seen_preds.insert(error.obligation.predicate.kind().skip_binder());
}

View File

@ -489,7 +489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
return true;
} else if let ty::Adt(adt, _) = found_ty_inner.peel_refs().kind()
&& Some(adt.did()) == self.tcx.lang_items().string()
&& self.tcx.is_lang_item(adt.did(), LangItem::String)
&& peeled.is_str()
// `Result::map`, conversely, does not take ref of the error type.
&& error_tys.is_none_or(|(found, expected)| {
@ -3147,7 +3147,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return;
}
if let ty::Adt(adt, _) = expected_ty.kind()
&& self.tcx.lang_items().range_struct() == Some(adt.did())
&& self.tcx.is_lang_item(adt.did(), LangItem::Range)
{
return;
}

View File

@ -1102,7 +1102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unsatisfied_predicates.iter().any(|(pred, _, _)| {
match pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
Some(pred.def_id()) == self.tcx.lang_items().sized_trait()
self.tcx.is_lang_item(pred.def_id(), LangItem::Sized)
&& pred.polarity == ty::PredicatePolarity::Positive
}
_ => false,
@ -1375,10 +1375,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty.is_str()
|| matches!(
ty.kind(),
ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string()
ty::Adt(adt, _) if self.tcx.is_lang_item(adt.did(), LangItem::String)
)
}
ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(),
ty::Adt(adt, _) => self.tcx.is_lang_item(adt.did(), LangItem::String),
_ => false,
};
if is_string_or_ref_str && item_name.name == sym::iter {
@ -2723,7 +2723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if tcx.is_diagnostic_item(sym::LocalKey, inner_id) {
err.help("use `with` or `try_with` to access thread local storage");
} else if Some(kind.did()) == tcx.lang_items().maybe_uninit() {
} else if tcx.is_lang_item(kind.did(), LangItem::MaybeUninit) {
err.help(format!(
"if this `{name}` has been initialized, \
use one of the `assume_init` methods to access the inner value"

View File

@ -7,7 +7,7 @@ use rustc_errors::{
};
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability, Pat, PatKind};
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind};
use rustc_infer::infer;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
@ -491,7 +491,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let tcx = self.tcx;
let expected = self.resolve_vars_if_possible(expected);
pat_ty = match expected.kind() {
ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected,
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => expected,
ty::Str => Ty::new_static_str(tcx),
_ => pat_ty,
};

View File

@ -3,7 +3,7 @@ use crate::{
LateContext, LateLintPass, LintContext,
};
use rustc_hir as hir;
use rustc_hir::{self as hir, LangItem};
use rustc_middle::ty;
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_session::{declare_lint, declare_lint_pass};
@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
// the trait is a `Deref` implementation
&& let Some(trait_) = &impl_.of_trait
&& let Some(did) = trait_.trait_def_id()
&& Some(did) == tcx.lang_items().deref_trait()
&& tcx.is_lang_item(did, LangItem::Deref)
// the self type is `dyn t_principal`
&& let self_ty = tcx.type_of(item.owner_id).instantiate_identity()
&& let ty::Dynamic(data, _, ty::Dyn) = self_ty.kind()

View File

@ -2,7 +2,7 @@ use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused};
use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext};
use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::bug;
use rustc_middle::lint::in_external_macro;
@ -53,8 +53,8 @@ impl<'tcx> LateLintPass<'tcx> for NonPanicFmt {
if let &ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(f).kind() {
let f_diagnostic_name = cx.tcx.get_diagnostic_name(def_id);
if Some(def_id) == cx.tcx.lang_items().begin_panic_fn()
|| Some(def_id) == cx.tcx.lang_items().panic_fn()
if cx.tcx.is_lang_item(def_id, LangItem::BeginPanic)
|| cx.tcx.is_lang_item(def_id, LangItem::Panic)
|| f_diagnostic_name == Some(sym::panic_str_2015)
{
if let Some(id) = f.span.ctxt().outer_expn_data().macro_def_id {
@ -153,7 +153,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
ty::Ref(_, r, _) if r.is_str(),
) || matches!(
ty.ty_adt_def(),
Some(ty_def) if Some(ty_def.did()) == cx.tcx.lang_items().string(),
Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String),
);
let infcx = cx.tcx.infer_ctxt().build();

View File

@ -2,7 +2,7 @@ use crate::lints::{DropGlue, DropTraitConstraintsDiag};
use crate::LateContext;
use crate::LateLintPass;
use crate::LintContext;
use rustc_hir as hir;
use rustc_hir::{self as hir, LangItem};
use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::symbol::sym;
@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
continue;
};
let def_id = trait_predicate.trait_ref.def_id;
if cx.tcx.lang_items().drop_trait() == Some(def_id) {
if cx.tcx.is_lang_item(def_id, LangItem::Drop) {
// Explicitly allow `impl Drop`, a drop-guards-as-unnameable-type pattern.
if trait_predicate.trait_ref.self_ty().is_impl_trait() {
continue;

View File

@ -10,9 +10,9 @@ use rustc_ast as ast;
use rustc_ast::util::{classify, parser};
use rustc_ast::{ExprKind, StmtKind};
use rustc_errors::{pluralize, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem};
use rustc_infer::traits::util::elaborate;
use rustc_middle::ty::adjustment;
use rustc_middle::ty::{self, Ty};
@ -289,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
is_ty_must_use(cx, boxed_ty, expr, span)
.map(|inner| MustUsePath::Boxed(Box::new(inner)))
}
ty::Adt(def, args) if cx.tcx.lang_items().pin_type() == Some(def.did()) => {
ty::Adt(def, args) if cx.tcx.is_lang_item(def.did(), LangItem::Pin) => {
let pinned_ty = args.type_at(0);
is_ty_must_use(cx, pinned_ty, expr, span)
.map(|inner| MustUsePath::Pinned(Box::new(inner)))

View File

@ -2020,7 +2020,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// if this is an impl of `CoerceUnsized`, create its
// "unsized info", else just store None
if Some(trait_ref.def_id) == tcx.lang_items().coerce_unsized_trait() {
if tcx.is_lang_item(trait_ref.def_id, LangItem::CoerceUnsized) {
let coerce_unsized_info = tcx.coerce_unsized_info(def_id).unwrap();
record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info);
}

View File

@ -8,9 +8,9 @@ use rustc_data_structures::intern::Interned;
use rustc_data_structures::stable_hasher::HashingControls;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem};
use rustc_index::{IndexSlice, IndexVec};
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_query_system::ich::StableHashingContext;
@ -274,16 +274,16 @@ impl AdtDefData {
if tcx.has_attr(did, sym::fundamental) {
flags |= AdtFlags::IS_FUNDAMENTAL;
}
if Some(did) == tcx.lang_items().phantom_data() {
if tcx.is_lang_item(did, LangItem::PhantomData) {
flags |= AdtFlags::IS_PHANTOM_DATA;
}
if Some(did) == tcx.lang_items().owned_box() {
if tcx.is_lang_item(did, LangItem::OwnedBox) {
flags |= AdtFlags::IS_BOX;
}
if Some(did) == tcx.lang_items().manually_drop() {
if tcx.is_lang_item(did, LangItem::ManuallyDrop) {
flags |= AdtFlags::IS_MANUALLY_DROP;
}
if Some(did) == tcx.lang_items().unsafe_cell_type() {
if tcx.is_lang_item(did, LangItem::UnsafeCell) {
flags |= AdtFlags::IS_UNSAFE_CELL;
}
if is_anonymous {

View File

@ -699,26 +699,25 @@ impl<'tcx> Instance<'tcx> {
};
let coroutine_kind = tcx.coroutine_kind(coroutine_def_id).unwrap();
let lang_items = tcx.lang_items();
let coroutine_callable_item = if Some(trait_id) == lang_items.future_trait() {
let coroutine_callable_item = if tcx.is_lang_item(trait_id, LangItem::Future) {
assert_matches!(
coroutine_kind,
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)
);
hir::LangItem::FuturePoll
} else if Some(trait_id) == lang_items.iterator_trait() {
} else if tcx.is_lang_item(trait_id, LangItem::Iterator) {
assert_matches!(
coroutine_kind,
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)
);
hir::LangItem::IteratorNext
} else if Some(trait_id) == lang_items.async_iterator_trait() {
} else if tcx.is_lang_item(trait_id, LangItem::AsyncIterator) {
assert_matches!(
coroutine_kind,
hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)
);
hir::LangItem::AsyncIteratorPollNext
} else if Some(trait_id) == lang_items.coroutine_trait() {
} else if tcx.is_lang_item(trait_id, LangItem::Coroutine) {
assert_matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_));
hir::LangItem::CoroutineResume
} else {

View File

@ -9,6 +9,7 @@ use rustc_errors::{
};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_index::IndexVec;
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable};
use rustc_session::config::OptLevel;
@ -850,7 +851,7 @@ where
// and we rely on this layout information to trigger a panic in
// `std::mem::uninitialized::<&dyn Trait>()`, for example.
if let ty::Adt(def, args) = metadata.kind()
&& Some(def.did()) == tcx.lang_items().dyn_metadata()
&& tcx.is_lang_item(def.did(), LangItem::DynMetadata)
&& let ty::Dynamic(data, _, ty::Dyn) = args.type_at(0).kind()
{
mk_dyn_vtable(data.principal())
@ -1169,7 +1170,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
// This is not part of `codegen_fn_attrs` as it can differ between crates
// and therefore cannot be computed in core.
if tcx.sess.opts.unstable_opts.panic_in_drop == PanicStrategy::Abort {
if Some(did) == tcx.lang_items().drop_in_place_fn() {
if tcx.is_lang_item(did, LangItem::DropInPlace) {
return false;
}
}

View File

@ -999,7 +999,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
let trait_ref = bound_predicate.rebind(pred.trait_ref);
// Don't print `+ Sized`, but rather `+ ?Sized` if absent.
if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
if tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
match pred.polarity {
ty::PredicatePolarity::Positive => {
has_sized_bound = true;
@ -1254,14 +1254,14 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
}
entry.has_fn_once = true;
return;
} else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() {
} else if self.tcx().is_lang_item(trait_def_id, LangItem::FnMut) {
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();
fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
return;
} else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() {
} else if self.tcx().is_lang_item(trait_def_id, LangItem::Fn) {
let super_trait_ref = supertraits_for_pretty_printing(self.tcx(), trait_ref)
.find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
.unwrap();

View File

@ -117,19 +117,19 @@ pub fn call_kind<'tcx>(
kind.unwrap_or_else(|| {
// This isn't a 'special' use of `self`
debug!(?method_did, ?fn_call_span);
let desugaring = if Some(method_did) == tcx.lang_items().into_iter_fn()
let desugaring = if tcx.is_lang_item(method_did, LangItem::IntoIterIntoIter)
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::ForLoop)
{
Some((CallDesugaringKind::ForLoopIntoIter, method_args.type_at(0)))
} else if fn_call_span.desugaring_kind() == Some(DesugaringKind::QuestionMark) {
if Some(method_did) == tcx.lang_items().branch_fn() {
if tcx.is_lang_item(method_did, LangItem::TryTraitBranch) {
Some((CallDesugaringKind::QuestionBranch, method_args.type_at(0)))
} else if Some(method_did) == tcx.lang_items().from_residual_fn() {
} else if tcx.is_lang_item(method_did, LangItem::TryTraitFromResidual) {
Some((CallDesugaringKind::QuestionFromResidual, method_args.type_at(0)))
} else {
None
}
} else if Some(method_did) == tcx.lang_items().from_output_fn()
} else if tcx.is_lang_item(method_did, LangItem::TryTraitFromOutput)
&& fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
{
Some((CallDesugaringKind::TryBlockFromOutput, method_args.type_at(0)))

View File

@ -2,6 +2,7 @@
use crate::build::{parse_float_into_constval, Builder};
use rustc_ast as ast;
use rustc_hir::LangItem;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{Allocation, LitToConstError, LitToConstInput, Scalar};
use rustc_middle::mir::*;
@ -142,7 +143,7 @@ fn lit_to_mir_constant<'tcx>(
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx))
}
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) =>
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) =>
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
let allocation = tcx.mk_const_alloc(allocation);

View File

@ -141,7 +141,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
let success_block = target_block(TestBranch::Success);
let fail_block = target_block(TestBranch::Failure);
if let ty::Adt(def, _) = ty.kind()
&& Some(def.did()) == tcx.lang_items().string()
&& tcx.is_lang_item(def.did(), LangItem::String)
{
if !tcx.features().string_deref_patterns {
bug!(

View File

@ -1,4 +1,5 @@
use rustc_ast as ast;
use rustc_hir::LangItem;
use rustc_middle::bug;
use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput};
use rustc_middle::ty::{self, ParamEnv, ScalarInt, TyCtxt};
@ -46,7 +47,7 @@ pub(crate) fn lit_to_const<'tcx>(
(ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
ty::ValTree::from_scalar_int((*n).into())
}
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) =>
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) =>
{
let bytes = data as &[u8];
ty::ValTree::from_raw_bytes(tcx, bytes)

View File

@ -454,8 +454,7 @@ where
});
}
let skip_contents =
adt.is_union() || Some(adt.did()) == self.tcx().lang_items().manually_drop();
let skip_contents = adt.is_union() || adt.is_manually_drop();
let contents_drop = if skip_contents {
(self.succ, self.unwind)
} else {

View File

@ -4,6 +4,7 @@
//! of MIR building, and only after this pass we think of the program has having the
//! normal MIR semantics.
use rustc_hir::LangItem;
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};
@ -27,7 +28,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
// References and Boxes (`noalias` sources)
ty::Ref(..) => true,
ty::Adt(..) if ty.is_box() => true,
ty::Adt(adt, _) if Some(adt.did()) == tcx.lang_items().ptr_unique() => true,
ty::Adt(adt, _) if tcx.is_lang_item(adt.did(), LangItem::PtrUnique) => true,
// Compound types: recurse
ty::Array(ty, _) | ty::Slice(ty) => {
// This does not branch so we keep the depth the same.

View File

@ -561,7 +561,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> {
// If projection of Discriminant then compare with `Ty::discriminant_ty`
if let ty::Alias(ty::Projection, ty::AliasTy { args, def_id, .. }) = expected_ty.kind()
&& Some(*def_id) == self.tcx.lang_items().discriminant_type()
&& self.tcx.is_lang_item(*def_id, LangItem::Discriminant)
&& args.first().unwrap().as_type().unwrap().discriminant_ty(self.tcx) == operand_ty
{
return;

View File

@ -1,4 +1,5 @@
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_hir::LangItem;
use rustc_index::bit_set::{BitSet, GrowableBitSet};
use rustc_index::IndexVec;
use rustc_middle::bug;
@ -70,7 +71,7 @@ fn escaping_locals<'tcx>(
// Exclude #[repr(simd)] types so that they are not de-optimized into an array
return true;
}
if Some(def.did()) == tcx.lang_items().dyn_metadata() {
if tcx.is_lang_item(def.did(), LangItem::DynMetadata) {
// codegen wants to see the `DynMetadata<T>`,
// not the inner reference-to-opaque-type.
return true;

View File

@ -1,6 +1,7 @@
//! Validates the MIR to ensure that invariants are upheld.
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::LangItem;
use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
use rustc_infer::traits::Reveal;
@ -689,7 +690,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
ty::Adt(adt_def, args) => {
// see <https://github.com/rust-lang/rust/blob/7601adcc764d42c9f2984082b49948af652df986/compiler/rustc_middle/src/ty/layout.rs#L861-L864>
if Some(adt_def.did()) == self.tcx.lang_items().dyn_metadata() {
if self.tcx.is_lang_item(adt_def.did(), LangItem::DynMetadata) {
self.fail(
location,
format!(

View File

@ -593,7 +593,7 @@ fn check_recursion_limit<'tcx>(
let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0);
debug!(" => recursion depth={}", recursion_depth);
let adjusted_recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
let adjusted_recursion_depth = if tcx.is_lang_item(def_id, LangItem::DropInPlace) {
// HACK: drop_in_place creates tight monomorphization loops. Give
// it more margin.
recursion_depth / 4

View File

@ -104,6 +104,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE};
use rustc_hir::definitions::DefPathDataName;
use rustc_hir::LangItem;
use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
@ -813,7 +814,7 @@ fn mono_item_visibility<'tcx>(
// from the `main` symbol we'll generate later.
//
// This may be fixable with a new `InstanceDef` perhaps? Unsure!
if tcx.lang_items().start_fn() == Some(def_id) {
if tcx.is_lang_item(def_id, LangItem::Start) {
*can_be_internalized = false;
return Visibility::Hidden;
}

View File

@ -289,7 +289,7 @@ pub fn transform_instance<'tcx>(
options: TransformTyOptions,
) -> Instance<'tcx> {
if (matches!(instance.def, ty::InstanceDef::Virtual(..))
&& Some(instance.def_id()) == tcx.lang_items().drop_in_place_fn())
&& tcx.is_lang_item(instance.def_id(), LangItem::DropInPlace))
|| matches!(instance.def, ty::InstanceDef::DropGlue(..))
{
// Adjust the type ids of DropGlues

View File

@ -6,6 +6,7 @@
#![allow(rustc::usage_of_qualified_ty)]
use rustc_abi::HasDataLayout;
use rustc_hir::LangItem;
use rustc_middle::ty::layout::{
FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers,
};
@ -295,7 +296,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
let mut tables = self.0.borrow_mut();
let tcx = tables.tcx;
let def_id = def.0.internal(&mut *tables, tcx);
tables.tcx.lang_items().c_str() == Some(def_id)
tables.tcx.is_lang_item(def_id, LangItem::CStr)
}
fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {

View File

@ -794,7 +794,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
obligation.predicate.kind().skip_binder()
&& Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait()
&& self.tcx.is_lang_item(trait_pred.def_id(), LangItem::Sized)
{
// Don't suggest calling to turn an unsized type into a sized type
return false;
@ -1106,7 +1106,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.iter()
.find_map(|pred| {
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output()
&& self.tcx.is_lang_item(proj.projection_term.def_id,LangItem::FnOnceOutput)
// args tuple will always be args[1]
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
{
@ -1123,7 +1123,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ty::Dynamic(data, _, ty::Dyn) => {
data.iter().find_map(|pred| {
if let ty::ExistentialPredicate::Projection(proj) = pred.skip_binder()
&& Some(proj.def_id) == self.tcx.lang_items().fn_once_output()
&& self.tcx.is_lang_item(proj.def_id, LangItem::FnOnceOutput)
// for existential projection, args are shifted over by 1
&& let ty::Tuple(args) = proj.args.type_at(0).kind()
{
@ -1150,7 +1150,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
param_env.caller_bounds().iter().find_map(|pred| {
if let ty::ClauseKind::Projection(proj) = pred.kind().skip_binder()
&& Some(proj.projection_term.def_id) == self.tcx.lang_items().fn_once_output()
&& self.tcx.is_lang_item(proj.projection_term.def_id, LangItem::FnOnceOutput)
&& proj.projection_term.self_ty() == found
// args tuple will always be args[1]
&& let ty::Tuple(args) = proj.projection_term.args.type_at(1).kind()
@ -1822,7 +1822,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&& box_path
.res
.opt_def_id()
.is_some_and(|def_id| Some(def_id) == self.tcx.lang_items().owned_box())
.is_some_and(|def_id| self.tcx.is_lang_item(def_id, LangItem::OwnedBox))
{
// Don't box `Box::new`
vec![]
@ -2737,7 +2737,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
| ObligationCauseCode::ObjectTypeBound(..) => {}
ObligationCauseCode::RustCall => {
if let Some(pred) = predicate.as_trait_clause()
&& Some(pred.def_id()) == tcx.lang_items().sized_trait()
&& tcx.is_lang_item(pred.def_id(), LangItem::Sized)
{
err.note("argument required to be sized due to `extern \"rust-call\"` ABI");
}
@ -2790,7 +2790,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Check for foreign traits being reachable.
tcx.visible_parent_map(()).get(&def_id).is_some()
};
if Some(def_id) == tcx.lang_items().sized_trait() {
if tcx.is_lang_item(def_id, LangItem::Sized) {
// Check if this is an implicit bound, even in foreign crates.
if tcx
.generics_of(item_def_id)

View File

@ -24,10 +24,10 @@ use rustc_data_structures::unord::UnordSet;
use rustc_errors::codes::*;
use rustc_errors::{pluralize, struct_span_code_err, Applicability, MultiSpan, StringPart};
use rustc_errors::{Diag, EmissionGuarantee, ErrorGuaranteed, FatalError, StashKey};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, LangItem};
use rustc_hir::{GenericParam, Item, Node};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::{InferOk, TypeTrace};
@ -118,7 +118,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// with more relevant type information and hide redundant E0282 errors.
errors.sort_by_key(|e| match e.obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
if Some(pred.def_id()) == self.tcx.lang_items().sized_trait() =>
if self.tcx.is_lang_item(pred.def_id(), LangItem::Sized) =>
{
1
}
@ -513,7 +513,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let have_alt_message = message.is_some() || label.is_some();
let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id());
let is_unsize =
Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
self.tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Unsize);
let (message, notes, append_const_msg) = if is_try_conversion {
(
Some(format!(
@ -586,14 +586,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
}
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Tuple) {
self.add_tuple_trait_message(
obligation.cause.code().peel_derives(),
&mut err,
);
}
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().drop_trait()
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
&& predicate_is_const
{
err.note("`~const Drop` was renamed to `~const Destruct`");
@ -648,7 +648,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let ObligationCauseCode::Coercion { source, target } =
*obligation.cause.code().peel_derives()
{
if Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
if self.tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Sized) {
self.suggest_borrowing_for_object_cast(
&mut err,
root_obligation,
@ -716,7 +716,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.suggest_remove_await(&obligation, &mut err);
self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().try_trait() {
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Try) {
self.suggest_await_before_try(
&mut err,
&obligation,
@ -1020,7 +1020,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// doesn't extend the goal kind. This is worth reporting, but we can only do so
// if we actually know which closure this goal comes from, so look at the cause
// to see if we can extract that information.
if Some(trait_ref.def_id()) == self.tcx.lang_items().async_fn_kind_helper()
if self.tcx.is_lang_item(trait_ref.def_id(), LangItem::AsyncFnKindHelper)
&& let Some(found_kind) = trait_ref.skip_binder().args.type_at(0).to_opt_closure_kind()
&& let Some(expected_kind) =
trait_ref.skip_binder().args.type_at(1).to_opt_closure_kind()
@ -1744,7 +1744,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let self_ty = pred.projection_term.self_ty();
with_forced_trimmed_paths! {
if Some(pred.projection_term.def_id) == self.tcx.lang_items().fn_once_output() {
if self.tcx.is_lang_item(pred.projection_term.def_id,LangItem::FnOnceOutput) {
let fn_kind = self_ty.prefix_string(self.tcx);
let item = match self_ty.kind() {
ty::FnDef(def, _) => self.tcx.item_name(*def).to_string(),
@ -1754,7 +1754,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
"expected `{item}` to be a {fn_kind} that returns `{expected_ty}`, but it \
returns `{normalized_ty}`",
))
} else if Some(trait_def_id) == self.tcx.lang_items().future_trait() {
} else if self.tcx.is_lang_item(trait_def_id, LangItem::Future) {
Some(format!(
"expected `{self_ty}` to be a future that resolves to `{expected_ty}`, but it \
resolves to `{normalized_ty}`"
@ -1783,7 +1783,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ty::Bool => Some(0),
ty::Char => Some(1),
ty::Str => Some(2),
ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => Some(2),
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => Some(2),
ty::Int(..)
| ty::Uint(..)
| ty::Float(..)
@ -2342,7 +2342,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// avoid inundating the user with unnecessary errors, but we now
// check upstream for type errors and don't add the obligations to
// begin with in those cases.
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
if self.tcx.is_lang_item(trait_ref.def_id(), LangItem::Sized) {
match self.tainted_by_errors() {
None => {
let err = self.emit_inference_failure_err(
@ -2925,7 +2925,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let (Some(node), true) = (
self.tcx.hir().get_if_local(item_def_id),
Some(pred.def_id()) == self.tcx.lang_items().sized_trait(),
self.tcx.is_lang_item(pred.def_id(), LangItem::Sized),
) else {
return;
};

View File

@ -1015,6 +1015,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// not eligible.
let self_ty = selcx.infcx.shallow_resolve(obligation.predicate.self_ty());
let tcx = selcx.tcx();
let lang_items = selcx.tcx().lang_items();
if [
lang_items.coroutine_trait(),
@ -1031,7 +1032,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
.contains(&Some(trait_ref.def_id))
{
true
} else if lang_items.async_fn_kind_helper() == Some(trait_ref.def_id) {
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::AsyncFnKindHelper) {
// FIXME(async_closures): Validity constraints here could be cleaned up.
if obligation.predicate.args.type_at(0).is_ty_var()
|| obligation.predicate.args.type_at(4).is_ty_var()
@ -1043,7 +1044,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
obligation.predicate.args.type_at(0).to_opt_closure_kind().is_some()
&& obligation.predicate.args.type_at(1).to_opt_closure_kind().is_some()
}
} else if lang_items.discriminant_kind_trait() == Some(trait_ref.def_id) {
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::DiscriminantKind) {
match self_ty.kind() {
ty::Bool
| ty::Char
@ -1080,7 +1081,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Infer(..)
| ty::Error(_) => false,
}
} else if lang_items.async_destruct_trait() == Some(trait_ref.def_id) {
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::AsyncDestruct) {
match self_ty.kind() {
ty::Bool
| ty::Char
@ -1116,7 +1117,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
| ty::Infer(_)
| ty::Error(_) => false,
}
} else if lang_items.pointee_trait() == Some(trait_ref.def_id) {
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::PointeeTrait) {
let tail = selcx.tcx().struct_tail_with_normalize(
self_ty,
|ty| {
@ -1300,15 +1301,15 @@ fn confirm_select_candidate<'cx, 'tcx>(
match impl_source {
ImplSource::UserDefined(data) => confirm_impl_candidate(selcx, obligation, data),
ImplSource::Builtin(BuiltinImplSource::Misc, data) => {
let trait_def_id = obligation.predicate.trait_def_id(selcx.tcx());
let lang_items = selcx.tcx().lang_items();
if lang_items.coroutine_trait() == Some(trait_def_id) {
let tcx = selcx.tcx();
let trait_def_id = obligation.predicate.trait_def_id(tcx);
if tcx.is_lang_item(trait_def_id, LangItem::Coroutine) {
confirm_coroutine_candidate(selcx, obligation, data)
} else if lang_items.future_trait() == Some(trait_def_id) {
} else if tcx.is_lang_item(trait_def_id, LangItem::Future) {
confirm_future_candidate(selcx, obligation, data)
} else if lang_items.iterator_trait() == Some(trait_def_id) {
} else if tcx.is_lang_item(trait_def_id, LangItem::Iterator) {
confirm_iterator_candidate(selcx, obligation, data)
} else if lang_items.async_iterator_trait() == Some(trait_def_id) {
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncIterator) {
confirm_async_iterator_candidate(selcx, obligation, data)
} else if selcx.tcx().fn_trait_kind_from_def_id(trait_def_id).is_some() {
if obligation.predicate.self_ty().is_closure()
@ -1320,7 +1321,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
}
} else if selcx.tcx().async_fn_trait_kind_from_def_id(trait_def_id).is_some() {
confirm_async_closure_candidate(selcx, obligation, data)
} else if lang_items.async_fn_kind_helper() == Some(trait_def_id) {
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncFnKindHelper) {
confirm_async_fn_kind_helper_candidate(selcx, obligation, data)
} else {
confirm_builtin_candidate(selcx, obligation, data)
@ -1373,10 +1374,9 @@ fn confirm_coroutine_candidate<'cx, 'tcx>(
coroutine_sig,
);
let lang_items = tcx.lang_items();
let ty = if Some(obligation.predicate.def_id) == lang_items.coroutine_return() {
let ty = if tcx.is_lang_item(obligation.predicate.def_id, LangItem::CoroutineReturn) {
return_ty
} else if Some(obligation.predicate.def_id) == lang_items.coroutine_yield() {
} else if tcx.is_lang_item(obligation.predicate.def_id, LangItem::CoroutineYield) {
yield_ty
} else {
span_bug!(
@ -1539,21 +1539,20 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
) -> Progress<'tcx> {
let tcx = selcx.tcx();
let self_ty = obligation.predicate.self_ty();
let lang_items = tcx.lang_items();
let item_def_id = obligation.predicate.def_id;
let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
let args = tcx.mk_args(&[self_ty.into()]);
let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) {
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
assert_eq!(discriminant_def_id, item_def_id);
(self_ty.discriminant_ty(tcx).into(), Vec::new())
} else if lang_items.async_destruct_trait() == Some(trait_def_id) {
} else if tcx.is_lang_item(trait_def_id, LangItem::AsyncDestruct) {
let destructor_def_id = tcx.associated_item_def_ids(trait_def_id)[0];
assert_eq!(destructor_def_id, item_def_id);
(self_ty.async_destructor_ty(tcx).into(), Vec::new())
} else if lang_items.pointee_trait() == Some(trait_def_id) {
} else if tcx.is_lang_item(trait_def_id, LangItem::PointeeTrait) {
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
assert_eq!(metadata_def_id, item_def_id);

View File

@ -55,7 +55,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
}
ty::Adt(def, _) => {
if Some(def.did()) == tcx.lang_items().manually_drop() {
if def.is_manually_drop() {
// `ManuallyDrop` never has a dtor.
true
} else {

View File

@ -67,9 +67,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Other bounds. Consider both in-scope bounds from fn decl
// and applicable impls. There is a certain set of precedence rules here.
let def_id = obligation.predicate.def_id();
let lang_items = self.tcx().lang_items();
let tcx = self.tcx();
if lang_items.copy_trait() == Some(def_id) {
if tcx.is_lang_item(def_id, LangItem::Copy) {
debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
// User-defined copy impls are permitted, but only for
@ -79,16 +79,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// For other types, we'll use the builtin rules.
let copy_conditions = self.copy_clone_conditions(obligation);
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::DiscriminantKind) {
// `DiscriminantKind` is automatically implemented for every type.
candidates.vec.push(BuiltinCandidate { has_nested: false });
} else if lang_items.async_destruct_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::AsyncDestruct) {
// `AsyncDestruct` is automatically implemented for every type.
candidates.vec.push(BuiltinCandidate { has_nested: false });
} else if lang_items.pointee_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::PointeeTrait) {
// `Pointee` is automatically implemented for every type.
candidates.vec.push(BuiltinCandidate { has_nested: false });
} else if lang_items.sized_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::Sized) {
// Sized is never implementable by end-users, it is
// always automatically computed.
@ -101,22 +101,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let sized_conditions = self.sized_conditions(obligation);
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
} else if lang_items.unsize_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::Unsize) {
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
} else if lang_items.destruct_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::Destruct) {
self.assemble_const_destruct_candidates(obligation, &mut candidates);
} else if lang_items.transmute_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::TransmuteTrait) {
// User-defined transmutability impls are permitted.
self.assemble_candidates_from_impls(obligation, &mut candidates);
self.assemble_candidates_for_transmutability(obligation, &mut candidates);
} else if lang_items.tuple_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::Tuple) {
self.assemble_candidate_for_tuple(obligation, &mut candidates);
} else if lang_items.pointer_like() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::PointerLike) {
self.assemble_candidate_for_pointer_like(obligation, &mut candidates);
} else if lang_items.fn_ptr_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::FnPtrTrait) {
self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
} else {
if lang_items.clone_trait() == Some(def_id) {
if tcx.is_lang_item(def_id, LangItem::Clone) {
// Same builtin conditions as `Copy`, i.e., every type which has builtin support
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
// types have builtin support for `Clone`.
@ -124,17 +124,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates);
}
if lang_items.coroutine_trait() == Some(def_id) {
if tcx.is_lang_item(def_id, LangItem::Coroutine) {
self.assemble_coroutine_candidates(obligation, &mut candidates);
} else if lang_items.future_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::Future) {
self.assemble_future_candidates(obligation, &mut candidates);
} else if lang_items.iterator_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::Iterator) {
self.assemble_iterator_candidates(obligation, &mut candidates);
} else if lang_items.fused_iterator_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::FusedIterator) {
self.assemble_fused_iterator_candidates(obligation, &mut candidates);
} else if lang_items.async_iterator_trait() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::AsyncIterator) {
self.assemble_async_iterator_candidates(obligation, &mut candidates);
} else if lang_items.async_fn_kind_helper() == Some(def_id) {
} else if tcx.is_lang_item(def_id, LangItem::AsyncFnKindHelper) {
self.assemble_async_fn_kind_helper_candidates(obligation, &mut candidates);
}
@ -755,7 +755,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.ambiguous = true;
}
ty::Coroutine(coroutine_def_id, _)
if self.tcx().lang_items().unpin_trait() == Some(def_id) =>
if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
{
match self.tcx().coroutine_movability(coroutine_def_id) {
hir::Movability::Static => {

View File

@ -258,16 +258,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> Vec<PredicateObligation<'tcx>> {
debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
let lang_items = self.tcx().lang_items();
let tcx = self.tcx();
let obligations = if has_nested {
let trait_def = obligation.predicate.def_id();
let conditions = if Some(trait_def) == lang_items.sized_trait() {
let conditions = if tcx.is_lang_item(trait_def, LangItem::Sized) {
self.sized_conditions(obligation)
} else if Some(trait_def) == lang_items.copy_trait() {
} else if tcx.is_lang_item(trait_def, LangItem::Copy) {
self.copy_clone_conditions(obligation)
} else if Some(trait_def) == lang_items.clone_trait() {
} else if tcx.is_lang_item(trait_def, LangItem::Clone) {
self.copy_clone_conditions(obligation)
} else if Some(trait_def) == lang_items.fused_iterator_trait() {
} else if tcx.is_lang_item(trait_def, LangItem::FusedIterator) {
self.fused_iterator_conditions(obligation)
} else {
bug!("unexpected builtin trait {:?}", trait_def)
@ -1444,7 +1444,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Foreign(_) => {}
// `ManuallyDrop` is trivially drop
ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().manually_drop() => {}
ty::Adt(def, _) if def.is_manually_drop() => {}
// These types are built-in, so we can fast-track by registering
// nested predicates for their constituent type(s)

View File

@ -32,6 +32,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_infer::infer::relate::TypeRelation;
use rustc_infer::infer::BoundRegionConversionTime;
use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType;
@ -2800,8 +2801,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
let predicates = predicates.instantiate_own(tcx, args);
let mut obligations = Vec::with_capacity(predicates.len());
for (index, (predicate, span)) in predicates.into_iter().enumerate() {
let cause =
if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() {
let cause = if tcx.is_lang_item(parent_trait_pred.def_id(), LangItem::CoerceUnsized) {
cause.clone()
} else {
cause.clone().derived_cause(parent_trait_pred, |derived| {

View File

@ -1,5 +1,6 @@
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::bug;
use rustc_middle::query::Providers;
@ -34,7 +35,7 @@ fn resolve_instance<'tcx>(
let def = if tcx.intrinsic(def_id).is_some() {
debug!(" => intrinsic");
ty::InstanceDef::Intrinsic(def_id)
} else if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
} else if tcx.is_lang_item(def_id, LangItem::DropInPlace) {
let ty = args.type_at(0);
if ty.needs_drop(tcx, param_env) {
@ -57,7 +58,7 @@ fn resolve_instance<'tcx>(
debug!(" => trivial drop glue");
ty::InstanceDef::DropGlue(def_id, None)
}
} else if Some(def_id) == tcx.lang_items().async_drop_in_place_fn() {
} else if tcx.is_lang_item(def_id, LangItem::AsyncDropInPlace) {
let ty = args.type_at(0);
if ty.async_drop_glue_morphology(tcx) != AsyncDropGlueMorphology::Noop {
@ -221,8 +222,7 @@ fn resolve_associated_item<'tcx>(
)
}
traits::ImplSource::Builtin(BuiltinImplSource::Misc, _) => {
let lang_items = tcx.lang_items();
if Some(trait_ref.def_id) == lang_items.clone_trait() {
if tcx.is_lang_item(trait_ref.def_id, LangItem::Clone) {
// FIXME(eddyb) use lang items for methods instead of names.
let name = tcx.item_name(trait_item_id);
if name == sym::clone {
@ -248,8 +248,8 @@ fn resolve_associated_item<'tcx>(
let args = tcx.erase_regions(rcvr_args);
Some(ty::Instance::new(trait_item_id, args))
}
} else if Some(trait_ref.def_id) == lang_items.fn_ptr_trait() {
if lang_items.fn_ptr_addr() == Some(trait_item_id) {
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) {
if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) {
let self_ty = trait_ref.self_ty();
if !matches!(self_ty.kind(), ty::FnPtr(..)) {
return Ok(None);