1
Fork 0

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
This commit is contained in:
bors 2024-03-05 00:13:01 +00:00
commit 2eeff462b7
31 changed files with 207 additions and 51 deletions

View file

@ -241,7 +241,7 @@ trivial! {
Option<rustc_target::abi::FieldIdx>,
Option<rustc_target::spec::PanicStrategy>,
Option<usize>,
Option<rustc_span::Symbol>,
Option<rustc_middle::ty::IntrinsicDef>,
Result<(), rustc_errors::ErrorGuaranteed>,
Result<(), rustc_middle::traits::query::NoSolution>,
Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,

View file

@ -1760,7 +1760,7 @@ rustc_queries! {
separate_provide_extern
}
/// Whether the function is an intrinsic
query intrinsic(def_id: DefId) -> Option<Symbol> {
query intrinsic(def_id: DefId) -> Option<rustc_middle::ty::IntrinsicDef> {
desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) }
separate_provide_extern
}

View file

@ -0,0 +1,17 @@
use rustc_span::{def_id::DefId, Symbol};
use super::TyCtxt;
#[derive(Copy, Clone, Debug, Decodable, Encodable, HashStable)]
pub struct IntrinsicDef {
pub name: Symbol,
/// Whether the intrinsic has no meaningful body and all backends need to shim all calls to it.
pub must_be_overridden: bool,
}
impl TyCtxt<'_> {
pub fn is_intrinsic(self, def_id: DefId, name: Symbol) -> bool {
let Some(i) = self.intrinsic(def_id) else { return false };
i.name == name
}
}

View file

@ -30,6 +30,7 @@ pub use adt::*;
pub use assoc::*;
pub use generic_args::*;
pub use generics::*;
pub use intrinsic::IntrinsicDef;
use rustc_ast as ast;
use rustc_ast::node_id::NodeMap;
pub use rustc_ast_ir::{Movability, Mutability};
@ -149,6 +150,7 @@ mod generic_args;
mod generics;
mod impls_ty;
mod instance;
mod intrinsic;
mod list;
mod opaque_types;
mod parameterized;

View file

@ -75,6 +75,7 @@ trivially_parameterized_over_tcx! {
ty::Visibility<DefIndex>,
ty::adjustment::CoerceUnsizedInfo,
ty::fast_reject::SimplifiedType,
ty::IntrinsicDef,
rustc_ast::Attribute,
rustc_ast::DelimArgs,
rustc_ast::expand::StrippedCfgItem<rustc_hir::def_id::DefIndex>,

View file

@ -19,7 +19,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_index::bit_set::GrowableBitSet;
use rustc_macros::HashStable;
use rustc_session::Limit;
use rustc_span::{sym, Symbol};
use rustc_span::sym;
use rustc_target::abi::{Integer, IntegerType, Primitive, Size};
use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
@ -1641,12 +1641,19 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
.any(|items| items.iter().any(|item| item.has_name(sym::notable_trait)))
}
/// Determines whether an item is an intrinsic by Abi. or by whether it has a `rustc_intrinsic` attribute
pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Symbol> {
/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute)
pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
match tcx.def_kind(def_id) {
DefKind::Fn | DefKind::AssocFn => {}
_ => return None,
}
if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
|| tcx.has_attr(def_id, sym::rustc_intrinsic)
{
Some(tcx.item_name(def_id.into()))
Some(ty::IntrinsicDef {
name: tcx.item_name(def_id.into()),
must_be_overridden: tcx.has_attr(def_id, sym::rustc_intrinsic_must_be_overridden),
})
} else {
None
}