diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cfb46f3ac8a..08b6aead728 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -1650,16 +1650,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let func_ty = func.ty(body, self.infcx.tcx); if let ty::FnDef(def_id, _) = *func_ty.kind() { - if self.tcx().is_intrinsic(def_id) { - match self.tcx().item_name(def_id) { - sym::simd_shuffle => { - if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) { - self.tcx() - .dcx() - .emit_err(SimdShuffleLastConst { span: term.source_info.span }); - } - } - _ => {} + if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) { + if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) { + self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span }); } } } diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index dbc29e607ef..ddad6683afb 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -49,7 +49,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness { hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. - let is_const = if tcx.is_intrinsic(def_id) { + let is_const = if tcx.intrinsic(def_id).is_some() { tcx.lookup_const_stability(def_id).is_some() } else { false diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index ff20fc5092c..0a130d4bc49 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -526,7 +526,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(def_id) => { - assert!(self.tcx.is_intrinsic(def_id)); + assert!(self.tcx.intrinsic(def_id).is_some()); // FIXME: Should `InPlace` arguments be reset to uninit? M::call_intrinsic( self, diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 28dc69859fd..1ee7c905d91 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -859,7 +859,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // We do not use `const` modifiers for intrinsic "functions", as intrinsics are // `extern` functions, and these have no way to get marked `const`. So instead we // use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const` - if self.ccx.is_const_stable_const_fn() || tcx.is_intrinsic(callee) { + if self.ccx.is_const_stable_const_fn() || tcx.intrinsic(callee).is_some() { self.check_op(ops::FnCallUnstable(callee, None)); return; } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index c4271c66e1c..27614634c6b 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -540,8 +540,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(def_id) = def_id && self.tcx.def_kind(def_id) == hir::def::DefKind::Fn - && self.tcx.is_intrinsic(def_id) - && self.tcx.item_name(def_id) == sym::const_eval_select + && matches!(self.tcx.intrinsic(def_id), Some(sym::const_eval_select)) { let fn_sig = self.resolve_vars_if_possible(fn_sig); for idx in 0..=1 { diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 549ad44d7e3..355fc61e795 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -864,7 +864,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { let a_sig = a.fn_sig(self.tcx); if let ty::FnDef(def_id, _) = *a.kind() { // Intrinsics are not coercible to function pointers - if self.tcx.is_intrinsic(def_id) { + if self.tcx.intrinsic(def_id).is_some() { return Err(TypeError::IntrinsicCast); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 248e1c0fcc8..81c531fad55 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -313,7 +313,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if !self.same_type_modulo_infer(*found_sig, *expected_sig) || !sig.is_suggestable(self.tcx, true) - || self.tcx.is_intrinsic(*did) + || self.tcx.intrinsic(*did).is_some() { return; } @@ -345,8 +345,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if !self.same_type_modulo_infer(*found_sig, *expected_sig) || !found_sig.is_suggestable(self.tcx, true) || !expected_sig.is_suggestable(self.tcx, true) - || self.tcx.is_intrinsic(*did1) - || self.tcx.is_intrinsic(*did2) + || self.tcx.intrinsic(*did1).is_some() + || self.tcx.intrinsic(*did2).is_some() { return; } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 6ee1d1ca924..faa35f51cd4 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1227,7 +1227,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { } fn def_id_is_transmute(cx: &LateContext<'_>, def_id: DefId) -> bool { - cx.tcx.is_intrinsic(def_id) && cx.tcx.item_name(def_id) == sym::transmute + matches!(cx.tcx.intrinsic(def_id), Some(sym::transmute)) } } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 11cb1bb6d9e..a738fc86a06 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1746,8 +1746,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { self.root.tables.attr_flags.get(self, index) } - fn get_is_intrinsic(self, index: DefIndex) -> bool { - self.root.tables.is_intrinsic.get(self, index) + fn get_intrinsic(self, index: DefIndex) -> bool { + self.root.tables.intrinsic.get(self, index) } fn get_doc_link_resolutions(self, index: DefIndex) -> DocLinkResMap { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 988388edfd5..1faddee2e98 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -348,7 +348,7 @@ provide! { tcx, def_id, other, cdata, cdata.get_stability_implications(tcx).iter().copied().collect() } stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) } - is_intrinsic => { cdata.get_is_intrinsic(def_id.index) } + intrinsic => { cdata.get_intrinsic(def_id.index).then(|| tcx.item_name(def_id)) } defined_lang_items => { cdata.get_lang_items(tcx) } diagnostic_items => { cdata.get_diagnostic_items() } missing_lang_items => { cdata.get_missing_lang_items(tcx) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 6ca1973396f..f3213185449 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1411,7 +1411,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Fn | DefKind::AssocFn = def_kind { self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id)); record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id)); - self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id)); + self.tables.intrinsic.set(def_id.index, tcx.intrinsic(def_id).is_some()); } if let DefKind::TyParam = def_kind { let default = self.tcx.object_lifetime_default(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 8205e995c19..49c97b8c2e6 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -375,7 +375,7 @@ macro_rules! define_tables { define_tables! { - defaulted: - is_intrinsic: Table, + intrinsic: Table, is_macro_rules: Table, is_type_alias_impl_trait: Table, type_alias_is_lazy: Table, diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index a272a51f327..92ce3854b92 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -240,6 +240,7 @@ trivial! { Option, Option, Option, + Option, Result<(), rustc_errors::ErrorGuaranteed>, Result<(), rustc_middle::traits::query::NoSolution>, Result, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 938fba0ed09..16d3a0bd0cf 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1753,8 +1753,8 @@ rustc_queries! { separate_provide_extern } /// Whether the function is an intrinsic - query is_intrinsic(def_id: DefId) -> bool { - desc { |tcx| "checking whether `{}` is an intrinsic", tcx.def_path_str(def_id) } + query intrinsic(def_id: DefId) -> Option { + desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) } separate_provide_extern } /// Returns the lang items defined in another crate by loading it from metadata. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4feaeb0dd05..626ea0342e5 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -18,7 +18,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_index::bit_set::GrowableBitSet; use rustc_macros::HashStable; use rustc_session::Limit; -use rustc_span::sym; +use rustc_span::{sym, Symbol}; use rustc_target::abi::{Integer, IntegerType, Primitive, Size}; use rustc_target::spec::abi::Abi; use smallvec::SmallVec; @@ -1550,8 +1550,13 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } /// Determines whether an item is an intrinsic by Abi. -pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic) +pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { + if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic) + { + Some(tcx.item_name(def_id.into())) + } else { + None + } } pub fn provide(providers: &mut Providers) { @@ -1559,7 +1564,7 @@ pub fn provide(providers: &mut Providers) { reveal_opaque_types_in_bounds, is_doc_hidden, is_doc_notable_trait, - is_intrinsic, + intrinsic, ..*providers } } diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index cbbf3548c07..1575f31e75e 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -202,8 +202,7 @@ impl PeekCall { &terminator.kind { if let ty::FnDef(def_id, fn_args) = *func.const_.ty().kind() { - let name = tcx.item_name(def_id); - if !tcx.is_intrinsic(def_id) || name != sym::rustc_peek { + if tcx.intrinsic(def_id)? != sym::rustc_peek { return None; } diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 79bed960b95..2c692c95003 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -70,7 +70,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => { let fn_ty = self.instantiate_ty(f.const_.ty()); self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() - && tcx.is_intrinsic(def_id) + && tcx.intrinsic(def_id).is_some() { // Don't give intrinsics the extra penalty for calls INSTR_COST diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index f65eb5cbea9..81cf31e6bf4 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -329,9 +329,8 @@ fn resolve_rust_intrinsic<'tcx>( func_ty: Ty<'tcx>, ) -> Option<(Symbol, GenericArgsRef<'tcx>)> { if let ty::FnDef(def_id, args) = *func_ty.kind() { - if tcx.is_intrinsic(def_id) { - return Some((tcx.item_name(def_id), args)); - } + let name = tcx.intrinsic(def_id)?; + return Some((name, args)); } None } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 72d9ffe8ca5..524d62546dd 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -161,8 +161,7 @@ fn remap_mir_for_const_eval_select<'tcx>( fn_span, .. } if let ty::FnDef(def_id, _) = *const_.ty().kind() - && tcx.item_name(def_id) == sym::const_eval_select - && tcx.is_intrinsic(def_id) => + && matches!(tcx.intrinsic(def_id), Some(sym::const_eval_select)) => { let [tupled_args, called_in_const, called_at_rt]: [_; 3] = std::mem::take(args).try_into().unwrap(); diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index f43b85173d4..a0af902c4e1 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -14,9 +14,8 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { if let TerminatorKind::Call { func, args, destination, target, .. } = &mut terminator.kind && let ty::FnDef(def_id, generic_args) = *func.ty(local_decls, tcx).kind() - && tcx.is_intrinsic(def_id) + && let Some(intrinsic_name) = tcx.intrinsic(def_id) { - let intrinsic_name = tcx.item_name(def_id); match intrinsic_name { sym::unreachable => { terminator.kind = TerminatorKind::Unreachable; diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 7fa416197b3..5fc93d666ab 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -28,7 +28,8 @@ fn resolve_instance<'tcx>( tcx.normalize_erasing_regions(param_env, args), ) } else { - let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) { + let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && 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() { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 8d5bcd665ad..47195fcc17b 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -335,7 +335,7 @@ fn check_terminator<'tcx>( // within const fns. `transmute` is allowed in all other const contexts. // This won't really scale to more intrinsics or functions. Let's allow const // transmutes in const fn before we add more hacks to this. - if tcx.is_intrinsic(fn_def_id) && tcx.item_name(fn_def_id) == sym::transmute { + if matches!(tcx.intrinsic(fn_def_id), Some(sym::transmute)) { return Err(( span, "can only call `transmute` from const items, not `const fn`".into(),