Expand output and suggestions, fix tests
This commit is contained in:
parent
36381fabaf
commit
2c7099baeb
6 changed files with 292 additions and 154 deletions
|
@ -2139,7 +2139,6 @@ register_diagnostics! {
|
||||||
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
|
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
|
||||||
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
|
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
|
||||||
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
|
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
|
||||||
E0689, // `#[repr]` must have a hint
|
|
||||||
|
|
||||||
E0906, // closures cannot be static
|
E0906, // closures cannot be static
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
//! conflicts between multiple such attributes attached to the same
|
//! conflicts between multiple such attributes attached to the same
|
||||||
//! item.
|
//! item.
|
||||||
|
|
||||||
use syntax_pos::Span;
|
use syntax_pos::{BytePos, Span};
|
||||||
use ty::TyCtxt;
|
use ty::TyCtxt;
|
||||||
|
|
||||||
use hir;
|
use hir;
|
||||||
|
@ -156,17 +156,54 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
|
||||||
.filter(|attr| attr.name() == "repr")
|
.filter(|attr| attr.name() == "repr")
|
||||||
.filter_map(|attr| {
|
.filter_map(|attr| {
|
||||||
let list = attr.meta_item_list();
|
let list = attr.meta_item_list();
|
||||||
let mut has_hints = false;
|
|
||||||
if let Some(ref list) = list {
|
// Emit warnings with `repr` either has a literal assignment (`#[repr = "C"]`) or
|
||||||
has_hints = !list.is_empty();
|
// no hints (``#[repr]`)
|
||||||
}
|
let has_hints = list.as_ref().map(|ref list| !list.is_empty()).unwrap_or(false);
|
||||||
if !has_hints {
|
if !has_hints {
|
||||||
span_warn!(
|
let mut suggested = false;
|
||||||
self.tcx.sess,
|
let mut warn = if let Some(ref lit) = attr.value_str() {
|
||||||
item.span,
|
// avoid warning about empty `repr` on `#[repr = "foo"]`
|
||||||
E0689,
|
let sp = match format!("{}", lit).as_ref() {
|
||||||
"`repr` attribute cannot be empty",
|
"C" | "packed" | "rust" | "u*" | "i*" => {
|
||||||
);
|
let lo = attr.span.lo() + BytePos(2);
|
||||||
|
let hi = attr.span.hi() - BytePos(1);
|
||||||
|
suggested = true;
|
||||||
|
attr.span.with_lo(lo).with_hi(hi)
|
||||||
|
}
|
||||||
|
_ => attr.span, // the literal wasn't a valid `repr` arg
|
||||||
|
};
|
||||||
|
let mut warn = self.tcx.sess.struct_span_warn(
|
||||||
|
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 = self.tcx.sess.struct_span_warn(
|
||||||
|
attr.span,
|
||||||
|
"`repr` attribute must have a hint",
|
||||||
|
);
|
||||||
|
warn.span_label(attr.span, "needs a hint");
|
||||||
|
warn
|
||||||
|
};
|
||||||
|
if !suggested {
|
||||||
|
warn.help("valid hints include `#[repr(C)]`, `#[repr(packed)]` and \
|
||||||
|
`#[repr(rust)]`");
|
||||||
|
warn.note("for more information, visit \
|
||||||
|
<https://doc.rust-lang.org/nomicon/other-reprs.html>");
|
||||||
|
}
|
||||||
|
warn.emit();
|
||||||
}
|
}
|
||||||
list
|
list
|
||||||
})
|
})
|
||||||
|
|
|
@ -309,20 +309,25 @@ mod bench {
|
||||||
|
|
||||||
#[repr = "3900"]
|
#[repr = "3900"]
|
||||||
//~^ WARN unused attribute
|
//~^ WARN unused attribute
|
||||||
|
//~| WARN `repr` attribute isn't configurable with a literal
|
||||||
mod repr {
|
mod repr {
|
||||||
mod inner { #![repr="3900"] }
|
mod inner { #![repr="3900"] }
|
||||||
//~^ WARN unused attribute
|
//~^ WARN unused attribute
|
||||||
|
//~| WARN `repr` attribute isn't configurable with a literal
|
||||||
|
|
||||||
#[repr = "3900"] fn f() { }
|
#[repr = "3900"] fn f() { }
|
||||||
//~^ WARN unused attribute
|
//~^ WARN unused attribute
|
||||||
|
//~| WARN `repr` attribute isn't configurable with a literal
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
|
||||||
#[repr = "3900"] type T = S;
|
#[repr = "3900"] type T = S;
|
||||||
//~^ WARN unused attribute
|
//~^ WARN unused attribute
|
||||||
|
//~| WARN `repr` attribute isn't configurable with a literal
|
||||||
|
|
||||||
#[repr = "3900"] impl S { }
|
#[repr = "3900"] impl S { }
|
||||||
//~^ WARN unused attribute
|
//~^ WARN unused attribute
|
||||||
|
//~| WARN `repr` attribute isn't configurable with a literal
|
||||||
}
|
}
|
||||||
|
|
||||||
#[path = "3800"]
|
#[path = "3800"]
|
||||||
|
|
File diff suppressed because it is too large
Load diff
28
src/test/ui/suggestions/repr.rs
Normal file
28
src/test/ui/suggestions/repr.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// compile-pass
|
||||||
|
|
||||||
|
#[repr]
|
||||||
|
//^ WARN `repr` attribute must have a hint
|
||||||
|
struct _A {}
|
||||||
|
|
||||||
|
#[repr = "B"]
|
||||||
|
//^ WARN `repr` attribute isn't configurable with a literal
|
||||||
|
struct _B {}
|
||||||
|
|
||||||
|
#[repr = "C"]
|
||||||
|
//^ WARN `repr` attribute isn't configurable with a literal
|
||||||
|
struct _C {}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
struct _D {}
|
||||||
|
|
||||||
|
fn main() {}
|
24
src/test/ui/suggestions/repr.stderr
Normal file
24
src/test/ui/suggestions/repr.stderr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
warning: `repr` attribute must have a hint
|
||||||
|
--> $DIR/repr.rs:13:1
|
||||||
|
|
|
||||||
|
LL | #[repr]
|
||||||
|
| ^^^^^^^ needs a hint
|
||||||
|
|
|
||||||
|
= help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]`
|
||||||
|
= note: for more information, visit <https://doc.rust-lang.org/nomicon/other-reprs.html>
|
||||||
|
|
||||||
|
warning: `repr` attribute isn't configurable with a literal
|
||||||
|
--> $DIR/repr.rs:17:1
|
||||||
|
|
|
||||||
|
LL | #[repr = "B"]
|
||||||
|
| ^^^^^^^^^^^^^ needs a hint
|
||||||
|
|
|
||||||
|
= help: valid hints include `#[repr(C)]`, `#[repr(packed)]` and `#[repr(rust)]`
|
||||||
|
= note: for more information, visit <https://doc.rust-lang.org/nomicon/other-reprs.html>
|
||||||
|
|
||||||
|
warning: `repr` attribute isn't configurable with a literal
|
||||||
|
--> $DIR/repr.rs:21:3
|
||||||
|
|
|
||||||
|
LL | #[repr = "C"]
|
||||||
|
| ^^^^^^^^^^ help: give `repr` a hint: `repr(C)`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue