diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index ae401b9d6f15c..481187f7c2ce7 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -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 + } } } diff --git a/src/test/compile-fail/unused-result.rs b/src/test/compile-fail/unused-result.rs index 44058c1ddda19..ecc52c0ee7d58 100644 --- a/src/test/compile-fail/unused-result.rs +++ b/src/test/compile-fail/unused-result.rs @@ -14,27 +14,35 @@ #[must_use] enum MustUse { Test } +#[must_use = "some message"] +enum MustUseMsg { Test2 } + fn foo() -> T { fail!() } fn bar() -> int { return foo::(); } fn baz() -> MustUse { return foo::(); } +fn qux() -> MustUseMsg { return foo::(); } #[allow(unused_result)] fn test() { foo::(); foo::(); //~ ERROR: unused result which must be used + foo::(); //~ ERROR: unused result which must be used: some message } #[allow(unused_result, unused_must_use)] fn test2() { foo::(); foo::(); + foo::(); } fn main() { foo::(); //~ ERROR: unused result foo::(); //~ ERROR: unused result which must be used + foo::(); //~ ERROR: unused result which must be used: some message let _ = foo::(); let _ = foo::(); + let _ = foo::(); }