Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
facc787
rustfmt: Discover modules via `cfg_select!`
mkroening Jun 24, 2026
28d994a
str: add ASCII fast path to word_to_titlecase
Rachit2323 Jul 14, 2026
ac53b43
add ligature test cases to word_to_titlecase
Rachit2323 Jul 14, 2026
905a7e0
Track placeholder assumptions for created universes
Dnreikronos Jul 16, 2026
8211f90
Add coverage for placeholder assumption ICE
Dnreikronos Jul 16, 2026
74c230e
ci: Enable autodiff tests on x86_64 linux
sgasho Jul 10, 2026
4ee71fe
docs: add autodiff CI job document
sgasho Jul 19, 2026
4e53ac1
Add allow_list checking for eii implementation attributes
chenyukang Jul 14, 2026
f68af89
rdg: Move Autodiff CI job below performance testing
sgasho Jul 21, 2026
2bb8a3b
Delete autodiff.sh and move the test command to the Dockerfile
sgasho Jul 21, 2026
7372202
Make some parser structured suggestions verbose
estebank Jul 21, 2026
1b7ae04
Tweak code and diagnostic formatting and messages
estebank Jul 21, 2026
6860c6b
Drop redundant canonical universe assumptions
Dnreikronos Jul 22, 2026
5871216
std: Implement futex on wasip3 targets, update target spec
alexcrichton Jul 22, 2026
0eb2348
Keep cfg predicate in `CfgAttrTrace` so it can be used by rustdoc
GuillaumeGomez Jul 22, 2026
9d0c58d
Retrieve `cfg_attr` information for derived impls for rustdoc `doc_cf…
GuillaumeGomez Jul 22, 2026
35c57b5
Add regression test for `doc_cfg` feature on derive impl blocks
GuillaumeGomez Jul 22, 2026
ed30e03
Update `AttributeKind::CfgAttrTrace` variant usage in `clippy`
GuillaumeGomez Jul 22, 2026
b1342c9
constify vec![1, 2, 3] macro arm functions
Lars-Schumann Jul 22, 2026
7f88868
Extend `cfg_attr` retrieval for all impls, including ones without the…
GuillaumeGomez Jul 22, 2026
f9d9939
make `DocLinkResMap` an `FxIndexMap`
jprochazk Jul 22, 2026
5c012f5
Promote riscv64-unknown-linux-musl to tier 2 with host tools
eshattow May 28, 2026
3086aff
don't build riscv64gc-unknown-linux-musl twice
marcoieni Jul 21, 2026
2af4af2
update download-ci-llvm-stamp
marcoieni Jul 23, 2026
219d6bb
Filter derive impls earlier on
GuillaumeGomez Jul 23, 2026
7e294a5
Fix `tests/ui/rust-2018/removing-extern-crate-malformed-cfg.rs` test
GuillaumeGomez Jul 23, 2026
220fbca
Avoid spurious rebuilds of JSON docs in bootstrap
Kobzol Jul 23, 2026
fe37a8a
Update bootstrap to use -Zembed-metadata=no instead of -Zno-embed-met…
dpaoliello Jul 23, 2026
2e2cdf9
Improve consistency of attribute stability error messages
nnethercote Jul 22, 2026
35b1187
Improve consistency of `InvalidTarget` attribute error messages
nnethercote Jul 22, 2026
d36d39f
Improve consistency of some `cfg_attr` attribute error messages
nnethercote Jul 22, 2026
c4621dd
Improve consistency of "malformed `foo` attribute input" error messages
nnethercote Jul 22, 2026
cd8a779
Mention attributes in the diagnostic output style guide
nnethercote Jul 23, 2026
9f2b657
Rollup merge of #159765 - Kobzol:bootstrap-docs-json-rebuild, r=Mark-…
jhpratt Jul 24, 2026
5e46148
Rollup merge of #159781 - dpaoliello:noembed, r=Kobzol
jhpratt Jul 24, 2026
9da519c
Rollup merge of #158362 - Dnreikronos:trait_solver/placeholder_univer…
jhpratt Jul 24, 2026
7a183d7
Rollup merge of #158372 - mkroening:rustfmt-cfg_select-modules, r=ytm…
jhpratt Jul 24, 2026
1b39801
Rollup merge of #159173 - chenyukang:yukang-fix-159015-no-mangle-eii,…
jhpratt Jul 24, 2026
d98e01e
Rollup merge of #159718 - jprochazk:doc-link-res-index-map, r=petroch…
jhpratt Jul 24, 2026
7a2710b
Rollup merge of #159722 - GuillaumeGomez:cfg_attr-doc_cfg, r=petroche…
jhpratt Jul 24, 2026
5c3196f
Rollup merge of #159731 - alexcrichton:wasip3-futex, r=clarfonthey
jhpratt Jul 24, 2026
59906a3
Rollup merge of #159755 - nnethercote:attribute-error-messages, r=est…
jhpratt Jul 24, 2026
649cfef
Rollup merge of #155795 - Lars-Schumann:const-vec-macro, r=oli-obk
jhpratt Jul 24, 2026
ab994ae
Rollup merge of #157776 - sgasho:linux_autodiff_tests_ci, r=ZuseZ4
jhpratt Jul 24, 2026
f907604
Rollup merge of #158766 - eshattow:linux-musl-riscv64-ci, r=marcoieni
jhpratt Jul 24, 2026
af4cac9
Rollup merge of #159271 - Rachit2323:fix-titlecase-ascii-fastpath, r=…
jhpratt Jul 24, 2026
625d5f9
Rollup merge of #159667 - estebank:verbose-parse-suggestions, r=TaKO8Ki
jhpratt Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3514,7 +3514,7 @@ pub enum SyntheticAttr {
/// because they are not needed.
///
/// The attribute is used by some clippy lints.
CfgAttrTrace,
CfgAttrTrace(CfgEntry),
}

impl AttrItem {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl AttributeExt for Attribute {
use SyntheticAttr::*;
match &self.kind {
AttrKind::Normal(normal) => normal.item.name(),
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => None,
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => None,
AttrKind::DocComment(..) => None,
}
}
Expand All @@ -117,7 +117,7 @@ impl AttributeExt for Attribute {
AttrKind::Normal(normal) => {
Some(normal.item.path.segments.iter().map(|i| i.ident.name).collect())
}
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => None,
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => None,
AttrKind::DocComment(_, _) => None,
}
}
Expand Down
48 changes: 46 additions & 2 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ impl<'a> AstValidator<'a> {
[sym::allow, sym::deny, sym::expect, sym::forbid, sym::splat, sym::warn];
!attr.has_any_name(&arr) && rustc_attr_parsing::is_builtin_attr(&normal.item)
}
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => false,
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => false,
AttrKind::DocComment(..) => true,
})
.for_each(|attr| {
Expand Down Expand Up @@ -1202,6 +1202,48 @@ impl<'a> AstValidator<'a> {
self.visit_vis(vis);
self.visit_ident(ident);
}

// Check EII implementation attributes against an allowlist.
fn check_eii_impl_attrs(&self, attrs: &[Attribute], eii_impls: &[EiiImpl]) {
if eii_impls.is_empty() {
return;
}

let allowed_attrs: &[Symbol] = &[
sym::allow,
sym::warn,
sym::deny,
sym::forbid,
sym::expect,
sym::doc,
sym::inline,
sym::cold,
sym::optimize,
sym::coverage,
sym::sanitize,
sym::must_use,
sym::deprecated,
];

for attr in attrs {
let AttrKind::Normal(normal) = &attr.kind else {
continue;
};
if attr.has_any_name(allowed_attrs) {
continue;
}

let attr_name = pprust::path_to_string(&normal.item.path);
for eii_impl in eii_impls {
self.dcx().emit_err(diagnostics::EiiImplAttributeNotSupported {
attr_span: attr.span,
attr_name: &attr_name,
eii_span: eii_impl.span,
eii_name: pprust::path_to_string(&eii_impl.eii_macro_path),
});
}
}
}
}

/// Checks that generic parameters are in the correct order,
Expand Down Expand Up @@ -1391,6 +1433,7 @@ impl Visitor<'_> for AstValidator<'_> {
for EiiImpl { eii_macro_path, .. } in eii_impls {
self.visit_path(eii_macro_path);
}
self.check_eii_impl_attrs(&item.attrs, eii_impls);

let is_intrinsic = item.attrs.iter().any(|a| a.has_name(sym::rustc_intrinsic));
if body.is_none() && !is_intrinsic && !self.is_sdylib_interface {
Expand Down Expand Up @@ -1566,8 +1609,9 @@ impl Visitor<'_> for AstValidator<'_> {

visit::walk_item(self, item);
}
ItemKind::Static(StaticItem { expr, safety, .. }) => {
ItemKind::Static(StaticItem { expr, safety, eii_impls, .. }) => {
self.check_item_safety(item.span, *safety);
self.check_eii_impl_attrs(&item.attrs, eii_impls);
if matches!(safety, Safety::Unsafe(_)) {
self.dcx().emit_err(diagnostics::UnsafeStatic { span: item.span });
}
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_ast_passes/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,17 @@ pub(crate) struct FnParamForbiddenAttr {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag("`#[{$eii_name}]` is not allowed to have `#[{$attr_name}]`")]
pub(crate) struct EiiImplAttributeNotSupported<'a> {
#[primary_span]
pub attr_span: Span,
pub attr_name: &'a str,
pub eii_name: String,
#[label("`#[{$eii_name}]` is not allowed to have `#[{$attr_name}]`")]
pub eii_span: Span,
}

#[derive(Diagnostic)]
#[diag("`self` parameter is only allowed in associated functions")]
#[note("associated functions are those in `impl` or `trait` definitions")]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_pretty/src/pprust/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) -> bool {
use ast::SyntheticAttr::*;
match attr.kind {
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace) => {
AttrKind::Synthetic(CfgTrace(_) | CfgAttrTrace(_)) => {
// These are internal synthetic attributes with no syntax, so avoid printing them
// to keep the printed code reasonably parse-able.
return false;
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_attr_parsing/src/attributes/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,12 +353,13 @@ pub fn parse_cfg_attr(
{
(dspan.entire(), AttributeParseErrorReason::ExpectedAtLeastOneArgument)
} else {
(cfg_attr.span, AttributeParseErrorReason::ExpectedList)
(cfg_attr.get_normal_item().span, AttributeParseErrorReason::ExpectedList)
};

sess.dcx().emit_err(AttributeParseError {
span,
attr_span: cfg_attr.span,
inner_span: cfg_attr.get_normal_item().span,
template: CFG_ATTR_TEMPLATE,
path: AttrPath::from_ast(&cfg_attr.get_normal_item().path, identity),
description: ParsedDescription::Attribute,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl SingleAttributeParser for PatternComplexityLimitParser {
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[pattern_complexity_limit]` attribute is used for rustc unit tests"
"the `pattern_complexity_limit` attribute is used for rustc unit tests"
);

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl AttributeParser for OnUnimplementedParser {
template!(List: &[r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#]),
unstable!(
rustc_attrs,
"see `#[diagnostic::on_unimplemented]` for the stable equivalent of this attribute"
"see the `diagnostic::on_unimplemented` attribute for the stable equivalent of this attribute"
),
|this, cx, args| {
this.parse(cx, args, Mode::RustcOnUnimplemented);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_attr_parsing/src/attributes/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl SingleAttributeParser for RustcDummyParser {
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::ManuallyChecked;
const TEMPLATE: AttributeTemplate = template!(Word); // Anything, really
const STABILITY: AttributeStability =
unstable!(rustc_attrs, "the `#[rustc_dummy]` attribute is used for rustc unit tests");
unstable!(rustc_attrs, "the `rustc_dummy` attribute is used for rustc unit tests");

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
args.ignore_args();
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_attr_parsing/src/attributes/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ impl SingleAttributeParser for RustcForceInlineParser {
Allow(Target::Fn),
Allow(Target::Method(MethodKind::Inherent)),
]);
const STABILITY: AttributeStability =
unstable!(rustc_attrs, "`#[rustc_force_inline]` forces a free function to be inlined");
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `rustc_force_inline` attribute forces a free function to be inlined"
);
const TEMPLATE: AttributeTemplate = template!(Word, List: &["reason"], NameValueStr: "reason");

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,8 @@ impl NoArgsAttributeParser for RustcDumpVariancesParser {
Allow(Target::Struct),
Allow(Target::Union),
]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_dump_variances]` attribute is used for rustc unit tests"
);
const STABILITY: AttributeStability =
unstable!(rustc_attrs, "the `rustc_dump_variances` attribute is used for rustc unit tests");
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariances;
}

Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl NoArgsAttributeParser for RustcMainParser {
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_main]` attribute is used internally to specify test entry point function"
"the `rustc_main` attribute is used internally to specify test entry point function"
);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain;
}
Expand All @@ -36,7 +36,7 @@ impl SingleAttributeParser for RustcMustImplementOneOfParser {
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Trait)]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete definition of a trait. Its syntax and semantics are highly experimental and will be subject to change before stabilization"
"the `rustc_must_implement_one_of` attribute is used to change minimal complete definition of a trait. Its syntax and semantics are highly experimental and will be subject to change before stabilization"
);
const TEMPLATE: AttributeTemplate = template!(List: &["function1, function2, ..."]);
fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
Expand Down Expand Up @@ -734,7 +734,7 @@ impl NoArgsAttributeParser for RustcNonConstTraitMethodParser {
]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"`#[rustc_non_const_trait_method]` should only used by the standard library to mark trait methods as non-const to allow large traits an easier transition to const"
"the `rustc_non_const_trait_method` attribute should only be used by the standard library to mark trait methods as non-const to allow large traits an easier transition to const"
);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod;
}
Expand Down Expand Up @@ -1018,7 +1018,7 @@ impl SingleAttributeParser for RustcDiagnosticItemParser {
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_diagnostic_item]` attribute allows the compiler to reference types from the standard library for diagnostic purposes"
"the `rustc_diagnostic_item` attribute allows the compiler to reference types from the standard library for diagnostic purposes"
);

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
Expand All @@ -1041,7 +1041,7 @@ impl NoArgsAttributeParser for RustcDoNotConstCheckParser {
]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"`#[rustc_do_not_const_check]` skips const-check for this function's body"
"the `rustc_do_not_const_check` attribute skips const-check for this function's body"
);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDoNotConstCheck;
}
Expand All @@ -1053,7 +1053,7 @@ impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser {
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in the standard library",
"the `rustc_nonnull_optimization_guaranteed` attribute is just used to document guaranteed niche optimizations in the standard library",
"the compiler does not even check whether the type indeed is being non-null-optimized; it is your responsibility to ensure that the attribute is only used on types that are optimized"
);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed;
Expand Down Expand Up @@ -1108,7 +1108,7 @@ impl SingleAttributeParser for RustcDocPrimitiveParser {
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "primitive name");
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_doc_primitive]` attribute is used by the standard library to provide a way to generate documentation for primitive types"
"the `rustc_doc_primitive` attribute is used by the standard library to provide a way to generate documentation for primitive types"
);

fn convert(cx: &mut AcceptContext<'_, '_>, args: &ArgParser) -> Option<AttributeKind> {
Expand Down Expand Up @@ -1154,7 +1154,7 @@ impl NoArgsAttributeParser for RustcCanonicalSymbolParser {
AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
const STABILITY: AttributeStability = unstable!(
rustc_attrs,
"the `#[rustc_canonical_symbol]` attribute registers a function's symbol to be linted against \
"the `rustc_canonical_symbol` attribute registers a function's symbol to be linted against \
by the `invalid_runtime_symbol_definitions` and `suspicious_runtime_symbol_definitions` \
lints"
);
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_attr_parsing/src/attributes/splat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub(crate) struct SplatParser;
impl NoArgsAttributeParser for SplatParser {
const PATH: &[Symbol] = &[sym::splat];
const ALLOWED_TARGETS: AllowedTargets<'_> = AllowedTargets::AllowList(&[Allow(Target::Param)]);
const STABILITY: AttributeStability =
unstable!(splat, "the `#[splat]` attribute is experimental");
const STABILITY: AttributeStability = unstable!(splat, "the `splat` attribute is experimental");
const CREATE: fn(Span) -> AttributeKind = AttributeKind::Splat;
}
9 changes: 8 additions & 1 deletion compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ pub(crate) struct AttributeDiagnosticContext<'a, 'f, 'sess> {
impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {
fn emit_parse_error(
&mut self,
span: Span,
mut span: Span,
reason: AttributeParseErrorReason<'_>,
) -> ErrorGuaranteed {
let suggestions = if self.custom_suggestions.is_empty() {
Expand All @@ -925,9 +925,16 @@ impl<'a, 'f, 'sess: 'f> AttributeDiagnosticContext<'a, 'f, 'sess> {
AttributeParseErrorSuggestions::CreatedByParser(mem::take(&mut self.custom_suggestions))
};

// If the span is the full attribute (including the `#[`/`]` delimiters) shrink it to
// exclude those delimiters, because that's what we want in error messages.
if span == self.attr_span {
span = self.inner_span;
}

self.emit_err(AttributeParseError {
span,
attr_span: self.attr_span,
inner_span: self.inner_span,
template: *self.template,
path: self.attr_path.clone(),
description: self.parsed_description,
Expand Down
15 changes: 9 additions & 6 deletions compiler/rustc_attr_parsing/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,18 @@ pub(crate) struct EmptyConfusables {
}

#[derive(Diagnostic)]
#[help("`#[{$name}{$attribute_args}]` can {$only}be applied to {$applied}")]
#[diag("`#[{$name}{$attribute_args}]` attribute cannot be used on {$target}")]
#[help("the `{$name}{$attribute_args}` attribute can {$only}be applied to {$applied}")]
#[diag("the `{$name}{$attribute_args}` attribute cannot be used on {$target}")]
pub(crate) struct InvalidTarget {
#[primary_span]
pub span: Span,
#[suggestion(
"remove the attribute",
code = "",
applicability = "machine-applicable",
style = "tool-only"
)]
pub span: Span,
pub attr_span: Span,
pub name: AttrPath,
pub target: &'static str,
pub applied: DiagArgValue,
Expand Down Expand Up @@ -509,6 +510,7 @@ pub enum ParsedDescription {
pub(crate) struct AttributeParseError<'a> {
pub(crate) span: Span,
pub(crate) attr_span: Span,
pub(crate) inner_span: Span,
pub(crate) template: AttributeTemplate,
pub(crate) path: AttrPath,
pub(crate) description: ParsedDescription,
Expand Down Expand Up @@ -652,7 +654,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
let description = self.description();

let mut diag = Diag::new(dcx, level, format!("malformed `{name}` {description} input"));
diag.span(self.attr_span);
diag.span(self.inner_span);
diag.code(E0539);
match &self.reason {
AttributeParseErrorReason::ExpectedStringLiteral { byte_string } => {
Expand Down Expand Up @@ -727,8 +729,9 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
diag.code(E0565);
}
AttributeParseErrorReason::ExpectedNameValue(None) => {
// If the span is the entire attribute, the suggestion we add below this match already contains enough information
if self.span != self.attr_span {
// If the span is the entire attribute inner, the suggestion we add below this
// match already contains enough information.
if self.span != self.inner_span {
diag.span_label(self.span, "expected this to be of the form `... = \"...\"`");
}
}
Expand Down
Loading
Loading