Skip to content

Remove support for extern "rust-intrinsic" blocks #139455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions compiler/rustc_abi/src/extern_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ pub enum ExternAbi {
System {
unwind: bool,
},
RustIntrinsic,
RustCall,
/// *Not* a stable ABI, just directly use the Rust types to describe the ABI for LLVM. Even
/// normally ABI-compatible Rust types can become ABI-incompatible with this ABI!
Expand Down Expand Up @@ -128,7 +127,6 @@ abi_impls! {
RiscvInterruptS =><= "riscv-interrupt-s",
RustCall =><= "rust-call",
RustCold =><= "rust-cold",
RustIntrinsic =><= "rust-intrinsic",
Stdcall { unwind: false } =><= "stdcall",
Stdcall { unwind: true } =><= "stdcall-unwind",
System { unwind: false } =><= "system",
Expand Down Expand Up @@ -199,7 +197,7 @@ impl ExternAbi {
/// - are subject to change between compiler versions
pub fn is_rustic_abi(self) -> bool {
use ExternAbi::*;
matches!(self, Rust | RustCall | RustIntrinsic | RustCold)
matches!(self, Rust | RustCall | RustCold)
}

pub fn supports_varargs(self) -> bool {
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_ast_lowering/src/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,6 @@ pub fn extern_abi_stability(abi: ExternAbi) -> Result<(), UnstableAbi> {
| ExternAbi::SysV64 { .. }
| ExternAbi::System { .. }
| ExternAbi::EfiApi => Ok(()),
// implementation details
ExternAbi::RustIntrinsic => {
Err(UnstableAbi { abi, feature: sym::intrinsics, explain: GateReason::ImplDetail })
}
ExternAbi::Unadjusted => {
Err(UnstableAbi { abi, feature: sym::abi_unadjusted, explain: GateReason::ImplDetail })
}
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Codegen of intrinsics. This includes `extern "rust-intrinsic"`,
//! functions marked with the `#[rustc_intrinsic]` attribute
//! Codegen of intrinsics. This includes functions marked with the `#[rustc_intrinsic]` attribute
//! and LLVM intrinsics that have symbol names starting with `llvm.`.

macro_rules! intrinsic_args {
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_error_codes/src/error_codes/E0622.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ Erroneous code example:
#![feature(intrinsics)]
#![allow(internal_features)]

extern "rust-intrinsic" {
pub static atomic_singlethreadfence_seqcst: fn();
extern "C" {
#[rustc_intrinsic]
pub static atomic_singlethreadfence_seqcst: unsafe fn();
// error: intrinsic must be a function
}

Expand All @@ -22,9 +23,8 @@ error, just declare a function. Example:
#![feature(intrinsics)]
#![allow(internal_features)]

extern "rust-intrinsic" {
pub fn atomic_singlethreadfence_seqcst(); // ok!
}
#[rustc_intrinsic]
pub unsafe fn atomic_singlethreadfence_seqcst(); // ok!

fn main() { unsafe { atomic_singlethreadfence_seqcst(); } }
```
2 changes: 1 addition & 1 deletion compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ declare_features! (
(internal, custom_mir, "1.65.0", None),
/// Outputs useful `assert!` messages
(unstable, generic_assert, "1.63.0", None),
/// Allows using the `rust-intrinsic`'s "ABI".
/// Allows using the #[rustc_intrinsic] attribute.
(internal, intrinsics, "1.0.0", None),
/// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
(internal, lang_items, "1.0.0", None),
Expand Down
108 changes: 49 additions & 59 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,10 +741,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {

for &assoc_item in assoc_items.in_definition_order() {
match assoc_item.kind {
ty::AssocKind::Fn => {
let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
}
ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
let trait_args = GenericArgs::identity_for_item(tcx, def_id);
let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
Expand Down Expand Up @@ -788,65 +784,59 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
};
check_abi(tcx, it.span, abi);

match abi {
ExternAbi::RustIntrinsic => {
for item in items {
intrinsic::check_intrinsic_type(
tcx,
item.id.owner_id.def_id,
item.span,
item.ident.name,
abi,
);
}
for item in items {
let def_id = item.id.owner_id.def_id;

if tcx.has_attr(def_id, sym::rustc_intrinsic) {
intrinsic::check_intrinsic_type(
tcx,
item.id.owner_id.def_id,
item.span,
item.ident.name,
abi,
);
}

_ => {
for item in items {
let def_id = item.id.owner_id.def_id;
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
if generics.own_params.len() - own_counts.lifetimes != 0 {
let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts)
{
(_, 0) => ("type", "types", Some("u32")),
// We don't specify an example value, because we can't generate
// a valid value for any type.
(0, _) => ("const", "consts", None),
_ => ("type or const", "types or consts", None),
};
struct_span_code_err!(
tcx.dcx(),
item.span,
E0044,
"foreign items may not have {kinds} parameters",
)
.with_span_label(item.span, format!("can't have {kinds} parameters"))
.with_help(
// FIXME: once we start storing spans for type arguments, turn this
// into a suggestion.
format!(
"replace the {} parameters with concrete {}{}",
kinds,
kinds_pl,
egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
),
)
.emit();
}
let generics = tcx.generics_of(def_id);
let own_counts = generics.own_counts();
if generics.own_params.len() - own_counts.lifetimes != 0 {
let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
(_, 0) => ("type", "types", Some("u32")),
// We don't specify an example value, because we can't generate
// a valid value for any type.
(0, _) => ("const", "consts", None),
_ => ("type or const", "types or consts", None),
};
struct_span_code_err!(
tcx.dcx(),
item.span,
E0044,
"foreign items may not have {kinds} parameters",
)
.with_span_label(item.span, format!("can't have {kinds} parameters"))
.with_help(
// FIXME: once we start storing spans for type arguments, turn this
// into a suggestion.
format!(
"replace the {} parameters with concrete {}{}",
kinds,
kinds_pl,
egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
),
)
.emit();
}

let item = tcx.hir_foreign_item(item.id);
match &item.kind {
hir::ForeignItemKind::Fn(sig, _, _) => {
require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
}
hir::ForeignItemKind::Static(..) => {
check_static_inhabited(tcx, def_id);
check_static_linkage(tcx, def_id);
}
_ => {}
}
let item = tcx.hir_foreign_item(item.id);
match &item.kind {
hir::ForeignItemKind::Fn(sig, _, _) => {
require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
}
hir::ForeignItemKind::Static(..) => {
check_static_inhabited(tcx, def_id);
check_static_linkage(tcx, def_id);
}
_ => {}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/intrinsic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Type-checking for the rust-intrinsic intrinsics that the compiler exposes.
//! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes.

use rustc_abi::ExternAbi;
use rustc_errors::codes::*;
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,15 +137,6 @@ fn get_owner_return_paths(
})
}

/// Forbid defining intrinsics in Rust code,
/// as they must always be defined by the compiler.
// FIXME: Move this to a more appropriate place.
pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: ExternAbi) {
if let ExternAbi::RustIntrinsic = abi {
tcx.dcx().span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
}
}

pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
// Only restricted on wasm target for now
if !tcx.sess.target.is_like_wasm {
Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::ObligationCtxt;
use tracing::{debug, instrument};

use crate::check::intrinsic::intrinsic_operation_unsafety;
use crate::errors;
use crate::hir_ty_lowering::errors::assoc_kind_str;
use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
Expand Down Expand Up @@ -1704,18 +1703,13 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
abi: ExternAbi,
safety: hir::Safety,
) -> ty::PolyFnSig<'tcx> {
let safety = if abi == ExternAbi::RustIntrinsic {
intrinsic_operation_unsafety(tcx, def_id)
} else {
safety
};
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let fty =
ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);

// Feature gate SIMD types in FFI, since I am not sure that the
// ABIs are handled at all correctly. -huonw
if abi != ExternAbi::RustIntrinsic && !tcx.features().simd_ffi() {
if !tcx.features().simd_ffi() {
let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
if ty.is_simd() {
let snip = tcx
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir_analysis::check::{check_function_signature, forbid_intrinsic_abi};
use rustc_hir_analysis::check::check_function_signature;
use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::traits::WellFormedLoc;
use rustc_middle::ty::{self, Binder, Ty, TyCtxt};
Expand Down Expand Up @@ -50,8 +50,6 @@ pub(super) fn check_fn<'a, 'tcx>(

let span = body.value.span;

forbid_intrinsic_abi(tcx, span, fn_sig.abi);

GatherLocalsVisitor::new(fcx).visit_body(body);

// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@

use std::ops::Deref;

use rustc_abi::ExternAbi;
use rustc_attr_parsing::InlineAttr;
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, struct_span_code_err};
Expand Down Expand Up @@ -1240,10 +1239,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
};
if let (Some(a_sig), Some(b_sig)) = (a_sig, b_sig) {
// Intrinsics are not coercible to function pointers.
if a_sig.abi() == ExternAbi::RustIntrinsic || b_sig.abi() == ExternAbi::RustIntrinsic {
return Err(TypeError::IntrinsicCast);
}
// The signature must match.
let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig));
let sig = self
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ impl<'tcx> Collector<'tcx> {

let sess = self.tcx.sess;

if matches!(abi, ExternAbi::Rust | ExternAbi::RustIntrinsic) {
if matches!(abi, ExternAbi::Rust) {
return;
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub enum InstanceKind<'tcx> {
/// - coroutines
Item(DefId),

/// An intrinsic `fn` item (with `"rust-intrinsic"` ABI).
/// An intrinsic `fn` item (with`#[rustc_instrinsic]`).
///
/// Alongside `Virtual`, this is the only `InstanceKind` that does not have its own callable MIR.
/// Instead, codegen and const eval "magically" evaluate calls to intrinsics purely in the
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1265,9 +1265,7 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: ExternAbi)
| CCmseNonSecureCall
| CCmseNonSecureEntry
| Unadjusted => false,
Rust | RustCall | RustCold | RustIntrinsic => {
tcx.sess.panic_strategy() == PanicStrategy::Unwind
}
Rust | RustCall | RustCold => tcx.sess.panic_strategy() == PanicStrategy::Unwind,
}
}

Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_middle/src/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use std::{fmt, iter};

use rustc_abi::{ExternAbi, Float, Integer, IntegerType, Size};
use rustc_abi::{Float, Integer, IntegerType, Size};
use rustc_apfloat::Float as _;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
Expand Down Expand Up @@ -1719,10 +1719,7 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
/// cause an ICE that we otherwise may want to prevent.
pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
if tcx.features().intrinsics()
&& (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
|| tcx.has_attr(def_id, sym::rustc_intrinsic))
{
if tcx.features().intrinsics() && tcx.has_attr(def_id, sym::rustc_intrinsic) {
let must_be_overridden = match tcx.hir_node_by_def_id(def_id) {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn { has_body, .. }, .. }) => {
!has_body
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
if target == Target::ForeignMod
&& let hir::Node::Item(item) = self.tcx.hir_node(hir_id)
&& let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
&& !matches!(abi, ExternAbi::Rust | ExternAbi::RustIntrinsic)
&& !matches!(abi, ExternAbi::Rust)
{
return;
}
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_smir/src/rustc_internal/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,6 @@ impl RustcInternal for Abi {
Abi::CCmseNonSecureCall => rustc_abi::ExternAbi::CCmseNonSecureCall,
Abi::CCmseNonSecureEntry => rustc_abi::ExternAbi::CCmseNonSecureEntry,
Abi::System { unwind } => rustc_abi::ExternAbi::System { unwind },
Abi::RustIntrinsic => rustc_abi::ExternAbi::RustIntrinsic,
Abi::RustCall => rustc_abi::ExternAbi::RustCall,
Abi::Unadjusted => rustc_abi::ExternAbi::Unadjusted,
Abi::RustCold => rustc_abi::ExternAbi::RustCold,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_smir/src/rustc_smir/convert/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,6 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi {
ExternAbi::CCmseNonSecureCall => Abi::CCmseNonSecureCall,
ExternAbi::CCmseNonSecureEntry => Abi::CCmseNonSecureEntry,
ExternAbi::System { unwind } => Abi::System { unwind },
ExternAbi::RustIntrinsic => Abi::RustIntrinsic,
ExternAbi::RustCall => Abi::RustCall,
ExternAbi::Unadjusted => Abi::Unadjusted,
ExternAbi::RustCold => Abi::RustCold,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_smir/src/stable_mir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,6 @@ pub enum Abi {
CCmseNonSecureCall,
CCmseNonSecureEntry,
System { unwind: bool },
RustIntrinsic,
RustCall,
Unadjusted,
RustCold,
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_target/src/callconv/loongarch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rustc_abi::{
BackendRepr, ExternAbi, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size,
TyAbiInterface, TyAndLayout, Variants,
BackendRepr, FieldsShape, HasDataLayout, Primitive, Reg, RegKind, Size, TyAbiInterface,
TyAndLayout, Variants,
};

use crate::callconv::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Uniform};
Expand Down Expand Up @@ -364,15 +364,11 @@ where
}
}

pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, abi: ExternAbi)
pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
if abi == ExternAbi::RustIntrinsic {
return;
}

let grlen = cx.data_layout().pointer_size.bits();

for arg in fn_abi.args.iter_mut() {
Expand Down
Loading
Loading