Make is_intrinsic
query return the intrinsic name
This commit is contained in:
parent
de4d615e6b
commit
0eee945680
@ -1650,16 +1650,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
|
|
||||||
let func_ty = func.ty(body, self.infcx.tcx);
|
let func_ty = func.ty(body, self.infcx.tcx);
|
||||||
if let ty::FnDef(def_id, _) = *func_ty.kind() {
|
if let ty::FnDef(def_id, _) = *func_ty.kind() {
|
||||||
if self.tcx().is_intrinsic(def_id) {
|
if let Some(sym::simd_shuffle) = self.tcx().intrinsic(def_id) {
|
||||||
match self.tcx().item_name(def_id) {
|
|
||||||
sym::simd_shuffle => {
|
|
||||||
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
|
if !matches!(args[2], Spanned { node: Operand::Constant(_), .. }) {
|
||||||
self.tcx()
|
self.tcx().dcx().emit_err(SimdShuffleLastConst { span: term.source_info.span });
|
||||||
.dcx()
|
|
||||||
.emit_err(SimdShuffleLastConst { span: term.source_info.span });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
|||||||
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
|
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
|
||||||
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
|
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
|
||||||
// foreign items cannot be evaluated at compile-time.
|
// foreign items cannot be evaluated at compile-time.
|
||||||
let is_const = if tcx.is_intrinsic(def_id) {
|
let is_const = if tcx.intrinsic(def_id).is_some() {
|
||||||
tcx.lookup_const_stability(def_id).is_some()
|
tcx.lookup_const_stability(def_id).is_some()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -526,7 +526,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
|
|
||||||
match instance.def {
|
match instance.def {
|
||||||
ty::InstanceDef::Intrinsic(def_id) => {
|
ty::InstanceDef::Intrinsic(def_id) => {
|
||||||
assert!(self.tcx.is_intrinsic(def_id));
|
assert!(self.tcx.intrinsic(def_id).is_some());
|
||||||
// FIXME: Should `InPlace` arguments be reset to uninit?
|
// FIXME: Should `InPlace` arguments be reset to uninit?
|
||||||
M::call_intrinsic(
|
M::call_intrinsic(
|
||||||
self,
|
self,
|
||||||
|
@ -859,7 +859,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||||||
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
|
// We do not use `const` modifiers for intrinsic "functions", as intrinsics are
|
||||||
// `extern` functions, and these have no way to get marked `const`. So instead we
|
// `extern` functions, and these have no way to get marked `const`. So instead we
|
||||||
// use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
|
// use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
|
||||||
if self.ccx.is_const_stable_const_fn() || tcx.is_intrinsic(callee) {
|
if self.ccx.is_const_stable_const_fn() || tcx.intrinsic(callee).is_some() {
|
||||||
self.check_op(ops::FnCallUnstable(callee, None));
|
self.check_op(ops::FnCallUnstable(callee, None));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -540,8 +540,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
if let Some(def_id) = def_id
|
if let Some(def_id) = def_id
|
||||||
&& self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
|
&& self.tcx.def_kind(def_id) == hir::def::DefKind::Fn
|
||||||
&& self.tcx.is_intrinsic(def_id)
|
&& matches!(self.tcx.intrinsic(def_id), Some(sym::const_eval_select))
|
||||||
&& self.tcx.item_name(def_id) == sym::const_eval_select
|
|
||||||
{
|
{
|
||||||
let fn_sig = self.resolve_vars_if_possible(fn_sig);
|
let fn_sig = self.resolve_vars_if_possible(fn_sig);
|
||||||
for idx in 0..=1 {
|
for idx in 0..=1 {
|
||||||
|
@ -864,7 +864,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
let a_sig = a.fn_sig(self.tcx);
|
let a_sig = a.fn_sig(self.tcx);
|
||||||
if let ty::FnDef(def_id, _) = *a.kind() {
|
if let ty::FnDef(def_id, _) = *a.kind() {
|
||||||
// Intrinsics are not coercible to function pointers
|
// Intrinsics are not coercible to function pointers
|
||||||
if self.tcx.is_intrinsic(def_id) {
|
if self.tcx.intrinsic(def_id).is_some() {
|
||||||
return Err(TypeError::IntrinsicCast);
|
return Err(TypeError::IntrinsicCast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
|
|
||||||
if !self.same_type_modulo_infer(*found_sig, *expected_sig)
|
if !self.same_type_modulo_infer(*found_sig, *expected_sig)
|
||||||
|| !sig.is_suggestable(self.tcx, true)
|
|| !sig.is_suggestable(self.tcx, true)
|
||||||
|| self.tcx.is_intrinsic(*did)
|
|| self.tcx.intrinsic(*did).is_some()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -345,8 +345,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
if !self.same_type_modulo_infer(*found_sig, *expected_sig)
|
if !self.same_type_modulo_infer(*found_sig, *expected_sig)
|
||||||
|| !found_sig.is_suggestable(self.tcx, true)
|
|| !found_sig.is_suggestable(self.tcx, true)
|
||||||
|| !expected_sig.is_suggestable(self.tcx, true)
|
|| !expected_sig.is_suggestable(self.tcx, true)
|
||||||
|| self.tcx.is_intrinsic(*did1)
|
|| self.tcx.intrinsic(*did1).is_some()
|
||||||
|| self.tcx.is_intrinsic(*did2)
|
|| self.tcx.intrinsic(*did2).is_some()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1227,7 +1227,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn def_id_is_transmute(cx: &LateContext<'_>, def_id: DefId) -> bool {
|
fn def_id_is_transmute(cx: &LateContext<'_>, def_id: DefId) -> bool {
|
||||||
cx.tcx.is_intrinsic(def_id) && cx.tcx.item_name(def_id) == sym::transmute
|
matches!(cx.tcx.intrinsic(def_id), Some(sym::transmute))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1746,8 +1746,8 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||||||
self.root.tables.attr_flags.get(self, index)
|
self.root.tables.attr_flags.get(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_is_intrinsic(self, index: DefIndex) -> bool {
|
fn get_intrinsic(self, index: DefIndex) -> bool {
|
||||||
self.root.tables.is_intrinsic.get(self, index)
|
self.root.tables.intrinsic.get(self, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_doc_link_resolutions(self, index: DefIndex) -> DocLinkResMap {
|
fn get_doc_link_resolutions(self, index: DefIndex) -> DocLinkResMap {
|
||||||
|
@ -348,7 +348,7 @@ provide! { tcx, def_id, other, cdata,
|
|||||||
cdata.get_stability_implications(tcx).iter().copied().collect()
|
cdata.get_stability_implications(tcx).iter().copied().collect()
|
||||||
}
|
}
|
||||||
stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) }
|
stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) }
|
||||||
is_intrinsic => { cdata.get_is_intrinsic(def_id.index) }
|
intrinsic => { cdata.get_intrinsic(def_id.index).then(|| tcx.item_name(def_id)) }
|
||||||
defined_lang_items => { cdata.get_lang_items(tcx) }
|
defined_lang_items => { cdata.get_lang_items(tcx) }
|
||||||
diagnostic_items => { cdata.get_diagnostic_items() }
|
diagnostic_items => { cdata.get_diagnostic_items() }
|
||||||
missing_lang_items => { cdata.get_missing_lang_items(tcx) }
|
missing_lang_items => { cdata.get_missing_lang_items(tcx) }
|
||||||
|
@ -1411,7 +1411,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
if let DefKind::Fn | DefKind::AssocFn = def_kind {
|
if let DefKind::Fn | DefKind::AssocFn = def_kind {
|
||||||
self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id));
|
self.tables.asyncness.set_some(def_id.index, tcx.asyncness(def_id));
|
||||||
record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id));
|
record_array!(self.tables.fn_arg_names[def_id] <- tcx.fn_arg_names(def_id));
|
||||||
self.tables.is_intrinsic.set(def_id.index, tcx.is_intrinsic(def_id));
|
self.tables.intrinsic.set(def_id.index, tcx.intrinsic(def_id).is_some());
|
||||||
}
|
}
|
||||||
if let DefKind::TyParam = def_kind {
|
if let DefKind::TyParam = def_kind {
|
||||||
let default = self.tcx.object_lifetime_default(def_id);
|
let default = self.tcx.object_lifetime_default(def_id);
|
||||||
|
@ -375,7 +375,7 @@ macro_rules! define_tables {
|
|||||||
|
|
||||||
define_tables! {
|
define_tables! {
|
||||||
- defaulted:
|
- defaulted:
|
||||||
is_intrinsic: Table<DefIndex, bool>,
|
intrinsic: Table<DefIndex, bool>,
|
||||||
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>,
|
||||||
|
@ -240,6 +240,7 @@ trivial! {
|
|||||||
Option<rustc_span::Span>,
|
Option<rustc_span::Span>,
|
||||||
Option<rustc_target::spec::PanicStrategy>,
|
Option<rustc_target::spec::PanicStrategy>,
|
||||||
Option<usize>,
|
Option<usize>,
|
||||||
|
Option<rustc_span::Symbol>,
|
||||||
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>,
|
||||||
|
@ -1753,8 +1753,8 @@ rustc_queries! {
|
|||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
/// Whether the function is an intrinsic
|
/// Whether the function is an intrinsic
|
||||||
query is_intrinsic(def_id: DefId) -> bool {
|
query intrinsic(def_id: DefId) -> Option<Symbol> {
|
||||||
desc { |tcx| "checking whether `{}` 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
|
||||||
}
|
}
|
||||||
/// Returns the lang items defined in another crate by loading it from metadata.
|
/// Returns the lang items defined in another crate by loading it from metadata.
|
||||||
|
@ -18,7 +18,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;
|
use rustc_span::{sym, Symbol};
|
||||||
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;
|
||||||
@ -1550,8 +1550,13 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether an item is an intrinsic by Abi.
|
/// Determines whether an item is an intrinsic by Abi.
|
||||||
pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Symbol> {
|
||||||
matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
|
if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
|
||||||
|
{
|
||||||
|
Some(tcx.item_name(def_id.into()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
@ -1559,7 +1564,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
reveal_opaque_types_in_bounds,
|
reveal_opaque_types_in_bounds,
|
||||||
is_doc_hidden,
|
is_doc_hidden,
|
||||||
is_doc_notable_trait,
|
is_doc_notable_trait,
|
||||||
is_intrinsic,
|
intrinsic,
|
||||||
..*providers
|
..*providers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,8 +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() {
|
||||||
let name = tcx.item_name(def_id);
|
if tcx.intrinsic(def_id)? != sym::rustc_peek {
|
||||||
if !tcx.is_intrinsic(def_id) || name != sym::rustc_peek {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
|||||||
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
||||||
let fn_ty = self.instantiate_ty(f.const_.ty());
|
let fn_ty = self.instantiate_ty(f.const_.ty());
|
||||||
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind()
|
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind()
|
||||||
&& tcx.is_intrinsic(def_id)
|
&& tcx.intrinsic(def_id).is_some()
|
||||||
{
|
{
|
||||||
// Don't give intrinsics the extra penalty for calls
|
// Don't give intrinsics the extra penalty for calls
|
||||||
INSTR_COST
|
INSTR_COST
|
||||||
|
@ -329,9 +329,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() {
|
||||||
if tcx.is_intrinsic(def_id) {
|
let name = tcx.intrinsic(def_id)?;
|
||||||
return Some((tcx.item_name(def_id), args));
|
return Some((name, args));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -161,8 +161,7 @@ fn remap_mir_for_const_eval_select<'tcx>(
|
|||||||
fn_span,
|
fn_span,
|
||||||
..
|
..
|
||||||
} if let ty::FnDef(def_id, _) = *const_.ty().kind()
|
} if let ty::FnDef(def_id, _) = *const_.ty().kind()
|
||||||
&& tcx.item_name(def_id) == sym::const_eval_select
|
&& matches!(tcx.intrinsic(def_id), Some(sym::const_eval_select)) =>
|
||||||
&& tcx.is_intrinsic(def_id) =>
|
|
||||||
{
|
{
|
||||||
let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
|
let [tupled_args, called_in_const, called_at_rt]: [_; 3] =
|
||||||
std::mem::take(args).try_into().unwrap();
|
std::mem::take(args).try_into().unwrap();
|
||||||
|
@ -14,9 +14,8 @@ 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()
|
||||||
&& tcx.is_intrinsic(def_id)
|
&& let Some(intrinsic_name) = tcx.intrinsic(def_id)
|
||||||
{
|
{
|
||||||
let intrinsic_name = tcx.item_name(def_id);
|
|
||||||
match intrinsic_name {
|
match intrinsic_name {
|
||||||
sym::unreachable => {
|
sym::unreachable => {
|
||||||
terminator.kind = TerminatorKind::Unreachable;
|
terminator.kind = TerminatorKind::Unreachable;
|
||||||
|
@ -28,7 +28,8 @@ fn resolve_instance<'tcx>(
|
|||||||
tcx.normalize_erasing_regions(param_env, args),
|
tcx.normalize_erasing_regions(param_env, args),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.is_intrinsic(def_id) {
|
let def = if matches!(tcx.def_kind(def_id), DefKind::Fn) && tcx.intrinsic(def_id).is_some()
|
||||||
|
{
|
||||||
debug!(" => intrinsic");
|
debug!(" => intrinsic");
|
||||||
ty::InstanceDef::Intrinsic(def_id)
|
ty::InstanceDef::Intrinsic(def_id)
|
||||||
} else if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
|
} else if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
|
||||||
|
@ -335,7 +335,7 @@ fn check_terminator<'tcx>(
|
|||||||
// within const fns. `transmute` is allowed in all other const contexts.
|
// within const fns. `transmute` is allowed in all other const contexts.
|
||||||
// This won't really scale to more intrinsics or functions. Let's allow const
|
// This won't really scale to more intrinsics or functions. Let's allow const
|
||||||
// transmutes in const fn before we add more hacks to this.
|
// transmutes in const fn before we add more hacks to this.
|
||||||
if tcx.is_intrinsic(fn_def_id) && tcx.item_name(fn_def_id) == sym::transmute {
|
if matches!(tcx.intrinsic(fn_def_id), Some(sym::transmute)) {
|
||||||
return Err((
|
return Err((
|
||||||
span,
|
span,
|
||||||
"can only call `transmute` from const items, not `const fn`".into(),
|
"can only call `transmute` from const items, not `const fn`".into(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user