Skip to content

Commit 2c7099b

Browse files
committed
Expand output and suggestions, fix tests
1 parent 36381fa commit 2c7099b

File tree

6 files changed

+292
-154
lines changed

6 files changed

+292
-154
lines changed

src/librustc/diagnostics.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,6 @@ register_diagnostics! {
21392139
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
21402140
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
21412141
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
2142-
E0689, // `#[repr]` must have a hint
21432142

21442143
E0906, // closures cannot be static
21452144
}

src/librustc/hir/check_attr.rs

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! conflicts between multiple such attributes attached to the same
1515
//! item.
1616
17-
use syntax_pos::Span;
17+
use syntax_pos::{BytePos, Span};
1818
use ty::TyCtxt;
1919

2020
use hir;
@@ -156,17 +156,54 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
156156
.filter(|attr| attr.name() == "repr")
157157
.filter_map(|attr| {
158158
let list = attr.meta_item_list();
159-
let mut has_hints = false;
160-
if let Some(ref list) = list {
161-
has_hints = !list.is_empty();
162-
}
159+
160+
// Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or
161+
// no hints (``#[repr]`)
162+
let has_hints = list.as_ref().map(|ref list| !list.is_empty()).unwrap_or(false);
163163
if !has_hints {
164-
span_warn!(
165-
self.tcx.sess,
166-
item.span,
167-
E0689,
168-
"`repr` attribute cannot be empty",
169-
);
164+
let mut suggested = false;
165+
let mut warn = if let Some(ref lit) = attr.value_str() {
166+
// avoid warning about empty `repr` on `#[repr = "foo"]`
167+
let sp = match format!("{}", lit).as_ref() {
168+
"C" | "packed" | "rust" | "u*" | "i*" => {
169+
let lo = attr.span.lo() + BytePos(2);
170+
let hi = attr.span.hi() - BytePos(1);
171+
suggested = true;
172+
attr.span.with_lo(lo).with_hi(hi)
173+
}
174+
_ => attr.span, // the literal wasn't a valid `repr` arg
175+
};
176+
let mut warn = self.tcx.sess.struct_span_warn(
177+
sp,
178+
"`repr` attribute isn't configurable with a literal",
179+
);
180+
if suggested {
181+
// if the literal could have been a valid `repr` arg,
182+
// suggest the correct syntax
183+
warn.span_suggestion(
184+
sp,
185+
"give `repr` a hint",
186+
format!("repr({})", lit),
187+
);
188+
} else {
189+
warn.span_label(attr.span, "needs a hint");
190+
}
191+
warn
192+
} else {
193+
let mut warn = self.tcx.sess.struct_span_warn(
194+
attr.span,
195+
"`repr` attribute must have a hint",
196+
);
197+
warn.span_label(attr.span, "needs a hint");
198+
warn
199+
};
200+
if !suggested {
201+
warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]` and \
202+
`#[repr(rust)]`");
203+
warn.note("for more information, visit \
204+
<https://doc.rust-lang.org/nomicon/other-reprs.html>");
205+
}
206+
warn.emit();
170207
}
171208
list
172209
})

src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,20 +309,25 @@ mod bench {
309309

310310
#[repr = "3900"]
311311
//~^ WARN unused attribute
312+
//~| WARN `repr` attribute isn't configurable with a literal
312313
mod repr {
313314
mod inner { #![repr="3900"] }
314315
//~^ WARN unused attribute
316+
//~| WARN `repr` attribute isn't configurable with a literal
315317

316318
#[repr = "3900"] fn f() { }
317319
//~^ WARN unused attribute
320+
//~| WARN `repr` attribute isn't configurable with a literal
318321

319322
struct S;
320323

321324
#[repr = "3900"] type T = S;
322325
//~^ WARN unused attribute
326+
//~| WARN `repr` attribute isn't configurable with a literal
323327

324328
#[repr = "3900"] impl S { }
325329
//~^ WARN unused attribute
330+
//~| WARN `repr` attribute isn't configurable with a literal
326331
}
327332

328333
#[path = "3800"]

0 commit comments

Comments
 (0)