Auto merge of #131808 - jdonszelmann:hir-attributes, r=oli-obk,petrochenkov
Hir attributes This PR needs some explanation, it's somewhat large. - This is step one as described in https://github.com/rust-lang/compiler-team/issues/796. I've added a new `hir::Attribute` which is a lowered version of `ast::Attribute`. Right now, this has few concrete effects, however every place that after this PR parses a `hir::Attribute` should later get a pre-parsed attribute as described in https://github.com/rust-lang/compiler-team/issues/796 and transitively https://github.com/rust-lang/rust/issues/131229. - an extension trait `AttributeExt` is added, which is implemented for both `ast::Attribute` and `hir::Atribute`. This makes `hir::Attributes` mostly compatible with code that used to parse `ast::Attribute`. All its methods are also added as inherent methods to avoid having to import the trait everywhere in the compiler. - Incremental can not not hash `ast::Attribute` at all.
This commit is contained in:
commit
f2b91ccbc2
89 changed files with 1153 additions and 717 deletions
|
@ -23,6 +23,7 @@ rustc_errors = { path = "../rustc_errors" }
|
|||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
rustc_fs_util = { path = "../rustc_fs_util" }
|
||||
rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
|
||||
rustc_incremental = { path = "../rustc_incremental" }
|
||||
rustc_index = { path = "../rustc_index" }
|
||||
rustc_macros = { path = "../rustc_macros" }
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
use rustc_middle::mir::mono::CodegenUnitNameBuilder;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
@ -77,7 +77,7 @@ struct AssertModuleSource<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> AssertModuleSource<'tcx> {
|
||||
fn check_attr(&mut self, attr: &ast::Attribute) {
|
||||
fn check_attr(&mut self, attr: &hir::Attribute) {
|
||||
let (expected_reuse, comp_kind) = if attr.has_name(sym::rustc_partition_reused) {
|
||||
(CguReuse::PreLto, ComparisonKind::AtLeast)
|
||||
} else if attr.has_name(sym::rustc_partition_codegened) {
|
||||
|
@ -158,7 +158,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol {
|
||||
fn field(&self, attr: &hir::Attribute, name: Symbol) -> Symbol {
|
||||
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
|
||||
if item.has_name(name) {
|
||||
if let Some(value) = item.value_str() {
|
||||
|
@ -177,7 +177,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
|
||||
/// Scan for a `cfg="foo"` attribute and check whether we have a
|
||||
/// cfg flag called `foo`.
|
||||
fn check_config(&self, attr: &ast::Attribute) -> bool {
|
||||
fn check_config(&self, attr: &hir::Attribute) -> bool {
|
||||
let config = &self.tcx.sess.psess.config;
|
||||
let value = self.field(attr, sym::cfg);
|
||||
debug!("check_config(config={:?}, value={:?})", config, value);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_ast::{MetaItemInner, MetaItemKind, ast, attr};
|
||||
use rustc_ast::{MetaItemInner, attr};
|
||||
use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::codes::*;
|
||||
|
@ -6,7 +6,7 @@ use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err};
|
|||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
|
||||
use rustc_hir::{HirId, LangItem, lang_items};
|
||||
use rustc_hir::{self as hir, HirId, LangItem, lang_items};
|
||||
use rustc_middle::middle::codegen_fn_attrs::{
|
||||
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
|
||||
};
|
||||
|
@ -525,28 +525,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
if !attr.has_name(sym::inline) {
|
||||
return ia;
|
||||
}
|
||||
match attr.meta_kind() {
|
||||
Some(MetaItemKind::Word) => InlineAttr::Hint,
|
||||
Some(MetaItemKind::List(ref items)) => {
|
||||
inline_span = Some(attr.span);
|
||||
if items.len() != 1 {
|
||||
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument")
|
||||
.emit();
|
||||
InlineAttr::None
|
||||
} else if list_contains_name(items, sym::always) {
|
||||
InlineAttr::Always
|
||||
} else if list_contains_name(items, sym::never) {
|
||||
InlineAttr::Never
|
||||
} else {
|
||||
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
|
||||
.with_help("valid inline arguments are `always` and `never`")
|
||||
.emit();
|
||||
if attr.is_word() {
|
||||
InlineAttr::Hint
|
||||
} else if let Some(ref items) = attr.meta_item_list() {
|
||||
inline_span = Some(attr.span);
|
||||
if items.len() != 1 {
|
||||
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit();
|
||||
InlineAttr::None
|
||||
} else if list_contains_name(items, sym::always) {
|
||||
InlineAttr::Always
|
||||
} else if list_contains_name(items, sym::never) {
|
||||
InlineAttr::Never
|
||||
} else {
|
||||
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
|
||||
.with_help("valid inline arguments are `always` and `never`")
|
||||
.emit();
|
||||
|
||||
InlineAttr::None
|
||||
}
|
||||
InlineAttr::None
|
||||
}
|
||||
Some(MetaItemKind::NameValue(_)) => ia,
|
||||
None => ia,
|
||||
} else {
|
||||
ia
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -562,27 +560,24 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
return ia;
|
||||
}
|
||||
let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit();
|
||||
match attr.meta_kind() {
|
||||
Some(MetaItemKind::Word) => {
|
||||
if attr.is_word() {
|
||||
err(attr.span, "expected one argument");
|
||||
ia
|
||||
} else if let Some(ref items) = attr.meta_item_list() {
|
||||
inline_span = Some(attr.span);
|
||||
if items.len() != 1 {
|
||||
err(attr.span, "expected one argument");
|
||||
ia
|
||||
OptimizeAttr::None
|
||||
} else if list_contains_name(items, sym::size) {
|
||||
OptimizeAttr::Size
|
||||
} else if list_contains_name(items, sym::speed) {
|
||||
OptimizeAttr::Speed
|
||||
} else {
|
||||
err(items[0].span(), "invalid argument");
|
||||
OptimizeAttr::None
|
||||
}
|
||||
Some(MetaItemKind::List(ref items)) => {
|
||||
inline_span = Some(attr.span);
|
||||
if items.len() != 1 {
|
||||
err(attr.span, "expected one argument");
|
||||
OptimizeAttr::None
|
||||
} else if list_contains_name(items, sym::size) {
|
||||
OptimizeAttr::Size
|
||||
} else if list_contains_name(items, sym::speed) {
|
||||
OptimizeAttr::Speed
|
||||
} else {
|
||||
err(items[0].span(), "invalid argument");
|
||||
OptimizeAttr::None
|
||||
}
|
||||
}
|
||||
Some(MetaItemKind::NameValue(_)) => ia,
|
||||
None => ia,
|
||||
} else {
|
||||
OptimizeAttr::None
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -730,7 +725,7 @@ fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
|
||||
fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
|
||||
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
|
||||
let meta_item_list = attr.meta_item_list();
|
||||
let meta_item_list = meta_item_list.as_deref();
|
||||
|
@ -795,7 +790,7 @@ struct MixedExportNameAndNoMangleState<'a> {
|
|||
export_name: Option<Span>,
|
||||
hir_id: Option<HirId>,
|
||||
no_mangle: Option<Span>,
|
||||
no_mangle_attr: Option<&'a ast::Attribute>,
|
||||
no_mangle_attr: Option<&'a hir::Attribute>,
|
||||
}
|
||||
|
||||
impl<'a> MixedExportNameAndNoMangleState<'a> {
|
||||
|
@ -803,7 +798,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
|
|||
self.export_name = Some(span);
|
||||
}
|
||||
|
||||
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a ast::Attribute) {
|
||||
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a hir::Attribute) {
|
||||
self.no_mangle = Some(span);
|
||||
self.hir_id = Some(hir_id);
|
||||
self.no_mangle_attr = Some(attr_name);
|
||||
|
@ -824,7 +819,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
|
|||
no_mangle,
|
||||
errors::MixedExportNameAndNoMangle {
|
||||
no_mangle,
|
||||
no_mangle_attr: rustc_ast_pretty::pprust::attribute_to_string(no_mangle_attr),
|
||||
no_mangle_attr: rustc_hir_pretty::attribute_to_string(&tcx, no_mangle_attr),
|
||||
export_name,
|
||||
removal_span: no_mangle,
|
||||
},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_ast::ast;
|
||||
use rustc_attr::InstructionSetAttr;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||
|
@ -19,7 +19,7 @@ use crate::errors;
|
|||
/// Enabled target features are added to `target_features`.
|
||||
pub(crate) fn from_target_feature_attr(
|
||||
tcx: TyCtxt<'_>,
|
||||
attr: &ast::Attribute,
|
||||
attr: &hir::Attribute,
|
||||
rust_target_features: &UnordMap<String, target_features::StabilityComputed>,
|
||||
target_features: &mut Vec<TargetFeature>,
|
||||
) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue