Skip to content

Commit e6b237a

Browse files
Clean up parse_repr function of ReprParser
1 parent c72dc2b commit e6b237a

16 files changed

Lines changed: 204 additions & 317 deletions

compiler/rustc_attr_parsing/src/attributes/prelude.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub(super) use rustc_hir::attrs::AttributeKind;
66
#[doc(hidden)]
77
pub(super) use rustc_hir::{MethodKind, Target};
88
#[doc(hidden)]
9-
pub(super) use rustc_span::{DUMMY_SP, Ident, Span, Symbol, sym};
9+
pub(super) use rustc_span::{Ident, Span, Symbol, sym};
1010
#[doc(hidden)]
1111
pub(super) use thin_vec::ThinVec;
1212

compiler/rustc_attr_parsing/src/attributes/repr.rs

Lines changed: 60 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rustc_abi::{Align, Size};
22
use rustc_ast::{IntTy, LitIntType, LitKind, UintTy};
3-
use rustc_hir::attrs::{IntType, ReprAttr};
3+
use rustc_hir::attrs::IntType::{SignedInt, UnsignedInt};
4+
use rustc_hir::attrs::ReprAttr;
45

56
use super::prelude::*;
6-
use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
7+
use crate::session_diagnostics;
78

89
/// Parse #[repr(...)] forms.
910
///
@@ -56,122 +57,69 @@ impl CombineAttributeParser for ReprParser {
5657
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
5758
}
5859

59-
macro_rules! int_pat {
60-
() => {
61-
sym::i8
62-
| sym::u8
63-
| sym::i16
64-
| sym::u16
65-
| sym::i32
66-
| sym::u32
67-
| sym::i64
68-
| sym::u64
69-
| sym::i128
70-
| sym::u128
71-
| sym::isize
72-
| sym::usize
73-
};
74-
}
75-
76-
fn int_type_of_word(s: Symbol) -> Option<IntType> {
77-
use IntType::*;
78-
79-
match s {
80-
sym::i8 => Some(SignedInt(IntTy::I8)),
81-
sym::u8 => Some(UnsignedInt(UintTy::U8)),
82-
sym::i16 => Some(SignedInt(IntTy::I16)),
83-
sym::u16 => Some(UnsignedInt(UintTy::U16)),
84-
sym::i32 => Some(SignedInt(IntTy::I32)),
85-
sym::u32 => Some(UnsignedInt(UintTy::U32)),
86-
sym::i64 => Some(SignedInt(IntTy::I64)),
87-
sym::u64 => Some(UnsignedInt(UintTy::U64)),
88-
sym::i128 => Some(SignedInt(IntTy::I128)),
89-
sym::u128 => Some(UnsignedInt(UintTy::U128)),
90-
sym::isize => Some(SignedInt(IntTy::Isize)),
91-
sym::usize => Some(UnsignedInt(UintTy::Usize)),
92-
_ => None,
93-
}
94-
}
95-
96-
fn parse_repr(cx: &AcceptContext<'_, '_>, param: &MetaItemParser) -> Option<ReprAttr> {
60+
fn parse_repr(cx: &mut AcceptContext<'_, '_>, param: &MetaItemParser) -> Option<ReprAttr> {
9761
use ReprAttr::*;
9862

99-
// FIXME(jdonszelmann): invert the parsing here to match on the word first and then the
100-
// structure.
101-
let (name, ident_span) = if let Some(ident) = param.path().word() {
102-
(Some(ident.name), ident.span)
103-
} else {
104-
(None, DUMMY_SP)
105-
};
106-
107-
let args = param.args();
63+
macro_rules! no_args {
64+
($constructor: expr) => {{
65+
cx.expect_no_args(param.args())?;
66+
Some($constructor)
67+
}};
68+
}
10869

109-
match (name, args) {
110-
(Some(sym::align), ArgParser::NoArgs) => {
111-
cx.emit_err(session_diagnostics::InvalidReprAlignNeedArg { span: ident_span });
112-
None
113-
}
114-
(Some(sym::align), ArgParser::List(l)) => {
70+
match param.path().word_sym() {
71+
Some(sym::align) => {
72+
let l = cx.expect_list(param.args(), param.span())?;
11573
parse_repr_align(cx, l, param.span(), AlignKind::Align)
11674
}
117-
118-
(Some(sym::packed), ArgParser::NoArgs) => Some(ReprPacked(Align::ONE)),
119-
(Some(sym::packed), ArgParser::List(l)) => {
120-
parse_repr_align(cx, l, param.span(), AlignKind::Packed)
121-
}
122-
123-
(Some(name @ sym::align | name @ sym::packed), ArgParser::NameValue(l)) => {
124-
cx.emit_err(session_diagnostics::IncorrectReprFormatGeneric {
125-
span: param.span(),
126-
// FIXME(jdonszelmann) can just be a string in the diag type
127-
repr_arg: name,
128-
cause: IncorrectReprFormatGenericCause::from_lit_kind(
129-
param.span(),
130-
&l.value_as_lit().kind,
131-
name,
132-
),
133-
});
134-
None
135-
}
136-
137-
(Some(sym::Rust), ArgParser::NoArgs) => Some(ReprRust),
138-
(Some(sym::C), ArgParser::NoArgs) => Some(ReprC),
139-
(Some(sym::simd), ArgParser::NoArgs) => Some(ReprSimd),
140-
(Some(sym::transparent), ArgParser::NoArgs) => Some(ReprTransparent),
141-
(Some(name @ int_pat!()), ArgParser::NoArgs) => {
142-
// int_pat!() should make sure it always parses
143-
Some(ReprInt(int_type_of_word(name).unwrap()))
144-
}
145-
146-
(
147-
Some(
148-
name @ sym::Rust
149-
| name @ sym::C
150-
| name @ sym::simd
151-
| name @ sym::transparent
152-
| name @ int_pat!(),
153-
),
154-
ArgParser::NameValue(_),
155-
) => {
156-
cx.emit_err(session_diagnostics::InvalidReprHintNoValue { span: param.span(), name });
157-
None
158-
}
159-
(
160-
Some(
161-
name @ sym::Rust
162-
| name @ sym::C
163-
| name @ sym::simd
164-
| name @ sym::transparent
165-
| name @ int_pat!(),
166-
),
167-
ArgParser::List(_),
168-
) => {
169-
cx.emit_err(session_diagnostics::InvalidReprHintNoParen { span: param.span(), name });
170-
None
171-
}
172-
75+
Some(sym::packed) => match param.args() {
76+
ArgParser::NoArgs => Some(ReprPacked(Align::ONE)),
77+
ArgParser::List(l) => parse_repr_align(cx, l, param.span(), AlignKind::Packed),
78+
ArgParser::NameValue(_) => {
79+
cx.adcx().expected_list_or_no_args(param.span());
80+
None
81+
}
82+
},
83+
Some(sym::Rust) => no_args!(ReprRust),
84+
Some(sym::C) => no_args!(ReprC),
85+
Some(sym::simd) => no_args!(ReprSimd),
86+
Some(sym::transparent) => no_args!(ReprTransparent),
87+
Some(sym::i8) => no_args!(ReprInt(SignedInt(IntTy::I8))),
88+
Some(sym::u8) => no_args!(ReprInt(UnsignedInt(UintTy::U8))),
89+
Some(sym::i16) => no_args!(ReprInt(SignedInt(IntTy::I16))),
90+
Some(sym::u16) => no_args!(ReprInt(UnsignedInt(UintTy::U16))),
91+
Some(sym::i32) => no_args!(ReprInt(SignedInt(IntTy::I32))),
92+
Some(sym::u32) => no_args!(ReprInt(UnsignedInt(UintTy::U32))),
93+
Some(sym::i64) => no_args!(ReprInt(SignedInt(IntTy::I64))),
94+
Some(sym::u64) => no_args!(ReprInt(UnsignedInt(UintTy::U64))),
95+
Some(sym::i128) => no_args!(ReprInt(SignedInt(IntTy::I128))),
96+
Some(sym::u128) => no_args!(ReprInt(UnsignedInt(UintTy::U128))),
97+
Some(sym::isize) => no_args!(ReprInt(SignedInt(IntTy::Isize))),
98+
Some(sym::usize) => no_args!(ReprInt(UnsignedInt(UintTy::Usize))),
17399
_ => {
174-
cx.emit_err(session_diagnostics::UnrecognizedReprHint { span: param.span() });
100+
cx.adcx().expected_specific_argument(
101+
param.span(),
102+
&[
103+
sym::align,
104+
sym::packed,
105+
sym::Rust,
106+
sym::C,
107+
sym::simd,
108+
sym::transparent,
109+
sym::i8,
110+
sym::u8,
111+
sym::i16,
112+
sym::u16,
113+
sym::i32,
114+
sym::u32,
115+
sym::i64,
116+
sym::u64,
117+
sym::i128,
118+
sym::u128,
119+
sym::isize,
120+
sym::usize,
121+
],
122+
);
175123
None
176124
}
177125
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use std::num::IntErrorKind;
22

3-
use rustc_ast as ast;
43
use rustc_errors::codes::*;
54
use rustc_errors::{
65
Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
@@ -198,36 +197,6 @@ pub(crate) struct IncorrectReprFormatPackedExpectInteger {
198197
pub span: Span,
199198
}
200199

201-
#[derive(Diagnostic)]
202-
#[diag("invalid representation hint: `{$name}` does not take a parenthesized argument list", code = E0552)]
203-
pub(crate) struct InvalidReprHintNoParen {
204-
#[primary_span]
205-
pub span: Span,
206-
207-
pub name: Symbol,
208-
}
209-
210-
#[derive(Diagnostic)]
211-
#[diag("invalid representation hint: `{$name}` does not take a value", code = E0552)]
212-
pub(crate) struct InvalidReprHintNoValue {
213-
#[primary_span]
214-
pub span: Span,
215-
216-
pub name: Symbol,
217-
}
218-
219-
#[derive(Diagnostic)]
220-
#[diag("invalid `repr(align)` attribute: `align` needs an argument", code = E0589)]
221-
pub(crate) struct InvalidReprAlignNeedArg {
222-
#[primary_span]
223-
#[suggestion(
224-
"supply an argument here",
225-
code = "align(...)",
226-
applicability = "has-placeholders"
227-
)]
228-
pub span: Span,
229-
}
230-
231200
#[derive(Diagnostic)]
232201
#[diag("invalid `repr({$repr_arg})` attribute: {$error_part}", code = E0589)]
233202
pub(crate) struct InvalidReprGeneric {
@@ -252,57 +221,6 @@ pub(crate) struct IncorrectReprFormatExpectInteger {
252221
pub span: Span,
253222
}
254223

255-
#[derive(Diagnostic)]
256-
#[diag("incorrect `repr({$repr_arg})` attribute format", code = E0693)]
257-
pub(crate) struct IncorrectReprFormatGeneric {
258-
#[primary_span]
259-
pub span: Span,
260-
261-
pub repr_arg: Symbol,
262-
263-
#[subdiagnostic]
264-
pub cause: Option<IncorrectReprFormatGenericCause>,
265-
}
266-
267-
#[derive(Subdiagnostic)]
268-
pub(crate) enum IncorrectReprFormatGenericCause {
269-
#[suggestion(
270-
"use parentheses instead",
271-
code = "{name}({value})",
272-
applicability = "machine-applicable"
273-
)]
274-
Int {
275-
#[primary_span]
276-
span: Span,
277-
name: Symbol,
278-
value: u128,
279-
},
280-
281-
#[suggestion(
282-
"use parentheses instead",
283-
code = "{name}({value})",
284-
applicability = "machine-applicable"
285-
)]
286-
Symbol {
287-
#[primary_span]
288-
span: Span,
289-
name: Symbol,
290-
value: Symbol,
291-
},
292-
}
293-
294-
impl IncorrectReprFormatGenericCause {
295-
pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option<Self> {
296-
match *kind {
297-
ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => {
298-
Some(Self::Int { span, name, value: value.get() })
299-
}
300-
ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }),
301-
_ => None,
302-
}
303-
}
304-
}
305-
306224
#[derive(Diagnostic)]
307225
#[diag("`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute", code = E0717)]
308226
pub(crate) struct RustcPromotablePairing {
@@ -484,19 +402,6 @@ pub(crate) struct InvalidAlignmentValue {
484402
pub error_part: String,
485403
}
486404

487-
#[derive(Diagnostic)]
488-
#[diag("unrecognized representation hint", code = E0552)]
489-
#[help(
490-
"valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`"
491-
)]
492-
#[note(
493-
"for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>"
494-
)]
495-
pub(crate) struct UnrecognizedReprHint {
496-
#[primary_span]
497-
pub span: Span,
498-
}
499-
500405
#[derive(Diagnostic)]
501406
#[diag("item annotated with `#[unstable_feature_bound]` should not be stable")]
502407
#[help(

tests/ui/attributes/attribute-on-wrong-item-inline-repr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ fn main() {
1616

1717
#[repr(nothing)]
1818
let _x = 0;
19-
//~^^ ERROR E0552
19+
//~^^ ERROR malformed `repr` attribute input
2020

2121
#[repr(something_not_real)]
2222
loop {
2323
()
2424
};
25-
//~^^^^ ERROR E0552
25+
//~^^^^ ERROR malformed `repr` attribute input
2626

2727
#[repr]
2828
let _y = "123";

tests/ui/attributes/attribute-on-wrong-item-inline-repr.stderr

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,25 @@ LL | #[inline(XYZ)]
3535
|
3636
= help: `#[inline]` can only be applied to functions
3737

38-
error[E0552]: unrecognized representation hint
39-
--> $DIR/attribute-on-wrong-item-inline-repr.rs:17:12
38+
error[E0539]: malformed `repr` attribute input
39+
--> $DIR/attribute-on-wrong-item-inline-repr.rs:17:5
4040
|
4141
LL | #[repr(nothing)]
42-
| ^^^^^^^
42+
| ^^^^^^^-------^^
43+
| |
44+
| valid arguments are `align`, `packed`, `Rust`, `C`, `simd`, `transparent`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize` or `usize`
4345
|
44-
= help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
45-
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>
46+
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html#representations>
4647

47-
error[E0552]: unrecognized representation hint
48-
--> $DIR/attribute-on-wrong-item-inline-repr.rs:21:12
48+
error[E0539]: malformed `repr` attribute input
49+
--> $DIR/attribute-on-wrong-item-inline-repr.rs:21:5
4950
|
5051
LL | #[repr(something_not_real)]
51-
| ^^^^^^^^^^^^^^^^^^
52+
| ^^^^^^^------------------^^
53+
| |
54+
| valid arguments are `align`, `packed`, `Rust`, `C`, `simd`, `transparent`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize` or `usize`
5255
|
53-
= help: valid reprs are `Rust` (default), `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize`
54-
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html?highlight=repr#representations>
56+
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html#representations>
5557

5658
error[E0539]: malformed `repr` attribute input
5759
--> $DIR/attribute-on-wrong-item-inline-repr.rs:27:5
@@ -100,5 +102,4 @@ LL | let _z = #[repr] 1;
100102

101103
error: aborting due to 9 previous errors
102104

103-
Some errors have detailed explanations: E0539, E0552.
104-
For more information about an error, try `rustc --explain E0539`.
105+
For more information about this error, try `rustc --explain E0539`.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
fn main() {
22
let y = #[repr(uwu(4))]
33
//~^ ERROR attributes on expressions are experimental
4-
//~| ERROR unrecognized representation hint
4+
//~| ERROR malformed `repr` attribute input
55
(&id(5)); //~ ERROR: cannot find function `id` in this scope
66
}

0 commit comments

Comments
 (0)