Skip to content

Commit 735efc0

Browse files
committed
Auto merge of rust-lang#97012 - oli-obk:🦀_intrinsics, r=davidtwco
Add a query for checking whether a function is an intrinsic. work towards rust-lang#93145 This will reduce churn when we add more ways to declare intrinsics r? `@scottmcm`
2 parents 7355d97 + 0a6b691 commit 735efc0

File tree

17 files changed

+51
-44
lines changed

17 files changed

+51
-44
lines changed

compiler/rustc_const_eval/src/const_eval/fn_queries.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use rustc_hir::def_id::{DefId, LocalDefId};
44
use rustc_middle::ty::query::Providers;
55
use rustc_middle::ty::{DefIdTree, TyCtxt};
66
use rustc_span::symbol::Symbol;
7-
use rustc_target::spec::abi::Abi;
87

98
/// Whether the `def_id` is an unstable const fn and what feature gate is necessary to enable it
109
pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Symbol> {
@@ -34,10 +33,7 @@ fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
3433
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
3534
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
3635
// foreign items cannot be evaluated at compile-time.
37-
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
38-
let is_const = if let Abi::RustIntrinsic | Abi::PlatformIntrinsic =
39-
tcx.hir().get_foreign_abi(hir_id)
40-
{
36+
let is_const = if tcx.is_intrinsic(def_id) {
4137
tcx.lookup_const_stability(def_id).is_some()
4238
} else {
4339
false

compiler/rustc_const_eval/src/interpret/terminator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
312312
};
313313

314314
match instance.def {
315-
ty::InstanceDef::Intrinsic(..) => {
316-
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
315+
ty::InstanceDef::Intrinsic(def_id) => {
316+
assert!(self.tcx.is_intrinsic(def_id));
317317
// caller_fn_abi is not relevant here, we interpret the arguments directly for each intrinsic.
318318
M::call_intrinsic(self, instance, args, ret, unwind)
319319
}

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -702,8 +702,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
702702

703703
#[instrument(level = "debug", skip(self))]
704704
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
705-
use rustc_target::spec::abi::Abi::RustIntrinsic;
706-
707705
self.super_terminator(terminator, location);
708706

709707
match &terminator.kind {
@@ -885,7 +883,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
885883
return;
886884
}
887885

888-
let is_intrinsic = tcx.fn_sig(callee).abi() == RustIntrinsic;
886+
let is_intrinsic = tcx.is_intrinsic(callee);
889887

890888
if !tcx.is_const_fn_raw(callee) {
891889
if tcx.trait_of_item(callee).is_some() {

compiler/rustc_lint/src/builtin.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,6 @@ declare_lint_pass!(MutableTransmutes => [MUTABLE_TRANSMUTES]);
12521252

12531253
impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
12541254
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
1255-
use rustc_target::spec::abi::Abi::RustIntrinsic;
12561255
if let Some((&ty::Ref(_, _, from_mt), &ty::Ref(_, _, to_mt))) =
12571256
get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind()))
12581257
{
@@ -1287,8 +1286,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
12871286
}
12881287

12891288
fn def_id_is_transmute(cx: &LateContext<'_>, def_id: DefId) -> bool {
1290-
cx.tcx.fn_sig(def_id).abi() == RustIntrinsic
1291-
&& cx.tcx.item_name(def_id) == sym::transmute
1289+
cx.tcx.is_intrinsic(def_id) && cx.tcx.item_name(def_id) == sym::transmute
12921290
}
12931291
}
12941292
}

compiler/rustc_metadata/src/rmeta/decoder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
17521752
fn get_may_have_doc_links(self, index: DefIndex) -> bool {
17531753
self.root.tables.may_have_doc_links.get(self, index).is_some()
17541754
}
1755+
1756+
fn get_is_intrinsic(self, index: DefIndex) -> bool {
1757+
self.root.tables.is_intrinsic.get(self, index).is_some()
1758+
}
17551759
}
17561760

17571761
impl CrateMetadata {

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
224224
tcx.arena.alloc_slice(&result)
225225
}
226226
defined_lib_features => { cdata.get_lib_features(tcx) }
227+
is_intrinsic => { cdata.get_is_intrinsic(def_id.index) }
227228
defined_lang_items => { cdata.get_lang_items(tcx) }
228229
diagnostic_items => { cdata.get_diagnostic_items() }
229230
missing_lang_items => { cdata.get_missing_lang_items(tcx) }

compiler/rustc_metadata/src/rmeta/encoder.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13181318
}
13191319
if impl_item.kind == ty::AssocKind::Fn {
13201320
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1321+
if tcx.is_intrinsic(def_id) {
1322+
self.tables.is_intrinsic.set(def_id.index, ());
1323+
}
13211324
}
13221325
}
13231326

@@ -1562,6 +1565,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
15621565
}
15631566
if let hir::ItemKind::Fn(..) = item.kind {
15641567
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1568+
if tcx.is_intrinsic(def_id) {
1569+
self.tables.is_intrinsic.set(def_id.index, ());
1570+
}
15651571
}
15661572
if let hir::ItemKind::Impl { .. } = item.kind {
15671573
if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
@@ -1958,6 +1964,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
19581964
self.encode_item_type(def_id);
19591965
if let hir::ForeignItemKind::Fn(..) = nitem.kind {
19601966
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1967+
if tcx.is_intrinsic(def_id) {
1968+
self.tables.is_intrinsic.set(def_id.index, ());
1969+
}
19611970
}
19621971
}
19631972
}

compiler/rustc_metadata/src/rmeta/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ define_tables! {
340340
impl_parent: Table<DefIndex, RawDefId>,
341341
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
342342
impl_constness: Table<DefIndex, hir::Constness>,
343+
is_intrinsic: Table<DefIndex, ()>,
343344
impl_defaultness: Table<DefIndex, hir::Defaultness>,
344345
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
345346
coerce_unsized_info: Table<DefIndex, Lazy!(ty::adjustment::CoerceUnsizedInfo)>,

compiler/rustc_middle/src/query/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,11 @@ rustc_queries! {
16011601
desc { "calculating the lib features defined in a crate" }
16021602
separate_provide_extern
16031603
}
1604+
/// Whether the function is an intrinsic
1605+
query is_intrinsic(def_id: DefId) -> bool {
1606+
desc { |tcx| "is_intrinsic({})", tcx.def_path_str(def_id) }
1607+
separate_provide_extern
1608+
}
16041609
/// Returns the lang items defined in another crate by loading it from metadata.
16051610
query get_lang_items(_: ()) -> LanguageItems {
16061611
storage(ArenaCacheSelector<'tcx>)

compiler/rustc_middle/src/ty/util.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_hir::def_id::DefId;
2121
use rustc_macros::HashStable;
2222
use rustc_span::{sym, DUMMY_SP};
2323
use rustc_target::abi::{Integer, Size, TargetDataLayout};
24+
use rustc_target::spec::abi::Abi;
2425
use smallvec::SmallVec;
2526
use std::{fmt, iter};
2627

@@ -1195,6 +1196,12 @@ pub fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
11951196
.any(|items| items.iter().any(|item| item.has_name(sym::hidden)))
11961197
}
11971198

1199+
/// Determines whether an item is an intrinsic by Abi.
1200+
pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
1201+
matches!(tcx.fn_sig(def_id).abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
1202+
}
1203+
11981204
pub fn provide(providers: &mut ty::query::Providers) {
1199-
*providers = ty::query::Providers { normalize_opaque_types, is_doc_hidden, ..*providers }
1205+
*providers =
1206+
ty::query::Providers { normalize_opaque_types, is_doc_hidden, is_intrinsic, ..*providers }
12001207
}

compiler/rustc_mir_dataflow/src/rustc_peek.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use rustc_span::symbol::sym;
22
use rustc_span::Span;
3-
use rustc_target::spec::abi::Abi;
43

54
use rustc_index::bit_set::BitSet;
65
use rustc_middle::mir::MirPass;
@@ -193,9 +192,8 @@ impl PeekCall {
193192
&terminator.kind
194193
{
195194
if let ty::FnDef(def_id, substs) = *func.literal.ty().kind() {
196-
let sig = tcx.fn_sig(def_id);
197195
let name = tcx.item_name(def_id);
198-
if sig.abi() != Abi::RustIntrinsic || name != sym::rustc_peek {
196+
if !tcx.is_intrinsic(def_id) || name != sym::rustc_peek {
199197
return None;
200198
}
201199

compiler/rustc_mir_transform/src/inline.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -418,8 +418,7 @@ impl<'tcx> Inliner<'tcx> {
418418
}
419419
}
420420
// Don't give intrinsics the extra penalty for calls
421-
let f = tcx.fn_sig(def_id);
422-
if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
421+
if tcx.is_intrinsic(def_id) {
423422
cost += INSTR_COST;
424423
} else {
425424
cost += CALL_PENALTY;

compiler/rustc_mir_transform/src/lower_intrinsics.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use rustc_middle::ty::subst::SubstsRef;
66
use rustc_middle::ty::{self, Ty, TyCtxt};
77
use rustc_span::symbol::{sym, Symbol};
88
use rustc_span::Span;
9-
use rustc_target::spec::abi::Abi;
109

1110
pub struct LowerIntrinsics;
1211

@@ -139,8 +138,7 @@ fn resolve_rust_intrinsic<'tcx>(
139138
func_ty: Ty<'tcx>,
140139
) -> Option<(Symbol, SubstsRef<'tcx>)> {
141140
if let ty::FnDef(def_id, substs) = *func_ty.kind() {
142-
let fn_sig = func_ty.fn_sig(tcx);
143-
if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = fn_sig.abi() {
141+
if tcx.is_intrinsic(def_id) {
144142
return Some((tcx.item_name(def_id), substs));
145143
}
146144
}

compiler/rustc_passes/src/intrinsicck.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_session::lint;
1414
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
1515
use rustc_target::abi::{Pointer, VariantIdx};
1616
use rustc_target::asm::{InlineAsmRegOrRegClass, InlineAsmType};
17-
use rustc_target::spec::abi::Abi::RustIntrinsic;
1817

1918
fn check_mod_intrinsics(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
2019
tcx.hir().deep_visit_item_likes_in_module(module_def_id, &mut ItemVisitor { tcx });
@@ -63,8 +62,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
6362

6463
impl<'tcx> ExprVisitor<'tcx> {
6564
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
66-
self.tcx.fn_sig(def_id).abi() == RustIntrinsic
67-
&& self.tcx.item_name(def_id) == sym::transmute
65+
self.tcx.is_intrinsic(def_id) && self.tcx.item_name(def_id) == sym::transmute
6866
}
6967

7068
fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) {

compiler/rustc_ty_utils/src/instance.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use rustc_middle::traits::CodegenObligationError;
55
use rustc_middle::ty::subst::SubstsRef;
66
use rustc_middle::ty::{self, Binder, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitor};
77
use rustc_span::{sym, DUMMY_SP};
8-
use rustc_target::spec::abi::Abi;
98
use rustc_trait_selection::traits;
109
use traits::{translate_substs, Reveal};
1110

@@ -155,12 +154,7 @@ fn inner_resolve_instance<'tcx>(
155154
let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty);
156155

157156
let def = match *item_type.kind() {
158-
ty::FnDef(..)
159-
if {
160-
let f = item_type.fn_sig(tcx);
161-
f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic
162-
} =>
163-
{
157+
ty::FnDef(def_id, ..) if tcx.is_intrinsic(def_id) => {
164158
debug!(" => intrinsic");
165159
ty::InstanceDef::Intrinsic(def.did)
166160
}

compiler/rustc_typeck/src/check/coercion.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -775,17 +775,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
775775
match b.kind() {
776776
ty::FnPtr(b_sig) => {
777777
let a_sig = a.fn_sig(self.tcx);
778-
// Intrinsics are not coercible to function pointers
779-
if a_sig.abi() == Abi::RustIntrinsic || a_sig.abi() == Abi::PlatformIntrinsic {
780-
return Err(TypeError::IntrinsicCast);
781-
}
778+
if let ty::FnDef(def_id, _) = *a.kind() {
779+
// Intrinsics are not coercible to function pointers
780+
if self.tcx.is_intrinsic(def_id) {
781+
return Err(TypeError::IntrinsicCast);
782+
}
782783

783-
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
784-
if let ty::FnDef(def_id, _) = *a.kind()
785-
&& b_sig.unsafety() == hir::Unsafety::Normal
786-
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
787-
{
788-
return Err(TypeError::TargetFeatureCast(def_id));
784+
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
785+
786+
if b_sig.unsafety() == hir::Unsafety::Normal
787+
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
788+
{
789+
return Err(TypeError::TargetFeatureCast(def_id));
790+
}
789791
}
790792

791793
let InferOk { value: a_sig, obligations: o1 } =

src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
1414
use rustc_semver::RustcVersion;
1515
use rustc_span::symbol::sym;
1616
use rustc_span::Span;
17-
use rustc_target::spec::abi::Abi::RustIntrinsic;
1817
use std::borrow::Cow;
1918

2019
type McfResult = Result<(), (Span, Cow<'static, str>)>;
@@ -323,7 +322,7 @@ fn check_terminator<'a, 'tcx>(
323322
// within const fns. `transmute` is allowed in all other const contexts.
324323
// This won't really scale to more intrinsics or functions. Let's allow const
325324
// transmutes in const fn before we add more hacks to this.
326-
if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic && tcx.item_name(fn_def_id) == sym::transmute {
325+
if tcx.is_intrinsic(fn_def_id) && tcx.item_name(fn_def_id) == sym::transmute {
327326
return Err((
328327
span,
329328
"can only call `transmute` from const items, not `const fn`".into(),

0 commit comments

Comments
 (0)