Skip to content

Commit 5a5c6df

Browse files
committed
Fix misleading message when using a named constant as a struct alignment/pack
1 parent e612d07 commit 5a5c6df

File tree

8 files changed

+126
-22
lines changed

8 files changed

+126
-22
lines changed

compiler/rustc_attr/messages.ftl

+6
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,16 @@ attr_incorrect_meta_item =
2727
attr_incorrect_repr_format_align_one_arg =
2828
incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
2929
30+
attr_incorrect_repr_format_expect_literal_integer =
31+
incorrect `repr(align)` attribute format: `align` expect a literal integer as argument
32+
3033
attr_incorrect_repr_format_generic =
3134
incorrect `repr({$repr_arg})` attribute format
3235
.suggestion = use parentheses instead
3336
37+
attr_incorrect_repr_format_packed_expect_integer =
38+
incorrect `repr(packed)` attribute format: `packed` expect a literal integer as argument
39+
3440
attr_incorrect_repr_format_packed_one_or_zero_arg =
3541
incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
3642

compiler/rustc_attr/src/builtin.rs

+27-11
Original file line numberDiff line numberDiff line change
@@ -1039,21 +1039,37 @@ pub fn parse_repr_attr(sess: &Session, attr: &Attribute) -> Vec<ReprAttr> {
10391039
});
10401040
}
10411041
}
1042-
MetaItemKind::List(_) => {
1042+
MetaItemKind::List(nested_items) => {
10431043
if meta_item.has_name(sym::align) {
10441044
recognised = true;
1045-
sess.dcx().emit_err(
1046-
session_diagnostics::IncorrectReprFormatAlignOneArg {
1047-
span: meta_item.span,
1048-
},
1049-
);
1045+
if nested_items.len() == 1 {
1046+
sess.dcx().emit_err(
1047+
session_diagnostics::IncorrectReprFormatExpectInteger {
1048+
span: nested_items[0].span(),
1049+
},
1050+
);
1051+
} else {
1052+
sess.dcx().emit_err(
1053+
session_diagnostics::IncorrectReprFormatAlignOneArg {
1054+
span: meta_item.span,
1055+
},
1056+
);
1057+
}
10501058
} else if meta_item.has_name(sym::packed) {
10511059
recognised = true;
1052-
sess.dcx().emit_err(
1053-
session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
1054-
span: meta_item.span,
1055-
},
1056-
);
1060+
if nested_items.len() == 1 {
1061+
sess.dcx().emit_err(
1062+
session_diagnostics::IncorrectReprFormatPackedExpectInteger {
1063+
span: nested_items[0].span(),
1064+
},
1065+
);
1066+
} else {
1067+
sess.dcx().emit_err(
1068+
session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
1069+
span: meta_item.span,
1070+
},
1071+
);
1072+
}
10571073
} else if matches!(
10581074
meta_item.name_or_empty(),
10591075
sym::Rust | sym::C | sym::simd | sym::transparent

compiler/rustc_attr/src/session_diagnostics.rs

+13
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
170170
#[primary_span]
171171
pub span: Span,
172172
}
173+
#[derive(Diagnostic)]
174+
#[diag(attr_incorrect_repr_format_packed_expect_integer, code = E0552)]
175+
pub(crate) struct IncorrectReprFormatPackedExpectInteger {
176+
#[primary_span]
177+
pub span: Span,
178+
}
173179

174180
#[derive(Diagnostic)]
175181
#[diag(attr_invalid_repr_hint_no_paren, code = E0552)]
@@ -252,6 +258,13 @@ pub(crate) struct IncorrectReprFormatAlignOneArg {
252258
pub span: Span,
253259
}
254260

261+
#[derive(Diagnostic)]
262+
#[diag(attr_incorrect_repr_format_expect_literal_integer, code = E0693)]
263+
pub(crate) struct IncorrectReprFormatExpectInteger {
264+
#[primary_span]
265+
pub span: Span,
266+
}
267+
255268
#[derive(Diagnostic)]
256269
#[diag(attr_incorrect_repr_format_generic, code = E0693)]
257270
pub(crate) struct IncorrectReprFormatGeneric<'a> {

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
441441
.map_err(|msg| {
442442
struct_span_code_err!(
443443
tcx.dcx(),
444-
attr.span,
444+
literal.span,
445445
E0589,
446446
"invalid `repr(align)` attribute: {}",
447447
msg
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//@ compile-flags: -Zdeduplicate-diagnostics=yes
2+
3+
const N: usize = 8;
4+
#[repr(align(N))]
5+
//~^ ERROR: incorrect `repr(align)` attribute format
6+
struct T;
7+
8+
#[repr(align('a'))]
9+
//~^ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer [E0589]
10+
struct H;
11+
12+
#[repr(align("str"))]
13+
//~^ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer [E0589]
14+
struct L;
15+
16+
#[repr(align())]
17+
//~^ ERROR: attribute format: `align` takes exactly one argument in parentheses
18+
struct X;
19+
20+
const P: usize = 8;
21+
#[repr(packed(P))]
22+
//~^ ERROR: attribute format: `packed` expect a literal integer as argument
23+
struct A;
24+
25+
#[repr(packed())]
26+
//~^ ERROR: attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
27+
struct B;
28+
29+
#[repr(packed)]
30+
struct C;
31+
32+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
error[E0693]: incorrect `repr(align)` attribute format: `align` expect a literal integer as argument
2+
--> $DIR/arg-error-issue-121425.rs:4:14
3+
|
4+
LL | #[repr(align(N))]
5+
| ^
6+
7+
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
8+
--> $DIR/arg-error-issue-121425.rs:8:8
9+
|
10+
LL | #[repr(align('a'))]
11+
| ^^^^^^^^^^
12+
13+
error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer
14+
--> $DIR/arg-error-issue-121425.rs:12:8
15+
|
16+
LL | #[repr(align("str"))]
17+
| ^^^^^^^^^^^^
18+
19+
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
20+
--> $DIR/arg-error-issue-121425.rs:16:8
21+
|
22+
LL | #[repr(align())]
23+
| ^^^^^^^
24+
25+
error[E0552]: incorrect `repr(packed)` attribute format: `packed` expect a literal integer as argument
26+
--> $DIR/arg-error-issue-121425.rs:21:15
27+
|
28+
LL | #[repr(packed(P))]
29+
| ^
30+
31+
error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
32+
--> $DIR/arg-error-issue-121425.rs:25:8
33+
|
34+
LL | #[repr(packed())]
35+
| ^^^^^^^^
36+
37+
error: aborting due to 6 previous errors
38+
39+
Some errors have detailed explanations: E0552, E0589, E0693.
40+
For more information about an error, try `rustc --explain E0552`.

tests/ui/attributes/nonterminal-expansion.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
//@ compile-flags: -Zdeduplicate-diagnostics=yes
2+
13
// Macros were previously expanded in `Expr` nonterminal tokens, now they are not.
24

35
macro_rules! pass_nonterminal {
46
($n:expr) => {
57
#[repr(align($n))]
68
//~^ ERROR expected unsuffixed literal or identifier, found `n!()`
7-
//~| ERROR incorrect `repr(align)` attribute format
89
struct S;
910
};
1011
}
@@ -14,5 +15,6 @@ macro_rules! n {
1415
}
1516

1617
pass_nonterminal!(n!());
18+
//~^ ERROR incorrect `repr(align)` attribute format: `align` expect a literal integer as argument [E0693]
1719

1820
fn main() {}

tests/ui/attributes/nonterminal-expansion.stderr

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: expected unsuffixed literal or identifier, found `n!()`
2-
--> $DIR/nonterminal-expansion.rs:5:22
2+
--> $DIR/nonterminal-expansion.rs:7:22
33
|
44
LL | #[repr(align($n))]
55
| ^^
@@ -9,16 +9,11 @@ LL | pass_nonterminal!(n!());
99
|
1010
= note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
1111

12-
error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
13-
--> $DIR/nonterminal-expansion.rs:5:16
12+
error[E0693]: incorrect `repr(align)` attribute format: `align` expect a literal integer as argument
13+
--> $DIR/nonterminal-expansion.rs:17:19
1414
|
15-
LL | #[repr(align($n))]
16-
| ^^^^^^^^^
17-
...
1815
LL | pass_nonterminal!(n!());
19-
| ----------------------- in this macro invocation
20-
|
21-
= note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
| ^
2217

2318
error: aborting due to 2 previous errors
2419

0 commit comments

Comments
 (0)