about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-06-06 15:48:08 -0700
committerEsteban Küber <esteban@kuber.com.ar>2018-06-06 17:36:28 -0700
commit3cc09c8380ed22d4aa9b3b0896b88707b4034b3b (patch)
tree981b5ceb238c22e369b104966e2222c089817bd6
parentb3810f61da08bc986ffd854361e957e4b8d42560 (diff)
downloadrust-3cc09c8380ed22d4aa9b3b0896b88707b4034b3b.tar.gz
rust-3cc09c8380ed22d4aa9b3b0896b88707b4034b3b.zip
Use consistent span for repr attr suggestion
-rw-r--r--src/librustc_lint/builtin.rs58
-rw-r--r--src/test/compile-fail/issue-43988.rs3
-rw-r--r--src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr4
-rw-r--r--src/test/ui/suggestions/repr.stderr4
4 files changed, 41 insertions, 28 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 5c05fdb5621..d95e0d77d86 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -687,6 +687,18 @@ impl EarlyLintPass for BadRepr {
     fn check_attribute(&mut self, cx: &EarlyContext, attr: &ast::Attribute) {
         if attr.name() == "repr" {
             let list = attr.meta_item_list();
+            let outer = match attr.style {
+                ast::AttrStyle::Outer => true,
+                ast::AttrStyle::Inner => false,
+            };
+
+            let repr_str = move |lit: &str| {
+                if outer {
+                    format!("#[repr({})]", lit)
+                } else {
+                    format!("#![repr({})]", lit)
+                }
+            };
 
             // Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or
             // no hints (``#[repr]`)
@@ -695,33 +707,28 @@ impl EarlyLintPass for BadRepr {
                 let mut suggested = false;
                 let mut warn = if let Some(ref lit) = attr.value_str() {
                     // avoid warning about empty `repr` on `#[repr = "foo"]`
-                    let sp = match format!("{}", lit).as_ref() {
+                    let mut warn = cx.struct_span_lint(
+                        BAD_REPR,
+                        attr.span,
+                        "`repr` attribute isn't configurable with a literal",
+                    );
+                    match format!("{}", lit).as_ref() {
                         | "C" | "packed" | "rust" | "transparent"
                         | "u8" | "u16" | "u32" | "u64" | "u128" | "usize"
                         | "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => {
-                            let lo = attr.span.lo() + BytePos(2);
-                            let hi = attr.span.hi() - BytePos(1);
+                            // if the literal could have been a valid `repr` arg,
+                            // suggest the correct syntax
+                            warn.span_suggestion(
+                                attr.span,
+                                "give `repr` a hint",
+                                repr_str(&lit.as_str()),
+                            );
                             suggested = true;
-                            attr.span.with_lo(lo).with_hi(hi)
                         }
-                        _ => attr.span,  // the literal wasn't a valid `repr` arg
+                        _ => {  // the literal wasn't a valid `repr` arg
+                            warn.span_label(attr.span, "needs a hint");
+                        }
                     };
-                    let mut warn = cx.struct_span_lint(
-                        BAD_REPR,
-                        sp,
-                        "`repr` attribute isn't configurable with a literal",
-                    );
-                    if suggested {
-                        // if the literal could have been a valid `repr` arg,
-                        // suggest the correct syntax
-                        warn.span_suggestion(
-                            sp,
-                            "give `repr` a hint",
-                            format!("repr({})", lit),
-                        );
-                    } else {
-                        warn.span_label(attr.span, "needs a hint");
-                    }
                     warn
                 } else {
                     let mut warn = cx.struct_span_lint(
@@ -733,8 +740,13 @@ impl EarlyLintPass for BadRepr {
                     warn
                 };
                 if !suggested {
-                    warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]`, \
-                               `#[repr(rust)]` and `#[repr(transparent)]`");
+                    warn.help(&format!(
+                        "valid hints include `{}`, `{}`, `{}` and `{}`",
+                        repr_str("C"),
+                        repr_str("packed"),
+                        repr_str("rust"),
+                        repr_str("transparent"),
+                    ));
                     warn.note("for more information, visit \
                                <https://doc.rust-lang.org/reference/type-layout.html>");
                 }
diff --git a/src/test/compile-fail/issue-43988.rs b/src/test/compile-fail/issue-43988.rs
index 0dfa9f6f0d3..6361af76482 100644
--- a/src/test/compile-fail/issue-43988.rs
+++ b/src/test/compile-fail/issue-43988.rs
@@ -34,6 +34,7 @@ fn main() {
     #[repr]
     let _y = "123";
     //~^^ ERROR attribute should not be applied to a statement
+    //~| WARN `repr` attribute must have a hint
 
 
     fn foo() {}
@@ -44,5 +45,5 @@ fn main() {
 
     let _z = #[repr] 1;
     //~^ ERROR attribute should not be applied to an expression
-
+    //~| WARN `repr` attribute must have a hint
 }
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
index f351a9e69d0..3569eecd883 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
@@ -193,7 +193,7 @@ LL |     mod inner { #![repr="3900"] }
    |                 ^^^^^^^^^^^^^^^ needs a hint
    |
    = note: #[warn(bad_repr)] on by default
-   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]`
    = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
 
 warning: `repr` attribute isn't configurable with a literal
@@ -238,7 +238,7 @@ warning: `repr` attribute isn't configurable with a literal
 LL | #![repr                       = "3900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs a hint
    |
-   = help: valid hints include `#[repr(C)]`, `#[repr(packed)]`, `#[repr(rust)]` and `#[repr(transparent)]`
+   = help: valid hints include `#![repr(C)]`, `#![repr(packed)]`, `#![repr(rust)]` and `#![repr(transparent)]`
    = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
 
 warning: unused attribute
diff --git a/src/test/ui/suggestions/repr.stderr b/src/test/ui/suggestions/repr.stderr
index 83f5bb48f7a..7a99d8c0448 100644
--- a/src/test/ui/suggestions/repr.stderr
+++ b/src/test/ui/suggestions/repr.stderr
@@ -18,8 +18,8 @@ LL | #[repr = "B"]
    = note: for more information, visit <https://doc.rust-lang.org/reference/type-layout.html>
 
 warning: `repr` attribute isn't configurable with a literal
-  --> $DIR/repr.rs:21:3
+  --> $DIR/repr.rs:21:1
    |
 LL | #[repr = "C"]
-   |   ^^^^^^^^^^ help: give `repr` a hint: `repr(C)`
+   | ^^^^^^^^^^^^^ help: give `repr` a hint: `#[repr(C)]`