Return a struct from query intrinsic to be able to add another field in the next commit

This commit is contained in:
Oli Scherer 2024-02-19 17:35:12 +00:00
parent aa2ae6b491
commit f2612daf58
14 changed files with 33 additions and 26 deletions

View File

@ -1667,7 +1667,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// (Eventually this should use const-generics, but those are not up for the task yet: // (Eventually this should use const-generics, but those are not up for the task yet:
// https://github.com/rust-lang/rust/issues/85229.) // https://github.com/rust-lang/rust/issues/85229.)
if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) = if let Some(name @ (sym::simd_shuffle | sym::simd_insert | sym::simd_extract)) =
self.tcx().intrinsic(def_id) self.tcx().intrinsic(def_id).map(|i| i.name)
{ {
let idx = match name { let idx = match name {
sym::simd_shuffle => 2, sym::simd_shuffle => 2,

View File

@ -17,7 +17,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::ty::{self, Instance, Ty};
use rustc_session::config::OptLevel; use rustc_session::config::OptLevel;
use rustc_span::{source_map::Spanned, sym, Span, Symbol}; use rustc_span::{source_map::Spanned, sym, Span};
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg}; use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode, Reg};
use rustc_target::abi::{self, HasDataLayout, WrappingRange}; use rustc_target::abi::{self, HasDataLayout, WrappingRange};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
@ -680,7 +680,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&mut self, &mut self,
helper: &TerminatorCodegenHelper<'tcx>, helper: &TerminatorCodegenHelper<'tcx>,
bx: &mut Bx, bx: &mut Bx,
intrinsic: Option<Symbol>, intrinsic: Option<ty::IntrinsicDef>,
instance: Option<Instance<'tcx>>, instance: Option<Instance<'tcx>>,
source_info: mir::SourceInfo, source_info: mir::SourceInfo,
target: Option<mir::BasicBlock>, target: Option<mir::BasicBlock>,
@ -690,7 +690,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Emit a panic or a no-op for `assert_*` intrinsics. // Emit a panic or a no-op for `assert_*` intrinsics.
// These are intrinsics that compile to panics so that we can get a message // These are intrinsics that compile to panics so that we can get a message
// which mentions the offending type, even from a const context. // which mentions the offending type, even from a const context.
let panic_intrinsic = intrinsic.and_then(|s| ValidityRequirement::from_intrinsic(s)); let panic_intrinsic = intrinsic.and_then(|i| ValidityRequirement::from_intrinsic(i.name));
if let Some(requirement) = panic_intrinsic { if let Some(requirement) = panic_intrinsic {
let ty = instance.unwrap().args.type_at(0); let ty = instance.unwrap().args.type_at(0);
@ -826,7 +826,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// The arguments we'll be passing. Plus one to account for outptr, if used. // The arguments we'll be passing. Plus one to account for outptr, if used.
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize; let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
if intrinsic == Some(sym::caller_location) { if matches!(intrinsic, Some(ty::IntrinsicDef { name: sym::caller_location, .. })) {
return if let Some(target) = target { return if let Some(target) = target {
let location = let location =
self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info }); self.get_caller_location(bx, mir::SourceInfo { span: fn_span, ..source_info });
@ -846,7 +846,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
} }
let instance = match intrinsic { let instance = match intrinsic {
None | Some(sym::drop_in_place) => instance, None | Some(ty::IntrinsicDef { name: sym::drop_in_place, .. }) => instance,
Some(intrinsic) => { Some(intrinsic) => {
let mut llargs = Vec::with_capacity(1); let mut llargs = Vec::with_capacity(1);
let ret_dest = self.make_return_dest( let ret_dest = self.make_return_dest(
@ -873,7 +873,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// The indices passed to simd_shuffle in the // The indices passed to simd_shuffle in the
// third argument must be constant. This is // third argument must be constant. This is
// checked by the type-checker. // checked by the type-checker.
if i == 2 && intrinsic == sym::simd_shuffle { if i == 2 && intrinsic.name == sym::simd_shuffle {
if let mir::Operand::Constant(constant) = &arg.node { if let mir::Operand::Constant(constant) = &arg.node {
let (llval, ty) = self.simd_shuffle_indices(bx, constant); let (llval, ty) = self.simd_shuffle_indices(bx, constant);
return OperandRef { return OperandRef {

View File

@ -527,12 +527,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
check_enum(tcx, def_id); check_enum(tcx, def_id);
} }
DefKind::Fn => { DefKind::Fn => {
if let Some(name) = tcx.intrinsic(def_id) { if let Some(i) = tcx.intrinsic(def_id) {
intrinsic::check_intrinsic_type( intrinsic::check_intrinsic_type(
tcx, tcx,
def_id, def_id,
tcx.def_ident_span(def_id).unwrap(), tcx.def_ident_span(def_id).unwrap(),
name, i.name,
Abi::Rust, Abi::Rust,
) )
} }

View File

@ -1749,7 +1749,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.tables.attr_flags.get(self, index) self.root.tables.attr_flags.get(self, index)
} }
fn get_intrinsic(self, index: DefIndex) -> Option<Symbol> { fn get_intrinsic(self, index: DefIndex) -> Option<ty::IntrinsicDef> {
self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self)) self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self))
} }

View File

@ -375,7 +375,7 @@ macro_rules! define_tables {
define_tables! { define_tables! {
- defaulted: - defaulted:
intrinsic: Table<DefIndex, Option<LazyValue<Symbol>>>, intrinsic: Table<DefIndex, Option<LazyValue<ty::IntrinsicDef>>>,
is_macro_rules: Table<DefIndex, bool>, is_macro_rules: Table<DefIndex, bool>,
is_type_alias_impl_trait: Table<DefIndex, bool>, is_type_alias_impl_trait: Table<DefIndex, bool>,
type_alias_is_lazy: Table<DefIndex, bool>, type_alias_is_lazy: Table<DefIndex, bool>,

View File

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

View File

@ -1760,7 +1760,7 @@ rustc_queries! {
separate_provide_extern separate_provide_extern
} }
/// Whether the function is an intrinsic /// 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) } desc { |tcx| "fetch intrinsic name if `{}` is an intrinsic", tcx.def_path_str(def_id) }
separate_provide_extern separate_provide_extern
} }

View File

@ -2,9 +2,14 @@ use rustc_span::{def_id::DefId, Symbol};
use super::TyCtxt; use super::TyCtxt;
#[derive(Copy, Clone, Debug, Decodable, Encodable, HashStable)]
pub struct IntrinsicDef {
pub name: Symbol,
}
impl TyCtxt<'_> { impl TyCtxt<'_> {
pub fn is_intrinsic(self, def_id: DefId, name: Symbol) -> bool { pub fn is_intrinsic(self, def_id: DefId, name: Symbol) -> bool {
let Some(i) = self.intrinsic(def_id) else { return false }; let Some(i) = self.intrinsic(def_id) else { return false };
i == name i.name == name
} }
} }

View File

@ -30,6 +30,7 @@ pub use adt::*;
pub use assoc::*; pub use assoc::*;
pub use generic_args::*; pub use generic_args::*;
pub use generics::*; pub use generics::*;
pub use intrinsic::IntrinsicDef;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::node_id::NodeMap; use rustc_ast::node_id::NodeMap;
pub use rustc_ast_ir::{Movability, Mutability}; pub use rustc_ast_ir::{Movability, Mutability};

View File

@ -75,6 +75,7 @@ trivially_parameterized_over_tcx! {
ty::Visibility<DefIndex>, ty::Visibility<DefIndex>,
ty::adjustment::CoerceUnsizedInfo, ty::adjustment::CoerceUnsizedInfo,
ty::fast_reject::SimplifiedType, ty::fast_reject::SimplifiedType,
ty::IntrinsicDef,
rustc_ast::Attribute, rustc_ast::Attribute,
rustc_ast::DelimArgs, rustc_ast::DelimArgs,
rustc_ast::expand::StrippedCfgItem<rustc_hir::def_id::DefIndex>, 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_index::bit_set::GrowableBitSet;
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_session::Limit; use rustc_session::Limit;
use rustc_span::{sym, Symbol}; use rustc_span::sym;
use rustc_target::abi::{Integer, IntegerType, Primitive, Size}; use rustc_target::abi::{Integer, IntegerType, Primitive, Size};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -1641,12 +1641,12 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
.any(|items| items.iter().any(|item| item.has_name(sym::notable_trait))) .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 /// 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<Symbol> { pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
|| tcx.has_attr(def_id, sym::rustc_intrinsic) || 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()) })
} else { } else {
None None
} }

View File

@ -202,7 +202,7 @@ impl PeekCall {
&terminator.kind &terminator.kind
{ {
if let ty::FnDef(def_id, fn_args) = *func.const_.ty().kind() { if let ty::FnDef(def_id, fn_args) = *func.const_.ty().kind() {
if tcx.intrinsic(def_id)? != sym::rustc_peek { if tcx.intrinsic(def_id)?.name != sym::rustc_peek {
return None; return None;
} }

View File

@ -323,8 +323,8 @@ fn resolve_rust_intrinsic<'tcx>(
func_ty: Ty<'tcx>, func_ty: Ty<'tcx>,
) -> Option<(Symbol, GenericArgsRef<'tcx>)> { ) -> Option<(Symbol, GenericArgsRef<'tcx>)> {
if let ty::FnDef(def_id, args) = *func_ty.kind() { if let ty::FnDef(def_id, args) = *func_ty.kind() {
let name = tcx.intrinsic(def_id)?; let intrinsic = tcx.intrinsic(def_id)?;
return Some((name, args)); return Some((intrinsic.name, args));
} }
None None
} }

View File

@ -14,9 +14,9 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
if let TerminatorKind::Call { func, args, destination, target, .. } = if let TerminatorKind::Call { func, args, destination, target, .. } =
&mut terminator.kind &mut terminator.kind
&& let ty::FnDef(def_id, generic_args) = *func.ty(local_decls, tcx).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 => { sym::unreachable => {
terminator.kind = TerminatorKind::Unreachable; terminator.kind = TerminatorKind::Unreachable;
} }
@ -105,7 +105,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
lhs = args.next().unwrap(); lhs = args.next().unwrap();
rhs = 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_add => BinOp::Add,
sym::wrapping_sub => BinOp::Sub, sym::wrapping_sub => BinOp::Sub,
sym::wrapping_mul => BinOp::Mul, sym::wrapping_mul => BinOp::Mul,
@ -136,7 +136,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
lhs = args.next().unwrap(); lhs = args.next().unwrap();
rhs = 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::add_with_overflow => BinOp::Add,
sym::sub_with_overflow => BinOp::Sub, sym::sub_with_overflow => BinOp::Sub,
sym::mul_with_overflow => BinOp::Mul, sym::mul_with_overflow => BinOp::Mul,
@ -155,7 +155,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
sym::size_of | sym::min_align_of => { sym::size_of | sym::min_align_of => {
if let Some(target) = *target { if let Some(target) = *target {
let tp_ty = generic_args.type_at(0); 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::size_of => NullOp::SizeOf,
sym::min_align_of => NullOp::AlignOf, sym::min_align_of => NullOp::AlignOf,
_ => bug!("unexpected intrinsic"), _ => bug!("unexpected intrinsic"),