Skip to main content

ide_diagnostics/handlers/
unused_must_use.rs

1use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
2
3// Diagnostic: unused-must-use
4//
5// This diagnostic is triggered when a value with the `#[must_use]` attribute
6// is dropped without being used.
7pub(crate) fn unused_must_use<'db>(
8    ctx: &DiagnosticsContext<'_, 'db>,
9    d: &hir::UnusedMustUse<'db>,
10) -> Diagnostic {
11    let message = match d.message {
12        Some(message) => format!("unused return value that must be used: {message}"),
13        None => "unused return value that must be used".to_owned(),
14    };
15    Diagnostic::new_with_syntax_node_ptr(
16        ctx,
17        DiagnosticCode::RustcLint("unused_must_use"),
18        message,
19        d.expr.map(Into::into),
20    )
21    .stable()
22}
23
24#[cfg(test)]
25mod tests {
26    use crate::tests::check_diagnostics;
27
28    #[test]
29    fn unused_must_use_function_call() {
30        check_diagnostics(
31            r#"
32#[must_use]
33fn produces() -> i32 { 0 }
34fn main() {
35    produces();
36  //^^^^^^^^^^ warn: unused return value that must be used
37}
38"#,
39        );
40    }
41
42    #[test]
43    fn unused_must_use_method_call() {
44        check_diagnostics(
45            r#"
46struct S;
47impl S {
48    #[must_use]
49    fn produces(&self) -> i32 { 0 }
50}
51fn main() {
52    let s = S;
53    s.produces();
54  //^^^^^^^^^^^^ warn: unused return value that must be used
55}
56"#,
57        );
58    }
59
60    #[test]
61    fn with_message() {
62        check_diagnostics(
63            r#"
64struct S;
65impl S {
66    #[must_use = "custom message"]
67    fn produces(&self) -> i32 { 0 }
68}
69fn main() {
70    let s = S;
71    s.produces();
72  //^^^^^^^^^^^^ warn: unused return value that must be used: custom message
73}
74"#,
75        );
76    }
77
78    #[test]
79    fn unused_must_use_type() {
80        check_diagnostics(
81            r#"
82#[must_use]
83struct Important;
84fn produces() -> Important { Important }
85fn main() {
86    produces();
87  //^^^^^^^^^^ warn: unused return value that must be used
88}
89"#,
90        );
91    }
92
93    #[test]
94    fn no_warning_when_value_used() {
95        check_diagnostics(
96            r#"
97#[must_use]
98fn produces() -> i32 { 0 }
99fn main() {
100    let _x = produces();
101}
102"#,
103        );
104    }
105
106    #[test]
107    fn no_warning_when_no_must_use_attribute() {
108        check_diagnostics(
109            r#"
110fn ordinary() -> i32 { 0 }
111fn main() {
112    ordinary();
113}
114"#,
115        );
116    }
117
118    #[test]
119    fn no_warning_when_value_assigned() {
120        check_diagnostics(
121            r#"
122#[must_use]
123fn produces() -> i32 { 0 }
124fn main() {
125    let x;
126    x = produces();
127    let _ = x;
128}
129"#,
130        );
131    }
132}