Skip to content

Commit b9e35a1

Browse files
committed
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.
1 parent 66e1f11 commit b9e35a1

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

src/librustc/lint/builtin.rs

+21-11
Original file line numberDiff line numberDiff line change
@@ -669,22 +669,13 @@ impl LintPass for UnusedResult {
669669
if ast_util::is_local(did) {
670670
match cx.tcx.map.get(did.node) {
671671
ast_map::NodeItem(it) => {
672-
if attr::contains_name(it.attrs.as_slice(),
673-
"must_use") {
674-
cx.span_lint(UNUSED_MUST_USE, s.span,
675-
"unused result which must be used");
676-
warned = true;
677-
}
672+
warned |= check_must_use(cx, it.attrs.as_slice(), s.span);
678673
}
679674
_ => {}
680675
}
681676
} else {
682677
csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
683-
if attr::contains_name(attrs.as_slice(), "must_use") {
684-
cx.span_lint(UNUSED_MUST_USE, s.span,
685-
"unused result which must be used");
686-
warned = true;
687-
}
678+
warned |= check_must_use(cx, attrs.as_slice(), s.span);
688679
});
689680
}
690681
}
@@ -693,6 +684,25 @@ impl LintPass for UnusedResult {
693684
if !warned {
694685
cx.span_lint(UNUSED_RESULT, s.span, "unused result");
695686
}
687+
688+
fn check_must_use(cx: &Context, attrs: &[ast::Attribute], sp: Span) -> bool {
689+
for attr in attrs.iter() {
690+
if attr.check_name("must_use") {
691+
let mut msg = "unused result which must be used".to_string();
692+
// check for #[must_use="..."]
693+
match attr.value_str() {
694+
None => {}
695+
Some(s) => {
696+
msg.push_str(": ");
697+
msg.push_str(s.get());
698+
}
699+
}
700+
cx.span_lint(UNUSED_MUST_USE, sp, msg.as_slice());
701+
return true;
702+
}
703+
}
704+
false
705+
}
696706
}
697707
}
698708

src/test/compile-fail/unused-result.rs

+8
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,35 @@
1414
#[must_use]
1515
enum MustUse { Test }
1616

17+
#[must_use = "some message"]
18+
enum MustUseMsg { Test2 }
19+
1720
fn foo<T>() -> T { fail!() }
1821

1922
fn bar() -> int { return foo::<int>(); }
2023
fn baz() -> MustUse { return foo::<MustUse>(); }
24+
fn qux() -> MustUseMsg { return foo::<MustUseMsg>(); }
2125

2226
#[allow(unused_result)]
2327
fn test() {
2428
foo::<int>();
2529
foo::<MustUse>(); //~ ERROR: unused result which must be used
30+
foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
2631
}
2732

2833
#[allow(unused_result, unused_must_use)]
2934
fn test2() {
3035
foo::<int>();
3136
foo::<MustUse>();
37+
foo::<MustUseMsg>();
3238
}
3339

3440
fn main() {
3541
foo::<int>(); //~ ERROR: unused result
3642
foo::<MustUse>(); //~ ERROR: unused result which must be used
43+
foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
3744

3845
let _ = foo::<int>();
3946
let _ = foo::<MustUse>();
47+
let _ = foo::<MustUseMsg>();
4048
}

0 commit comments

Comments
 (0)