Auto merge of #135726 - jdonszelmann:attr-parsing, r=oli-obk
New attribute parsing infrastructure Another step in the plan outlined in https://github.com/rust-lang/rust/issues/131229 introduces infrastructure for structured parsers for attributes, as well as converting a couple of complex attributes to have such structured parsers. This PR may prove too large to review. I left some of my own comments to guide it a little. Some general notes: - The first commit is basically standalone. It just preps some mostly unrelated sources for the rest of the PR to work. It might not have enormous merit on its own, but not negative merit either. Could be merged alone, but also doesn't make the review a whole lot easier. (but it's only +274 -209) - The second commit is the one that introduces new infrastructure. It's the important one to review. - The 3rd commit uses the new infrastructure showing how some of the more complex attributes can be parsed using it. Theoretically can be split up, though the parsers in this commit are the ones that really test the new infrastructure and show that it all works. - The 4th commit fixes up rustdoc and clippy. In the previous 2 they didn't compile yet while the compiler does. Separated them out to separate concerns and make the rest more palatable. - The 5th commit blesses some test outputs. Sometimes that's just because a diagnostic happens slightly earlier than before, which I'd say is acceptable. Sometimes a diagnostic is now only emitted once where it would've been twice before (yay! fixed some bugs). One test I actually moved from crashes to fixed, because it simply doesn't crash anymore. That's why this PR Closes #132391. I think most choices I made here are generally reasonable, but let me know if you disagree anywhere. - The 6th commit adds a derive to pretty print attributes - The 7th removes smir apis for attributes, for the time being. The api will at some point be replaced by one based on `rustc_ast_data_structures::AttributeKind` In general, a lot of the additions here are comments. I've found it very important to document new things in the 2nd commit well so other people can start using it. Closes #132391 Closes #136717
This commit is contained in:
commit
7d8c6e781d
167 changed files with 3963 additions and 2292 deletions
|
@ -94,7 +94,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
other => {
|
||||
self.tcx
|
||||
.dcx()
|
||||
.emit_fatal(errors::UnknownReuseKind { span: attr.span, kind: other });
|
||||
.emit_fatal(errors::UnknownReuseKind { span: attr.span(), kind: other });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -102,7 +102,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
};
|
||||
|
||||
if !self.tcx.sess.opts.unstable_opts.query_dep_graph {
|
||||
self.tcx.dcx().emit_fatal(errors::MissingQueryDepGraph { span: attr.span });
|
||||
self.tcx.dcx().emit_fatal(errors::MissingQueryDepGraph { span: attr.span() });
|
||||
}
|
||||
|
||||
if !self.check_config(attr) {
|
||||
|
@ -115,7 +115,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
|
||||
if !user_path.starts_with(&crate_name) {
|
||||
self.tcx.dcx().emit_fatal(errors::MalformedCguName {
|
||||
span: attr.span,
|
||||
span: attr.span(),
|
||||
user_path,
|
||||
crate_name,
|
||||
});
|
||||
|
@ -145,7 +145,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
let cgu_names: Vec<&str> =
|
||||
self.available_cgus.items().map(|cgu| cgu.as_str()).into_sorted_stable_ord();
|
||||
self.tcx.dcx().emit_err(errors::NoModuleNamed {
|
||||
span: attr.span,
|
||||
span: attr.span(),
|
||||
user_path,
|
||||
cgu_name,
|
||||
cgu_names: cgu_names.join(", "),
|
||||
|
@ -155,7 +155,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
self.cgu_reuse_tracker.set_expectation(
|
||||
cgu_name,
|
||||
user_path,
|
||||
attr.span,
|
||||
attr.span(),
|
||||
expected_reuse,
|
||||
comp_kind,
|
||||
);
|
||||
|
@ -175,7 +175,7 @@ impl<'tcx> AssertModuleSource<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
self.tcx.dcx().emit_fatal(errors::NoField { span: attr.span, name });
|
||||
self.tcx.dcx().emit_fatal(errors::NoField { span: attr.span(), name });
|
||||
}
|
||||
|
||||
/// Scan for a `cfg="foo"` attribute and check whether we have a
|
||||
|
|
|
@ -5,7 +5,9 @@ use std::time::{Duration, Instant};
|
|||
|
||||
use itertools::Itertools;
|
||||
use rustc_abi::FIRST_VARIANT;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name};
|
||||
use rustc_attr_parsing::OptimizeAttr;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
|
||||
use rustc_data_structures::sync::par_map;
|
||||
|
@ -29,7 +31,6 @@ use rustc_span::{DUMMY_SP, Symbol, sym};
|
|||
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
|
||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
|
||||
use tracing::{debug, info};
|
||||
use {rustc_ast as ast, rustc_attr_parsing as attr};
|
||||
|
||||
use crate::assert_module_sources::CguReuse;
|
||||
use crate::back::link::are_upstream_rust_objects_already_included;
|
||||
|
@ -1061,7 +1062,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||
|
||||
let any_for_speed = defids.items().any(|id| {
|
||||
let CodegenFnAttrs { optimize, .. } = tcx.codegen_fn_attrs(*id);
|
||||
matches!(optimize, attr::OptimizeAttr::Speed)
|
||||
matches!(optimize, OptimizeAttr::Speed)
|
||||
});
|
||||
|
||||
if any_for_speed {
|
||||
|
|
|
@ -5,7 +5,8 @@ use rustc_ast::expand::autodiff_attrs::{
|
|||
AutoDiffAttrs, DiffActivity, DiffMode, valid_input_activity, valid_ret_activity,
|
||||
};
|
||||
use rustc_ast::{MetaItem, MetaItemInner, attr};
|
||||
use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
use rustc_attr_parsing::ReprAttr::ReprAlign;
|
||||
use rustc_attr_parsing::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::codes::*;
|
||||
use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err};
|
||||
|
@ -104,12 +105,26 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
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");
|
||||
tcx.dcx().span_delayed_bug(
|
||||
attr.span(),
|
||||
"this attribute can only be applied to functions",
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
if let hir::Attribute::Parsed(p) = attr {
|
||||
match p {
|
||||
AttributeKind::Repr(reprs) => {
|
||||
codegen_fn_attrs.alignment = reprs
|
||||
.iter()
|
||||
.find_map(|(r, _)| if let ReprAlign(x) = r { Some(*x) } else { None });
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let Some(Ident { name, .. }) = attr.ident() else {
|
||||
continue;
|
||||
};
|
||||
|
@ -130,14 +145,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
if tcx.opt_item_name(did.to_def_id()).is_some() {
|
||||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
|
||||
mixed_export_name_no_mangle_lint_state.track_no_mangle(
|
||||
attr.span,
|
||||
attr.span(),
|
||||
tcx.local_def_id_to_hir_id(did),
|
||||
attr,
|
||||
);
|
||||
} else {
|
||||
tcx.dcx()
|
||||
.struct_span_err(
|
||||
attr.span,
|
||||
attr.span(),
|
||||
format!(
|
||||
"`#[no_mangle]` cannot be used on {} {} as it has no name",
|
||||
tcx.def_descr_article(did.to_def_id()),
|
||||
|
@ -158,7 +173,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
feature_err(
|
||||
&tcx.sess,
|
||||
sym::used_with_arg,
|
||||
attr.span,
|
||||
attr.span(),
|
||||
"`#[used(linker)]` is currently unstable",
|
||||
)
|
||||
.emit();
|
||||
|
@ -170,7 +185,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
feature_err(
|
||||
&tcx.sess,
|
||||
sym::used_with_arg,
|
||||
attr.span,
|
||||
attr.span(),
|
||||
"`#[used(compiler)]` is currently unstable",
|
||||
)
|
||||
.emit();
|
||||
|
@ -178,7 +193,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED;
|
||||
}
|
||||
Some(_) => {
|
||||
tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span });
|
||||
tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() });
|
||||
}
|
||||
None => {
|
||||
// Unfortunately, unconditionally using `llvm.used` causes
|
||||
|
@ -223,7 +238,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
{
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
attr.span,
|
||||
attr.span(),
|
||||
E0737,
|
||||
"`#[track_caller]` requires Rust ABI"
|
||||
)
|
||||
|
@ -231,12 +246,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
if is_closure
|
||||
&& !tcx.features().closure_track_caller()
|
||||
&& !attr.span.allows_unstable(sym::closure_track_caller)
|
||||
&& !attr.span().allows_unstable(sym::closure_track_caller)
|
||||
{
|
||||
feature_err(
|
||||
&tcx.sess,
|
||||
sym::closure_track_caller,
|
||||
attr.span,
|
||||
attr.span(),
|
||||
"`#[track_caller]` on closures is currently unstable",
|
||||
)
|
||||
.emit();
|
||||
|
@ -250,19 +265,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
// so it may not contain any null characters.
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
attr.span,
|
||||
attr.span(),
|
||||
E0648,
|
||||
"`export_name` may not contain null characters"
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
codegen_fn_attrs.export_name = Some(s);
|
||||
mixed_export_name_no_mangle_lint_state.track_export_name(attr.span);
|
||||
mixed_export_name_no_mangle_lint_state.track_export_name(attr.span());
|
||||
}
|
||||
}
|
||||
sym::target_feature => {
|
||||
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
|
||||
tcx.dcx().span_delayed_bug(attr.span, "target_feature applied to non-fn");
|
||||
tcx.dcx().span_delayed_bug(attr.span(), "target_feature applied to non-fn");
|
||||
continue;
|
||||
};
|
||||
let safe_target_features =
|
||||
|
@ -292,7 +307,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
// `main`, `start`, and other functions that are not usually
|
||||
// allowed.
|
||||
} else {
|
||||
check_target_feature_trait_unsafe(tcx, did, attr.span);
|
||||
check_target_feature_trait_unsafe(tcx, did, attr.span());
|
||||
}
|
||||
}
|
||||
from_target_feature_attr(
|
||||
|
@ -310,7 +325,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
|
||||
if tcx.is_mutable_static(did.into()) {
|
||||
let mut diag = tcx.dcx().struct_span_err(
|
||||
attr.span,
|
||||
attr.span(),
|
||||
"extern mutable statics are not allowed with `#[linkage]`",
|
||||
);
|
||||
diag.note(
|
||||
|
@ -329,7 +344,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
if let Some(val) = attr.value_str() {
|
||||
if val.as_str().bytes().any(|b| b == 0) {
|
||||
let msg = format!("illegal null byte in link_section value: `{val}`");
|
||||
tcx.dcx().span_err(attr.span, msg);
|
||||
tcx.dcx().span_err(attr.span(), msg);
|
||||
} else {
|
||||
codegen_fn_attrs.link_section = Some(val);
|
||||
}
|
||||
|
@ -337,13 +352,13 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
sym::link_name => codegen_fn_attrs.link_name = attr.value_str(),
|
||||
sym::link_ordinal => {
|
||||
link_ordinal_span = Some(attr.span);
|
||||
link_ordinal_span = Some(attr.span());
|
||||
if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) {
|
||||
codegen_fn_attrs.link_ordinal = ordinal;
|
||||
}
|
||||
}
|
||||
sym::no_sanitize => {
|
||||
no_sanitize_span = Some(attr.span);
|
||||
no_sanitize_span = Some(attr.span());
|
||||
if let Some(list) = attr.meta_item_list() {
|
||||
for item in list.iter() {
|
||||
match item.name_or_empty() {
|
||||
|
@ -381,7 +396,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
{
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
attr.span,
|
||||
attr.span(),
|
||||
E0779,
|
||||
"target does not support `#[instruction_set]`"
|
||||
)
|
||||
|
@ -393,7 +408,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
_ => {
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
attr.span,
|
||||
attr.span(),
|
||||
E0779,
|
||||
"invalid instruction set specified",
|
||||
)
|
||||
|
@ -405,7 +420,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
[] => {
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
attr.span,
|
||||
attr.span(),
|
||||
E0778,
|
||||
"`#[instruction_set]` requires an argument"
|
||||
)
|
||||
|
@ -415,7 +430,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
_ => {
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
attr.span,
|
||||
attr.span(),
|
||||
E0779,
|
||||
"cannot specify more than one instruction set"
|
||||
)
|
||||
|
@ -424,27 +439,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
})
|
||||
}
|
||||
sym::repr => {
|
||||
codegen_fn_attrs.alignment = if let Some(items) = attr.meta_item_list()
|
||||
&& let [item] = items.as_slice()
|
||||
&& let Some((sym::align, literal)) = item.singleton_lit_list()
|
||||
{
|
||||
rustc_attr_parsing::parse_alignment(&literal.kind)
|
||||
.inspect_err(|msg| {
|
||||
struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
literal.span,
|
||||
E0589,
|
||||
"invalid `repr(align)` attribute: {}",
|
||||
msg
|
||||
)
|
||||
.emit();
|
||||
})
|
||||
.ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
sym::patchable_function_entry => {
|
||||
codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| {
|
||||
let mut prefix = None;
|
||||
|
@ -510,7 +504,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
|
||||
if let (None, None) = (prefix, entry) {
|
||||
tcx.dcx().span_err(attr.span, "must specify at least one parameter");
|
||||
tcx.dcx().span_err(attr.span(), "must specify at least one parameter");
|
||||
}
|
||||
|
||||
Some(PatchableFunctionEntry::from_prefix_and_entry(
|
||||
|
@ -536,18 +530,19 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
let Some(ref items) = attr.meta_item_list() else {
|
||||
return ia;
|
||||
};
|
||||
inline_span = Some(attr.span());
|
||||
|
||||
inline_span = Some(attr.span);
|
||||
let [item] = &items[..] else {
|
||||
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument").emit();
|
||||
struct_span_code_err!(tcx.dcx(), attr.span(), E0534, "expected one argument").emit();
|
||||
return InlineAttr::None;
|
||||
};
|
||||
|
||||
if item.has_name(sym::always) {
|
||||
InlineAttr::Always
|
||||
} else if item.has_name(sym::never) {
|
||||
InlineAttr::Never
|
||||
} else {
|
||||
struct_span_code_err!(tcx.dcx(), item.span(), E0535, "invalid argument")
|
||||
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
|
||||
.with_help("valid inline arguments are `always` and `never`")
|
||||
.emit();
|
||||
|
||||
|
@ -560,9 +555,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
|
||||
if attr.is_word() {
|
||||
InlineAttr::Force { attr_span: attr.span, reason: None }
|
||||
InlineAttr::Force { attr_span: attr.span(), reason: None }
|
||||
} else if let Some(val) = attr.value_str() {
|
||||
InlineAttr::Force { attr_span: attr.span, reason: Some(val) }
|
||||
InlineAttr::Force { attr_span: attr.span(), reason: Some(val) }
|
||||
} else {
|
||||
debug!("`rustc_force_inline` not checked by attribute validation");
|
||||
ia
|
||||
|
@ -582,16 +577,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
}
|
||||
let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit();
|
||||
if attr.is_word() {
|
||||
err(attr.span, "expected one argument");
|
||||
err(attr.span(), "expected one argument");
|
||||
return ia;
|
||||
}
|
||||
let Some(ref items) = attr.meta_item_list() else {
|
||||
return OptimizeAttr::Default;
|
||||
};
|
||||
|
||||
inline_span = Some(attr.span);
|
||||
inline_span = Some(attr.span());
|
||||
let [item] = &items[..] else {
|
||||
err(attr.span, "expected one argument");
|
||||
err(attr.span(), "expected one argument");
|
||||
return OptimizeAttr::Default;
|
||||
};
|
||||
if item.has_name(sym::size) {
|
||||
|
@ -703,7 +698,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
|
|||
let span = tcx
|
||||
.get_attrs(did, sym::target_feature)
|
||||
.next()
|
||||
.map_or_else(|| tcx.def_span(did), |a| a.span);
|
||||
.map_or_else(|| tcx.def_span(did), |a| a.span());
|
||||
tcx.dcx()
|
||||
.create_err(errors::TargetFeatureDisableOrEnable {
|
||||
features,
|
||||
|
@ -752,7 +747,7 @@ 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 [sole_meta_list] = &meta_item_list[..] else {
|
||||
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span });
|
||||
tcx.dcx().emit_err(errors::InvalidLinkOrdinalNargs { span: attr.span() });
|
||||
return None;
|
||||
};
|
||||
if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
|
||||
|
@ -776,13 +771,13 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &hir::Attribute) -> Option<u16> {
|
|||
} else {
|
||||
let msg = format!("ordinal value in `link_ordinal` is too large: `{ordinal}`");
|
||||
tcx.dcx()
|
||||
.struct_span_err(attr.span, msg)
|
||||
.struct_span_err(attr.span(), msg)
|
||||
.with_note("the value may not exceed `u16::MAX`")
|
||||
.emit();
|
||||
None
|
||||
}
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span });
|
||||
tcx.dcx().emit_err(errors::InvalidLinkOrdinalFormat { span: attr.span() });
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -828,7 +823,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
|
|||
export_name: Some(export_name),
|
||||
no_mangle: Some(no_mangle),
|
||||
hir_id: Some(hir_id),
|
||||
no_mangle_attr: Some(no_mangle_attr),
|
||||
no_mangle_attr: Some(_),
|
||||
} = self
|
||||
{
|
||||
tcx.emit_node_span_lint(
|
||||
|
@ -837,7 +832,7 @@ impl<'a> MixedExportNameAndNoMangleState<'a> {
|
|||
no_mangle,
|
||||
errors::MixedExportNameAndNoMangle {
|
||||
no_mangle,
|
||||
no_mangle_attr: rustc_hir_pretty::attribute_to_string(&tcx, no_mangle_attr),
|
||||
no_mangle_attr: "#[unsafe(no_mangle)]".to_string(),
|
||||
export_name,
|
||||
removal_span: no_mangle,
|
||||
},
|
||||
|
@ -869,7 +864,7 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
|||
_ => {
|
||||
//FIXME(ZuseZ4): Once we fixed our parser, we should also prohibit the two-attribute
|
||||
//branch above.
|
||||
span_bug!(attrs[1].span, "cg_ssa: rustc_autodiff should only exist once per source");
|
||||
span_bug!(attrs[1].span(), "cg_ssa: rustc_autodiff should only exist once per source");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -881,12 +876,12 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
|||
}
|
||||
|
||||
let [mode, input_activities @ .., ret_activity] = &list[..] else {
|
||||
span_bug!(attr.span, "rustc_autodiff attribute must contain mode and activities");
|
||||
span_bug!(attr.span(), "rustc_autodiff attribute must contain mode and activities");
|
||||
};
|
||||
let mode = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = mode {
|
||||
p1.segments.first().unwrap().ident
|
||||
} else {
|
||||
span_bug!(attr.span, "rustc_autodiff attribute must contain mode");
|
||||
span_bug!(attr.span(), "rustc_autodiff attribute must contain mode");
|
||||
};
|
||||
|
||||
// parse mode
|
||||
|
@ -902,7 +897,7 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
|||
let ret_symbol = if let MetaItemInner::MetaItem(MetaItem { path: p1, .. }) = ret_activity {
|
||||
p1.segments.first().unwrap().ident
|
||||
} else {
|
||||
span_bug!(attr.span, "rustc_autodiff attribute must contain the return activity");
|
||||
span_bug!(attr.span(), "rustc_autodiff attribute must contain the return activity");
|
||||
};
|
||||
|
||||
// Then parse it into an actual DiffActivity
|
||||
|
@ -937,11 +932,11 @@ fn autodiff_attrs(tcx: TyCtxt<'_>, id: DefId) -> Option<AutoDiffAttrs> {
|
|||
|
||||
for &input in &arg_activities {
|
||||
if !valid_input_activity(mode, input) {
|
||||
span_bug!(attr.span, "Invalid input activity {} for {} mode", input, mode);
|
||||
span_bug!(attr.span(), "Invalid input activity {} for {} mode", input, mode);
|
||||
}
|
||||
}
|
||||
if !valid_ret_activity(mode, ret_activity) {
|
||||
span_bug!(attr.span, "Invalid return activity {} for {} mode", ret_activity, mode);
|
||||
span_bug!(attr.span(), "Invalid return activity {} for {} mode", ret_activity, mode);
|
||||
}
|
||||
|
||||
Some(AutoDiffAttrs { mode, ret_activity, input_activity: arg_activities })
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue