From 5a5c6dfb33ec9f17416ac96ca66554a033ecd387 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 2 Mar 2024 22:42:13 +0800 Subject: [PATCH 1/2] Fix misleading message when using a named constant as a struct alignment/pack --- compiler/rustc_attr/messages.ftl | 6 +++ compiler/rustc_attr/src/builtin.rs | 38 +++++++++++++----- .../rustc_attr/src/session_diagnostics.rs | 13 ++++++ .../rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- tests/ui/attributes/arg-error-issue-121425.rs | 32 +++++++++++++++ .../attributes/arg-error-issue-121425.stderr | 40 +++++++++++++++++++ tests/ui/attributes/nonterminal-expansion.rs | 4 +- .../attributes/nonterminal-expansion.stderr | 13 ++---- 8 files changed, 126 insertions(+), 22 deletions(-) create mode 100644 tests/ui/attributes/arg-error-issue-121425.rs create mode 100644 tests/ui/attributes/arg-error-issue-121425.stderr diff --git a/compiler/rustc_attr/messages.ftl b/compiler/rustc_attr/messages.ftl index 7281282fec3..9c01e6a9d2c 100644 --- a/compiler/rustc_attr/messages.ftl +++ b/compiler/rustc_attr/messages.ftl @@ -27,10 +27,16 @@ attr_incorrect_meta_item = attr_incorrect_repr_format_align_one_arg = incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses +attr_incorrect_repr_format_expect_literal_integer = + incorrect `repr(align)` attribute format: `align` expect a literal integer as argument + attr_incorrect_repr_format_generic = incorrect `repr({$repr_arg})` attribute format .suggestion = use parentheses instead +attr_incorrect_repr_format_packed_expect_integer = + incorrect `repr(packed)` attribute format: `packed` expect a literal integer as argument + attr_incorrect_repr_format_packed_one_or_zero_arg = incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index f414ff746bb..6b6eefc64f8 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -1039,21 +1039,37 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { }); } } - MetaItemKind::List(_) => { + MetaItemKind::List(nested_items) => { if meta_item.has_name(sym::align) { recognised = true; - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatAlignOneArg { - span: meta_item.span, - }, - ); + if nested_items.len() == 1 { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatExpectInteger { + span: nested_items[0].span(), + }, + ); + } else { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatAlignOneArg { + span: meta_item.span, + }, + ); + } } else if meta_item.has_name(sym::packed) { recognised = true; - sess.dcx().emit_err( - session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { - span: meta_item.span, - }, - ); + if nested_items.len() == 1 { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatPackedExpectInteger { + span: nested_items[0].span(), + }, + ); + } else { + sess.dcx().emit_err( + session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg { + span: meta_item.span, + }, + ); + } } else if matches!( meta_item.name_or_empty(), sym::Rust | sym::C | sym::simd | sym::transparent diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 8cbd401d300..f489cc87bc7 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -170,6 +170,12 @@ pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg { #[primary_span] pub span: Span, } +#[derive(Diagnostic)] +#[diag(attr_incorrect_repr_format_packed_expect_integer, code = E0552)] +pub(crate) struct IncorrectReprFormatPackedExpectInteger { + #[primary_span] + pub span: Span, +} #[derive(Diagnostic)] #[diag(attr_invalid_repr_hint_no_paren, code = E0552)] @@ -252,6 +258,13 @@ pub(crate) struct IncorrectReprFormatAlignOneArg { pub span: Span, } +#[derive(Diagnostic)] +#[diag(attr_incorrect_repr_format_expect_literal_integer, code = E0693)] +pub(crate) struct IncorrectReprFormatExpectInteger { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(attr_incorrect_repr_format_generic, code = E0693)] pub(crate) struct IncorrectReprFormatGeneric<'a> { diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 9e23757fcee..9c9e134f033 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -441,7 +441,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { .map_err(|msg| { struct_span_code_err!( tcx.dcx(), - attr.span, + literal.span, E0589, "invalid `repr(align)` attribute: {}", msg diff --git a/tests/ui/attributes/arg-error-issue-121425.rs b/tests/ui/attributes/arg-error-issue-121425.rs new file mode 100644 index 00000000000..47b85fa1400 --- /dev/null +++ b/tests/ui/attributes/arg-error-issue-121425.rs @@ -0,0 +1,32 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes + +const N: usize = 8; +#[repr(align(N))] +//~^ ERROR: incorrect `repr(align)` attribute format +struct T; + +#[repr(align('a'))] +//~^ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer [E0589] +struct H; + +#[repr(align("str"))] +//~^ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer [E0589] +struct L; + +#[repr(align())] +//~^ ERROR: attribute format: `align` takes exactly one argument in parentheses +struct X; + +const P: usize = 8; +#[repr(packed(P))] +//~^ ERROR: attribute format: `packed` expect a literal integer as argument +struct A; + +#[repr(packed())] +//~^ ERROR: attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all +struct B; + +#[repr(packed)] +struct C; + +fn main() {} diff --git a/tests/ui/attributes/arg-error-issue-121425.stderr b/tests/ui/attributes/arg-error-issue-121425.stderr new file mode 100644 index 00000000000..10f3f3c0b8f --- /dev/null +++ b/tests/ui/attributes/arg-error-issue-121425.stderr @@ -0,0 +1,40 @@ +error[E0693]: incorrect `repr(align)` attribute format: `align` expect a literal integer as argument + --> $DIR/arg-error-issue-121425.rs:4:14 + | +LL | #[repr(align(N))] + | ^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/arg-error-issue-121425.rs:8:8 + | +LL | #[repr(align('a'))] + | ^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/arg-error-issue-121425.rs:12:8 + | +LL | #[repr(align("str"))] + | ^^^^^^^^^^^^ + +error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + --> $DIR/arg-error-issue-121425.rs:16:8 + | +LL | #[repr(align())] + | ^^^^^^^ + +error[E0552]: incorrect `repr(packed)` attribute format: `packed` expect a literal integer as argument + --> $DIR/arg-error-issue-121425.rs:21:15 + | +LL | #[repr(packed(P))] + | ^ + +error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all + --> $DIR/arg-error-issue-121425.rs:25:8 + | +LL | #[repr(packed())] + | ^^^^^^^^ + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0552, E0589, E0693. +For more information about an error, try `rustc --explain E0552`. diff --git a/tests/ui/attributes/nonterminal-expansion.rs b/tests/ui/attributes/nonterminal-expansion.rs index 97bf225f0cc..decf3ec8185 100644 --- a/tests/ui/attributes/nonterminal-expansion.rs +++ b/tests/ui/attributes/nonterminal-expansion.rs @@ -1,10 +1,11 @@ +//@ compile-flags: -Zdeduplicate-diagnostics=yes + // Macros were previously expanded in `Expr` nonterminal tokens, now they are not. macro_rules! pass_nonterminal { ($n:expr) => { #[repr(align($n))] //~^ ERROR expected unsuffixed literal or identifier, found `n!()` - //~| ERROR incorrect `repr(align)` attribute format struct S; }; } @@ -14,5 +15,6 @@ macro_rules! n { } pass_nonterminal!(n!()); +//~^ ERROR incorrect `repr(align)` attribute format: `align` expect a literal integer as argument [E0693] fn main() {} diff --git a/tests/ui/attributes/nonterminal-expansion.stderr b/tests/ui/attributes/nonterminal-expansion.stderr index 52376ac1911..4d995eee5ac 100644 --- a/tests/ui/attributes/nonterminal-expansion.stderr +++ b/tests/ui/attributes/nonterminal-expansion.stderr @@ -1,5 +1,5 @@ error: expected unsuffixed literal or identifier, found `n!()` - --> $DIR/nonterminal-expansion.rs:5:22 + --> $DIR/nonterminal-expansion.rs:7:22 | LL | #[repr(align($n))] | ^^ @@ -9,16 +9,11 @@ LL | pass_nonterminal!(n!()); | = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses - --> $DIR/nonterminal-expansion.rs:5:16 +error[E0693]: incorrect `repr(align)` attribute format: `align` expect a literal integer as argument + --> $DIR/nonterminal-expansion.rs:17:19 | -LL | #[repr(align($n))] - | ^^^^^^^^^ -... LL | pass_nonterminal!(n!()); - | ----------------------- in this macro invocation - | - = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info) + | ^ error: aborting due to 2 previous errors From 53dba7fb5546f5a0d450bbef6995a2d5425e72e5 Mon Sep 17 00:00:00 2001 From: yukang Date: Sat, 2 Mar 2024 23:18:06 +0800 Subject: [PATCH 2/2] fix spans of arguments in diagnostic --- compiler/rustc_attr/messages.ftl | 4 +- compiler/rustc_attr/src/builtin.rs | 13 +++-- tests/ui/attributes/arg-error-issue-121425.rs | 2 +- .../attributes/arg-error-issue-121425.stderr | 12 ++--- tests/ui/attributes/nonterminal-expansion.rs | 2 +- .../attributes/nonterminal-expansion.stderr | 2 +- tests/ui/repr/repr-align.stderr | 48 +++++++++---------- 7 files changed, 45 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_attr/messages.ftl b/compiler/rustc_attr/messages.ftl index 9c01e6a9d2c..eb51e568f81 100644 --- a/compiler/rustc_attr/messages.ftl +++ b/compiler/rustc_attr/messages.ftl @@ -28,14 +28,14 @@ attr_incorrect_repr_format_align_one_arg = incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses attr_incorrect_repr_format_expect_literal_integer = - incorrect `repr(align)` attribute format: `align` expect a literal integer as argument + incorrect `repr(align)` attribute format: `align` expects a literal integer as argument attr_incorrect_repr_format_generic = incorrect `repr({$repr_arg})` attribute format .suggestion = use parentheses instead attr_incorrect_repr_format_packed_expect_integer = - incorrect `repr(packed)` attribute format: `packed` expect a literal integer as argument + incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument attr_incorrect_repr_format_packed_one_or_zero_arg = incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 6b6eefc64f8..3d2cf25e98b 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -984,17 +984,24 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { } } else if let Some((name, value)) = item.name_value_literal() { let mut literal_error = None; + let mut err_span = item.span(); if name == sym::align { recognised = true; match parse_alignment(&value.kind) { Ok(literal) => acc.push(ReprAlign(literal)), - Err(message) => literal_error = Some(message), + Err(message) => { + err_span = value.span; + literal_error = Some(message) + } }; } else if name == sym::packed { recognised = true; match parse_alignment(&value.kind) { Ok(literal) => acc.push(ReprPacked(literal)), - Err(message) => literal_error = Some(message), + Err(message) => { + err_span = value.span; + literal_error = Some(message) + } }; } else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent) || int_type_of_word(name).is_some() @@ -1007,7 +1014,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec { } if let Some(literal_error) = literal_error { sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric { - span: item.span(), + span: err_span, repr_arg: name.to_ident_string(), error_part: literal_error, }); diff --git a/tests/ui/attributes/arg-error-issue-121425.rs b/tests/ui/attributes/arg-error-issue-121425.rs index 47b85fa1400..c15b276ad4e 100644 --- a/tests/ui/attributes/arg-error-issue-121425.rs +++ b/tests/ui/attributes/arg-error-issue-121425.rs @@ -19,7 +19,7 @@ struct X; const P: usize = 8; #[repr(packed(P))] -//~^ ERROR: attribute format: `packed` expect a literal integer as argument +//~^ ERROR: attribute format: `packed` expects a literal integer as argument struct A; #[repr(packed())] diff --git a/tests/ui/attributes/arg-error-issue-121425.stderr b/tests/ui/attributes/arg-error-issue-121425.stderr index 10f3f3c0b8f..1beb99b1703 100644 --- a/tests/ui/attributes/arg-error-issue-121425.stderr +++ b/tests/ui/attributes/arg-error-issue-121425.stderr @@ -1,20 +1,20 @@ -error[E0693]: incorrect `repr(align)` attribute format: `align` expect a literal integer as argument +error[E0693]: incorrect `repr(align)` attribute format: `align` expects a literal integer as argument --> $DIR/arg-error-issue-121425.rs:4:14 | LL | #[repr(align(N))] | ^ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/arg-error-issue-121425.rs:8:8 + --> $DIR/arg-error-issue-121425.rs:8:14 | LL | #[repr(align('a'))] - | ^^^^^^^^^^ + | ^^^ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/arg-error-issue-121425.rs:12:8 + --> $DIR/arg-error-issue-121425.rs:12:14 | LL | #[repr(align("str"))] - | ^^^^^^^^^^^^ + | ^^^^^ error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses --> $DIR/arg-error-issue-121425.rs:16:8 @@ -22,7 +22,7 @@ error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly on LL | #[repr(align())] | ^^^^^^^ -error[E0552]: incorrect `repr(packed)` attribute format: `packed` expect a literal integer as argument +error[E0552]: incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument --> $DIR/arg-error-issue-121425.rs:21:15 | LL | #[repr(packed(P))] diff --git a/tests/ui/attributes/nonterminal-expansion.rs b/tests/ui/attributes/nonterminal-expansion.rs index decf3ec8185..6db7aea0745 100644 --- a/tests/ui/attributes/nonterminal-expansion.rs +++ b/tests/ui/attributes/nonterminal-expansion.rs @@ -15,6 +15,6 @@ macro_rules! n { } pass_nonterminal!(n!()); -//~^ ERROR incorrect `repr(align)` attribute format: `align` expect a literal integer as argument [E0693] +//~^ ERROR incorrect `repr(align)` attribute format: `align` expects a literal integer as argument [E0693] fn main() {} diff --git a/tests/ui/attributes/nonterminal-expansion.stderr b/tests/ui/attributes/nonterminal-expansion.stderr index 4d995eee5ac..78541495b32 100644 --- a/tests/ui/attributes/nonterminal-expansion.stderr +++ b/tests/ui/attributes/nonterminal-expansion.stderr @@ -9,7 +9,7 @@ LL | pass_nonterminal!(n!()); | = note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0693]: incorrect `repr(align)` attribute format: `align` expect a literal integer as argument +error[E0693]: incorrect `repr(align)` attribute format: `align` expects a literal integer as argument --> $DIR/nonterminal-expansion.rs:17:19 | LL | pass_nonterminal!(n!()); diff --git a/tests/ui/repr/repr-align.stderr b/tests/ui/repr/repr-align.stderr index 84d33a08a6f..bb0e17ba395 100644 --- a/tests/ui/repr/repr-align.stderr +++ b/tests/ui/repr/repr-align.stderr @@ -1,84 +1,84 @@ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/repr-align.rs:3:8 + --> $DIR/repr-align.rs:3:14 | LL | #[repr(align(16.0))] - | ^^^^^^^^^^^ + | ^^^^ error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/repr-align.rs:7:8 + --> $DIR/repr-align.rs:7:14 | LL | #[repr(align(15))] - | ^^^^^^^^^ + | ^^ error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:11:8 + --> $DIR/repr-align.rs:11:14 | LL | #[repr(align(4294967296))] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/repr-align.rs:18:8 + --> $DIR/repr-align.rs:18:14 | LL | #[repr(align(16.0))] - | ^^^^^^^^^^^ + | ^^^^ error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/repr-align.rs:22:8 + --> $DIR/repr-align.rs:22:14 | LL | #[repr(align(15))] - | ^^^^^^^^^ + | ^^ error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:26:8 + --> $DIR/repr-align.rs:26:14 | LL | #[repr(align(4294967296))] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/repr-align.rs:3:8 + --> $DIR/repr-align.rs:3:14 | LL | #[repr(align(16.0))] - | ^^^^^^^^^^^ + | ^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/repr-align.rs:7:8 + --> $DIR/repr-align.rs:7:14 | LL | #[repr(align(15))] - | ^^^^^^^^^ + | ^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:11:8 + --> $DIR/repr-align.rs:11:14 | LL | #[repr(align(4294967296))] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer - --> $DIR/repr-align.rs:18:8 + --> $DIR/repr-align.rs:18:14 | LL | #[repr(align(16.0))] - | ^^^^^^^^^^^ + | ^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: not a power of two - --> $DIR/repr-align.rs:22:8 + --> $DIR/repr-align.rs:22:14 | LL | #[repr(align(15))] - | ^^^^^^^^^ + | ^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0589]: invalid `repr(align)` attribute: larger than 2^29 - --> $DIR/repr-align.rs:26:8 + --> $DIR/repr-align.rs:26:14 | LL | #[repr(align(4294967296))] - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^ | = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`