about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-05 00:13:01 +0000
committerbors <bors@rust-lang.org>2024-03-05 00:13:01 +0000
commit2eeff462b762ed00f9d557d8c6ad7a3d562f692a (patch)
treed5e2442dec8294e89a12d0680109e0ef3fd8d7cf /compiler/rustc_mir_transform/src
parent50e77f133f8eb1f745e05681163a0143d6c4dd7d (diff)
parentc04f0caaff5b09a2202bb220579ef45722e74ed2 (diff)
downloadrust-2eeff462b762ed00f9d557d8c6ad7a3d562f692a.tar.gz
rust-2eeff462b762ed00f9d557d8c6ad7a3d562f692a.zip
Auto merge of #120675 - oli-obk:intrinsics3.0, r=pnkfelix
Add a scheme for moving away from `extern "rust-intrinsic"` entirely

All `rust-intrinsic`s can become free functions now, either with a fallback body, or with a dummy body and an attribute, requiring backends to actually implement the intrinsic.

This PR demonstrates the dummy-body scheme with the `vtable_size` intrinsic.

cc https://github.com/rust-lang/rust/issues/63585

follow-up to #120500

MCP at https://github.com/rust-lang/compiler-team/issues/720
Diffstat (limited to 'compiler/rustc_mir_transform/src')
-rw-r--r--compiler/rustc_mir_transform/src/cross_crate_inline.rs4
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs4
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs8
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs10
4 files changed, 18 insertions, 8 deletions
diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
index 483fd753e70..07e6ecccaa4 100644
--- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs
+++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
@@ -23,6 +23,10 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
         return false;
     }
 
+    if tcx.intrinsic(def_id).is_some_and(|i| i.must_be_overridden) {
+        return false;
+    }
+
     // This just reproduces the logic from Instance::requires_inline.
     match tcx.def_kind(def_id) {
         DefKind::Ctor(..) | DefKind::Closure => return true,
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index 73102a5f026..6b33d81c1c4 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -323,8 +323,8 @@ fn resolve_rust_intrinsic<'tcx>(
     func_ty: Ty<'tcx>,
 ) -> Option<(Symbol, GenericArgsRef<'tcx>)> {
     if let ty::FnDef(def_id, args) = *func_ty.kind() {
-        let name = tcx.intrinsic(def_id)?;
-        return Some((name, args));
+        let intrinsic = tcx.intrinsic(def_id)?;
+        return Some((intrinsic.name, args));
     }
     None
 }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 945c3c662a6..cd9b98e4f32 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -160,7 +160,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
                 fn_span,
                 ..
             } if let ty::FnDef(def_id, _) = *const_.ty().kind()
-                && matches!(tcx.intrinsic(def_id), Some(sym::const_eval_select)) =>
+                && tcx.is_intrinsic(def_id, sym::const_eval_select) =>
             {
                 let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
                     std::mem::take(args).try_into().unwrap();
@@ -632,6 +632,12 @@ fn optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> &Body<'_> {
 }
 
 fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
+    if tcx.intrinsic(did).is_some_and(|i| i.must_be_overridden) {
+        span_bug!(
+            tcx.def_span(did),
+            "this intrinsic must be overridden by the codegen backend, it has no meaningful body",
+        )
+    }
     if tcx.is_constructor(did.to_def_id()) {
         // There's no reason to run all of the MIR passes on constructors when
         // we can just output the MIR we want directly. This also saves const
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index a0af902c4e1..f317c025e96 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -14,9 +14,9 @@ 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()
-                && let Some(intrinsic_name) = tcx.intrinsic(def_id)
+                && let Some(intrinsic) = tcx.intrinsic(def_id)
             {
-                match intrinsic_name {
+                match intrinsic.name {
                     sym::unreachable => {
                         terminator.kind = TerminatorKind::Unreachable;
                     }
@@ -105,7 +105,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                             lhs = args.next().unwrap();
                             rhs = args.next().unwrap();
                         }
-                        let bin_op = match intrinsic_name {
+                        let bin_op = match intrinsic.name {
                             sym::wrapping_add => BinOp::Add,
                             sym::wrapping_sub => BinOp::Sub,
                             sym::wrapping_mul => BinOp::Mul,
@@ -136,7 +136,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                                 lhs = args.next().unwrap();
                                 rhs = args.next().unwrap();
                             }
-                            let bin_op = match intrinsic_name {
+                            let bin_op = match intrinsic.name {
                                 sym::add_with_overflow => BinOp::Add,
                                 sym::sub_with_overflow => BinOp::Sub,
                                 sym::mul_with_overflow => BinOp::Mul,
@@ -155,7 +155,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     sym::size_of | sym::min_align_of => {
                         if let Some(target) = *target {
                             let tp_ty = generic_args.type_at(0);
-                            let null_op = match intrinsic_name {
+                            let null_op = match intrinsic.name {
                                 sym::size_of => NullOp::SizeOf,
                                 sym::min_align_of => NullOp::AlignOf,
                                 _ => bug!("unexpected intrinsic"),