Skip to content

Commit 95d7abf

Browse files
committed
Add a scheme for moving away from extern "rust-intrinsic" entirely
1 parent b9d8f00 commit 95d7abf

File tree

28 files changed

+156
-35
lines changed

28 files changed

+156
-35
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1648,7 +1648,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
16481648

16491649
let func_ty = func.ty(body, self.infcx.tcx);
16501650
if let ty::FnDef(def_id, _) = *func_ty.kind() {
1651-
if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) {
1651+
if self.tcx().is_intrinsic(def_id, sym::simd_shuffle) {
16521652
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
16531653
self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span });
16541654
}

compiler/rustc_codegen_cranelift/src/abi/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
398398
Ok(()) => return,
399399
// Unimplemented intrinsics must have a fallback body. The fallback body is obtained
400400
// by converting the `InstanceDef::Intrinsic` to an `InstanceDef::Item`.
401-
Err(()) => Some(Instance::new(instance.def_id(), instance.args)),
401+
Err(()) => {
402+
let intrinsic = fx.tcx.intrinsic(instance.def_id()).unwrap();
403+
if intrinsic.must_be_overridden {
404+
span_bug!(
405+
source_info.span,
406+
"intrinsic {} must be overridden by codegen_cranelift, but isn't",
407+
intrinsic.name,
408+
);
409+
}
410+
Some(Instance::new(instance.def_id(), instance.args))
411+
}
402412
}
403413
}
404414
InstanceDef::DropGlue(_, None) => {

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_middle::ty::{self, SymbolName, TyCtxt};
1616
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
1717
use rustc_middle::util::Providers;
1818
use rustc_session::config::{CrateType, OomStrategy};
19+
use rustc_span::sym;
1920
use rustc_target::spec::{SanitizerSet, TlsModel};
2021

2122
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
@@ -81,6 +82,10 @@ fn reachable_non_generics_provider(tcx: TyCtxt<'_>, _: LocalCrate) -> DefIdMap<S
8182
return library.kind.is_statically_included().then_some(def_id);
8283
}
8384

85+
if tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden) {
86+
return None;
87+
}
88+
8489
// Only consider nodes that actually have exported symbols.
8590
match tcx.def_kind(def_id) {
8691
DefKind::Fn | DefKind::Static(_) => {}

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
1717
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
1818
use rustc_middle::ty::{self, Instance, Ty};
1919
use rustc_session::config::OptLevel;
20-
use rustc_span::{source_map::Spanned, sym, Span, Symbol};
20+
use rustc_span::{source_map::Spanned, sym, Span};
2121
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
2222
use rustc_target::abi::{self, HasDataLayout, WrappingRange};
2323
use rustc_target::spec::abi::Abi;
@@ -672,7 +672,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
672672
&mut self,
673673
helper: &TerminatorCodegenHelper<'tcx>,
674674
bx: &mut Bx,
675-
intrinsic: Option<Symbol>,
675+
intrinsic: Option<ty::IntrinsicDef>,
676676
instance: Option<Instance<'tcx>>,
677677
source_info: mir::SourceInfo,
678678
target: Option<mir::BasicBlock>,
@@ -682,7 +682,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
682682
// Emit a panic or a no-op for `assert_*` intrinsics.
683683
// These are intrinsics that compile to panics so that we can get a message
684684
// which mentions the offending type, even from a const context.
685-
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s));
685+
let panic_intrinsic = intrinsic.and_then(|i| ValidityRequirement::from_intrinsic(i.name));
686686
if let Some(requirement) = panic_intrinsic {
687687
let ty = instance.unwrap().args.type_at(0);
688688

@@ -818,7 +818,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
818818
// The arguments we'll be passing. Plus one to account for outptr, if used.
819819
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
820820

821-
if intrinsic == Some(sym::caller_location) {
821+
if matches!(intrinsic, Some(ty::IntrinsicDef { name: sym::caller_location, .. })) {
822822
return if let Some(target) = target {
823823
let location =
824824
self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
@@ -838,7 +838,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
838838
}
839839

840840
let instance = match intrinsic {
841-
None | Some(sym::drop_in_place) => instance,
841+
None | Some(ty::IntrinsicDef { name: sym::drop_in_place, .. }) => instance,
842842
Some(intrinsic) => {
843843
let mut llargs = Vec::with_capacity(1);
844844
let ret_dest = self.make_return_dest(
@@ -866,7 +866,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
866866
// third argument must be constant. This is
867867
// checked by const-qualification, which also
868868
// promotes any complex rvalues to constants.
869-
if i == 2 && intrinsic == sym::simd_shuffle {
869+
if i == 2 && intrinsic.name == sym::simd_shuffle {
870870
if let mir::Operand::Constant(constant) = &arg.node {
871871
let (llval, ty) = self.simd_shuffle_indices(bx, constant);
872872
return OperandRef {
@@ -897,7 +897,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
897897
};
898898
}
899899
// Call the fallback body instead of generating the intrinsic code
900-
Err(()) => Some(Instance::new(instance.def_id(), instance.args)),
900+
Err(()) => {
901+
if intrinsic.must_be_overridden {
902+
span_bug!(
903+
span,
904+
"intrinsic {} must be overridden by codegen backend, but isn't",
905+
intrinsic.name,
906+
);
907+
}
908+
Some(Instance::new(instance.def_id(), instance.args))
909+
}
901910
}
902911
}
903912
};

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
795795
rustc_intrinsic, Normal, template!(Word), ErrorFollowing,
796796
"the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
797797
),
798+
rustc_attr!(
799+
rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing,
800+
"the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
801+
),
798802

799803
// ==========================================================================
800804
// Internal attributes, Testing:

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,12 +473,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
473473
check_enum(tcx, def_id);
474474
}
475475
DefKind::Fn => {
476-
if let Some(name) = tcx.intrinsic(def_id) {
476+
if let Some(i) = tcx.intrinsic(def_id) {
477477
intrinsic::check_intrinsic_type(
478478
tcx,
479479
def_id,
480480
tcx.def_ident_span(def_id).unwrap(),
481-
name,
481+
i.name,
482482
Abi::Rust,
483483
)
484484
}

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
480480

481481
if let Some(def_id) = def_id
482482
&& self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
483-
&& matches!(self.tcx.intrinsic(def_id), Some(sym::const_eval_select))
483+
&& self.tcx.is_intrinsic(def_id, sym::const_eval_select)
484484
{
485485
let fn_sig = self.resolve_vars_if_possible(fn_sig);
486486
for idx in 0..=1 {

compiler/rustc_lint/src/builtin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1227,7 +1227,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
12271227
}
12281228

12291229
fn def_id_is_transmute(cx: &LateContext<'_>, def_id: DefId) -> bool {
1230-
matches!(cx.tcx.intrinsic(def_id), Some(sym::transmute))
1230+
cx.tcx.is_intrinsic(def_id, sym::transmute)
12311231
}
12321232
}
12331233
}

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1744,7 +1744,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
17441744
self.root.tables.attr_flags.get(self, index)
17451745
}
17461746

1747-
fn get_intrinsic(self, index: DefIndex) -> Option<Symbol> {
1747+
fn get_intrinsic(self, index: DefIndex) -> Option<ty::IntrinsicDef> {
17481748
self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self))
17491749
}
17501750

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ macro_rules! define_tables {
375375

376376
define_tables! {
377377
- defaulted:
378-
intrinsic: Table<DefIndex, Option<LazyValue<Symbol>>>,
378+
intrinsic: Table<DefIndex, Option<LazyValue<ty::IntrinsicDef>>>,
379379
is_macro_rules: Table<DefIndex, bool>,
380380
is_type_alias_impl_trait: Table<DefIndex, bool>,
381381
type_alias_is_lazy: Table<DefIndex, bool>,

0 commit comments

Comments
 (0)