remove compiler support for extern "rust-intrinsic" blocks

This commit is contained in:
Skgland 2025-04-06 21:32:58 +02:00 committed by Bennet Bleßmann
parent 175dcc7773
commit 5eb535c568
No known key found for this signature in database
GPG key ID: 3BE1A1A3CBC3CF99
23 changed files with 79 additions and 147 deletions

View file

@ -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!
@ -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",
@ -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 {

View file

@ -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 })
}

View file

@ -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(
@ -788,9 +784,10 @@ 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 {
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,
@ -799,16 +796,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
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)
{
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.
@ -848,8 +840,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
}
}
}
}
}
_ => {}
}
}

View file

@ -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::*;

View file

@ -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 {

View file

@ -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};
@ -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

View file

@ -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};
@ -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`

View file

@ -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};
@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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,
}
}

View file

@ -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};
@ -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

View file

@ -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;
}

View file

@ -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,

View file

@ -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,

View file

@ -1093,7 +1093,6 @@ pub enum Abi {
CCmseNonSecureCall,
CCmseNonSecureEntry,
System { unwind: bool },
RustIntrinsic,
RustCall,
Unadjusted,
RustCold,

View file

@ -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};
@ -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() {

View file

@ -717,16 +717,16 @@ impl<'a, Ty> FnAbi<'a, Ty> {
}
}
pub fn adjust_for_rust_abi<C>(&mut self, cx: &C, abi: ExternAbi)
pub fn adjust_for_rust_abi<C>(&mut self, cx: &C)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout + HasTargetSpec,
{
let spec = cx.target_spec();
match &*spec.arch {
"x86" => x86::compute_rust_abi_info(cx, self, abi),
"riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self, abi),
"loongarch64" => loongarch::compute_rust_abi_info(cx, self, abi),
"x86" => x86::compute_rust_abi_info(cx, self),
"riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self),
"loongarch64" => loongarch::compute_rust_abi_info(cx, self),
"aarch64" => aarch64::compute_rust_abi_info(cx, self),
_ => {}
};
@ -850,10 +850,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
//
// Note that the intrinsic ABI is exempt here as those are not
// real functions anyway, and the backend expects very specific types.
if abi != ExternAbi::RustIntrinsic
&& spec.simd_types_indirect
&& !can_pass_simd_directly(arg)
{
if spec.simd_types_indirect && !can_pass_simd_directly(arg) {
arg.make_indirect();
}
}

View file

@ -5,8 +5,8 @@
// https://github.com/llvm/llvm-project/blob/8e780252a7284be45cf1ba224cabd884847e8e92/clang/lib/CodeGen/TargetInfo.cpp#L9311-L9773
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};
@ -370,15 +370,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 xlen = cx.data_layout().pointer_size.bits();
for arg in fn_abi.args.iter_mut() {

View file

@ -1,6 +1,6 @@
use rustc_abi::{
AddressSpace, Align, BackendRepr, ExternAbi, HasDataLayout, Primitive, Reg, RegKind,
TyAbiInterface, TyAndLayout,
AddressSpace, Align, BackendRepr, HasDataLayout, Primitive, Reg, RegKind, TyAbiInterface,
TyAndLayout,
};
use crate::callconv::{ArgAttribute, FnAbi, PassMode};
@ -193,7 +193,7 @@ pub(crate) fn fill_inregs<'a, Ty, C>(
}
}
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,
@ -201,10 +201,7 @@ where
// Avoid returning floats in x87 registers on x86 as loading and storing from x87
// registers will quiet signalling NaNs. Also avoid using SSE registers since they
// are not always available (depending on target features).
if !fn_abi.ret.is_ignore()
// Intrinsics themselves are not "real" functions, so theres no need to change their ABIs.
&& abi != ExternAbi::RustIntrinsic
{
if !fn_abi.ret.is_ignore() {
let has_float = match fn_abi.ret.layout.backend_repr {
BackendRepr::Scalar(s) => matches!(s.primitive(), Primitive::Float(_)),
BackendRepr::ScalarPair(s1, s2) => {

View file

@ -2962,14 +2962,9 @@ impl Target {
pub fn is_abi_supported(&self, abi: ExternAbi) -> bool {
use ExternAbi::*;
match abi {
Rust
| C { .. }
| System { .. }
| RustIntrinsic
| RustCall
| Unadjusted
| Cdecl { .. }
| RustCold => true,
Rust | C { .. } | System { .. } | RustCall | Unadjusted | Cdecl { .. } | RustCold => {
true
}
EfiApi => {
["arm", "aarch64", "riscv32", "riscv64", "x86", "x86_64"].contains(&&self.arch[..])
}

View file

@ -244,7 +244,7 @@ fn fn_sig_for_fn_abi<'tcx>(
fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: ExternAbi, c_variadic: bool) -> Conv {
use rustc_abi::ExternAbi::*;
match tcx.sess.target.adjust_abi(abi, c_variadic) {
RustIntrinsic | Rust | RustCall => Conv::Rust,
Rust | RustCall => Conv::Rust,
// This is intentionally not using `Conv::Cold`, as that has to preserve
// even SIMD registers, which is generally not a good trade-off.
@ -660,7 +660,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
let tcx = cx.tcx();
if abi.is_rustic_abi() {
fn_abi.adjust_for_rust_abi(cx, abi);
fn_abi.adjust_for_rust_abi(cx);
// Look up the deduced parameter attributes for this function, if we have its def ID and
// we're optimizing in non-incremental mode. We'll tag its parameters with those attributes

View file

@ -11,7 +11,6 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{BodyId, Mutability};
use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety;
use rustc_index::IndexVec;
use rustc_metadata::rendered_const;
use rustc_middle::span_bug;
@ -687,8 +686,6 @@ impl Item {
hir::FnHeader {
safety: if tcx.codegen_fn_attrs(def_id).safe_target_features {
hir::HeaderSafety::SafeTargetFeatures
} else if abi == ExternAbi::RustIntrinsic {
intrinsic_operation_unsafety(tcx, def_id.expect_local()).into()
} else {
safety.into()
},