lint: extend #[must_use]
to handle a message.
Similar to the stability attributes, a type annotated with `#[must_use = "informative snippet"]` will print the normal warning message along with "informative snippet". This allows the type author to provide some guidance about why the type should be used.
This commit is contained in:
parent
66e1f11ef4
commit
b9e35a1644
2 changed files with 29 additions and 11 deletions
|
@ -669,22 +669,13 @@ impl LintPass for UnusedResult {
|
|||
if ast_util::is_local(did) {
|
||||
match cx.tcx.map.get(did.node) {
|
||||
ast_map::NodeItem(it) => {
|
||||
if attr::contains_name(it.attrs.as_slice(),
|
||||
"must_use") {
|
||||
cx.span_lint(UNUSED_MUST_USE, s.span,
|
||||
"unused result which must be used");
|
||||
warned = true;
|
||||
}
|
||||
warned |= check_must_use(cx, it.attrs.as_slice(), s.span);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
|
||||
if attr::contains_name(attrs.as_slice(), "must_use") {
|
||||
cx.span_lint(UNUSED_MUST_USE, s.span,
|
||||
"unused result which must be used");
|
||||
warned = true;
|
||||
}
|
||||
warned |= check_must_use(cx, attrs.as_slice(), s.span);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -693,6 +684,25 @@ impl LintPass for UnusedResult {
|
|||
if !warned {
|
||||
cx.span_lint(UNUSED_RESULT, s.span, "unused result");
|
||||
}
|
||||
|
||||
fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
|
||||
for attr in attrs.iter() {
|
||||
if attr.check_name("must_use") {
|
||||
let mut msg = "unused result which must be used".to_string();
|
||||
// check for #[must_use="..."]
|
||||
match attr.value_str() {
|
||||
None => {}
|
||||
Some(s) => {
|
||||
msg.push_str(": ");
|
||||
msg.push_str(s.get());
|
||||
}
|
||||
}
|
||||
cx.span_lint(UNUSED_MUST_USE, sp, msg.as_slice());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,27 +14,35 @@
|
|||
#[must_use]
|
||||
enum MustUse { Test }
|
||||
|
||||
#[must_use = "some message"]
|
||||
enum MustUseMsg { Test2 }
|
||||
|
||||
fn foo<T>() -> T { fail!() }
|
||||
|
||||
fn bar() -> int { return foo::<int>(); }
|
||||
fn baz() -> MustUse { return foo::<MustUse>(); }
|
||||
fn qux() -> MustUseMsg { return foo::<MustUseMsg>(); }
|
||||
|
||||
#[allow(unused_result)]
|
||||
fn test() {
|
||||
foo::<int>();
|
||||
foo::<MustUse>(); //~ ERROR: unused result which must be used
|
||||
foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
|
||||
}
|
||||
|
||||
#[allow(unused_result, unused_must_use)]
|
||||
fn test2() {
|
||||
foo::<int>();
|
||||
foo::<MustUse>();
|
||||
foo::<MustUseMsg>();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::<int>(); //~ ERROR: unused result
|
||||
foo::<MustUse>(); //~ ERROR: unused result which must be used
|
||||
foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
|
||||
|
||||
let _ = foo::<int>();
|
||||
let _ = foo::<MustUse>();
|
||||
let _ = foo::<MustUseMsg>();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue