Skip to content

Commit 3cc09c8

Browse files
committed
Use consistent span for repr attr suggestion
1 parent b3810f6 commit 3cc09c8

File tree

4 files changed

+41
-28
lines changed

4 files changed

+41
-28
lines changed

src/librustc_lint/builtin.rs

+35-23
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,18 @@ impl EarlyLintPass for BadRepr {
687687
fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
688688
if attr.name() == "repr" {
689689
let list = attr.meta_item_list();
690+
let outer = match attr.style {
691+
ast::AttrStyle::Outer => true,
692+
ast::AttrStyle::Inner => false,
693+
};
694+
695+
let repr_str = move |lit: &str| {
696+
if outer {
697+
format!("#[repr({})]", lit)
698+
} else {
699+
format!("#![repr({})]", lit)
700+
}
701+
};
690702

691703
// Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or
692704
// no hints (``#[repr]`)
@@ -695,33 +707,28 @@ impl EarlyLintPass for BadRepr {
695707
let mut suggested = false;
696708
let mut warn = if let Some(ref lit) = attr.value_str() {
697709
// avoid warning about empty `repr` on `#[repr = "foo"]`
698-
let sp = match format!("{}", lit).as_ref() {
710+
let mut warn = cx.struct_span_lint(
711+
BAD_REPR,
712+
attr.span,
713+
"`repr` attribute isn't configurable with a literal",
714+
);
715+
match format!("{}", lit).as_ref() {
699716
| "C" | "packed" | "rust" | "transparent"
700717
| "u8" | "u16" | "u32" | "u64" | "u128" | "usize"
701718
| "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => {
702-
let lo = attr.span.lo() + BytePos(2);
703-
let hi = attr.span.hi() - BytePos(1);
719+
// if the literal could have been a valid `repr` arg,
720+
// suggest the correct syntax
721+
warn.span_suggestion(
722+
attr.span,
723+
"give `repr` a hint",
724+
repr_str(&lit.as_str()),
725+
);
704726
suggested = true;
705-
attr.span.with_lo(lo).with_hi(hi)
706727
}
707-
_ => attr.span, // the literal wasn't a valid `repr` arg
728+
_ => { // the literal wasn't a valid `repr` arg
729+
warn.span_label(attr.span, "needs a hint");
730+
}
708731
};
709-
let mut warn = cx.struct_span_lint(
710-
BAD_REPR,
711-
sp,
712-
"`repr` attribute isn't configurable with a literal",
713-
);
714-
if suggested {
715-
// if the literal could have been a valid `repr` arg,
716-
// suggest the correct syntax
717-
warn.span_suggestion(
718-
sp,
719-
"give `repr` a hint",
720-
format!("repr({})", lit),
721-
);
722-
} else {
723-
warn.span_label(attr.span, "needs a hint");
724-
}
725732
warn
726733
} else {
727734
let mut warn = cx.struct_span_lint(
@@ -733,8 +740,13 @@ impl EarlyLintPass for BadRepr {
733740
warn
734741
};
735742
if !suggested {
736-
warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]`, \
737-
`#[repr(rust)]` and `#[repr(transparent)]`");
743+
warn.help(&format!(
744+
"valid hints include `{}`, `{}`, `{}` and `{}`",
745+
repr_str("C"),
746+
repr_str("packed"),
747+
repr_str("rust"),
748+
repr_str("transparent"),
749+
));
738750
warn.note("for more information, visit \
739751
<https://doc.rust-lang.org/reference/type-layout.html>");
740752
}

src/test/compile-fail/issue-43988.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fn main() {
3434
#[repr]
3535
let _y = "123";
3636
//~^^ ERROR attribute should not be applied to a statement
37+
//~| WARN `repr` attribute must have a hint
3738

3839

3940
fn foo() {}
@@ -44,5 +45,5 @@ fn main() {
4445

4546
let _z = #[repr] 1;
4647
//~^ ERROR attribute should not be applied to an expression
47-
48+
//~| WARN `repr` attribute must have a hint
4849
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ LL | mod inner { #![repr="3900"] }
193193
| ^^^^^^^^^^^^^^^ needs a hint
194194
|
195195
= note: #[warn(bad_repr)] on by default
196-
= help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
196+
= help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]`
197197
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
198198

199199
warning: `repr` attribute isn't configurable with a literal
@@ -238,7 +238,7 @@ warning: `repr` attribute isn't configurable with a literal
238238
LL | #![repr = "3900"]
239239
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint
240240
|
241-
= help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
241+
= help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]`
242242
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
243243

244244
warning: unused attribute

src/test/ui/suggestions/repr.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ LL | #[repr = "B"]
1818
= note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
1919

2020
warning: `repr` attribute isn't configurable with a literal
21-
--> $DIR/repr.rs:21:3
21+
--> $DIR/repr.rs:21:1
2222
|
2323
LL | #[repr = "C"]
24-
| ^^^^^^^^^^ help: give `repr` a hint: `repr(C)`
24+
| ^^^^^^^^^^^^^ help: give `repr` a hint: `#[repr(C)]`
2525

0 commit comments

Comments
 (0)