Revert "Auto merge of #127537 - veluca93:struct_tf, r=BoxyUwU"
This reverts commitacb4e8b625
, reversing changes made to100fde5246
.
This commit is contained in:
parent
1a1cc050d8
commit
47e6b5deed
25 changed files with 27 additions and 511 deletions
|
@ -1,6 +1,5 @@
|
|||
use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem};
|
||||
use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{struct_span_code_err, DiagMessage, SubdiagMessage};
|
||||
use rustc_hir as hir;
|
||||
|
@ -9,7 +8,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
|||
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
|
||||
use rustc_hir::{lang_items, LangItem};
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, TargetFeature,
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||
};
|
||||
use rustc_middle::mir::mono::Linkage;
|
||||
use rustc_middle::query::Providers;
|
||||
|
@ -18,7 +17,6 @@ use rustc_session::lint;
|
|||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::{abi, SanitizerSet};
|
||||
|
||||
use crate::errors;
|
||||
|
@ -80,13 +78,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
let mut link_ordinal_span = None;
|
||||
let mut no_sanitize_span = None;
|
||||
|
||||
let fn_sig_outer = || {
|
||||
use DefKind::*;
|
||||
|
||||
let def_kind = tcx.def_kind(did);
|
||||
if let Fn | AssocFn | Variant | Ctor(..) = def_kind { Some(tcx.fn_sig(did)) } else { None }
|
||||
};
|
||||
|
||||
for attr in attrs.iter() {
|
||||
// In some cases, attribute are only valid on functions, but it's the `check_attr`
|
||||
// pass that check that they aren't used anywhere else, rather this module.
|
||||
|
@ -94,12 +85,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
// functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
|
||||
// report a delayed bug, just in case `check_attr` isn't doing its job.
|
||||
let fn_sig = || {
|
||||
let sig = fn_sig_outer();
|
||||
if sig.is_none() {
|
||||
use DefKind::*;
|
||||
|
||||
let def_kind = tcx.def_kind(did);
|
||||
if let Fn | AssocFn | Variant | Ctor(..) = def_kind {
|
||||
Some(tcx.fn_sig(did))
|
||||
} else {
|
||||
tcx.dcx()
|
||||
.span_delayed_bug(attr.span, "this attribute can only be applied to functions");
|
||||
None
|
||||
}
|
||||
sig
|
||||
};
|
||||
|
||||
let Some(Ident { name, .. }) = attr.ident() else {
|
||||
|
@ -618,93 +613,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(sig) = fn_sig_outer() {
|
||||
// Collect target features from types reachable from arguments.
|
||||
// We define a type as "reachable" if:
|
||||
// - it is a function argument
|
||||
// - it is a field of a reachable struct
|
||||
// - there is a reachable reference to it
|
||||
// FIXME(struct_target_features): we may want to cache the result of this computation.
|
||||
let mut visited_types = FxHashSet::default();
|
||||
let mut reachable_types: Vec<_> = sig.skip_binder().inputs().skip_binder().to_owned();
|
||||
let mut additional_tf = vec![];
|
||||
|
||||
while let Some(ty) = reachable_types.pop() {
|
||||
if visited_types.contains(&ty) {
|
||||
continue;
|
||||
}
|
||||
visited_types.insert(ty);
|
||||
match ty.kind() {
|
||||
ty::Alias(..) => {
|
||||
if let Ok(t) =
|
||||
tcx.try_normalize_erasing_regions(tcx.param_env(did.to_def_id()), ty)
|
||||
{
|
||||
reachable_types.push(t)
|
||||
}
|
||||
}
|
||||
|
||||
ty::Ref(_, inner, _) => reachable_types.push(*inner),
|
||||
ty::Tuple(tys) => reachable_types.extend(tys.iter()),
|
||||
ty::Adt(adt_def, args) => {
|
||||
additional_tf.extend_from_slice(tcx.struct_target_features(adt_def.did()));
|
||||
// This only recurses into structs as i.e. an Option<TargetFeature> is an ADT
|
||||
// that doesn't actually always contain a TargetFeature.
|
||||
if adt_def.is_struct() {
|
||||
reachable_types.extend(
|
||||
adt_def
|
||||
.variant(VariantIdx::from_usize(0))
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| field.ty(tcx, args)),
|
||||
);
|
||||
}
|
||||
}
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(..)
|
||||
| ty::Uint(..)
|
||||
| ty::Float(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Str
|
||||
| ty::Array(..)
|
||||
| ty::Pat(..)
|
||||
| ty::Slice(..)
|
||||
| ty::RawPtr(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
| ty::Param(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Error(..) => (),
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(struct_target_features): is this really necessary?
|
||||
if !additional_tf.is_empty() && sig.skip_binder().abi() != abi::Abi::Rust {
|
||||
tcx.dcx().span_err(
|
||||
tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
|
||||
"cannot use a struct with target features in a function with non-Rust ABI",
|
||||
);
|
||||
}
|
||||
if !additional_tf.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
|
||||
tcx.dcx().span_err(
|
||||
tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
|
||||
"cannot use a struct with target features in a #[inline(always)] function",
|
||||
);
|
||||
}
|
||||
codegen_fn_attrs
|
||||
.target_features
|
||||
.extend(additional_tf.iter().map(|tf| TargetFeature { implied: true, ..*tf }));
|
||||
}
|
||||
|
||||
// If a function uses non-default target_features it can't be inlined into general
|
||||
// If a function uses #[target_feature] it can't be inlined into general
|
||||
// purpose functions as they wouldn't have the right target features
|
||||
// enabled. For that reason we also forbid #[inline(always)] as it can't be
|
||||
// respected.
|
||||
|
@ -849,20 +758,6 @@ fn check_link_name_xor_ordinal(
|
|||
}
|
||||
}
|
||||
|
||||
fn struct_target_features(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &[TargetFeature] {
|
||||
let mut features = vec![];
|
||||
let supported_features = tcx.supported_target_features(LOCAL_CRATE);
|
||||
for attr in tcx.get_attrs(def_id, sym::target_feature) {
|
||||
from_target_feature(tcx, attr, supported_features, &mut features);
|
||||
}
|
||||
tcx.arena.alloc_slice(&features)
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
*providers = Providers {
|
||||
codegen_fn_attrs,
|
||||
should_inherit_track_caller,
|
||||
struct_target_features,
|
||||
..*providers
|
||||
};
|
||||
*providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue