Skip to main content

rustc_attr_parsing/attributes/
must_use.rs

1use super::prelude::*;
2
3pub(crate) struct MustUseParser;
4
5impl<S: Stage> SingleAttributeParser<S> for MustUseParser {
6    const PATH: &[Symbol] = &[sym::must_use];
7    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
8    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
9        Allow(Target::Fn),
10        Allow(Target::Enum),
11        Allow(Target::Struct),
12        Allow(Target::Union),
13        Allow(Target::Method(MethodKind::Trait { body: false })),
14        Allow(Target::Method(MethodKind::Trait { body: true })),
15        Allow(Target::Method(MethodKind::Inherent)),
16        Allow(Target::ForeignFn),
17        // `impl Trait` in return position can trip
18        // `unused_must_use` if `Trait` is marked as
19        // `#[must_use]`
20        Allow(Target::Trait),
21        Error(Target::WherePredicate),
22    ]);
23    const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
    word: true,
    list: None,
    one_of: &[],
    name_value_str: Some(&["reason"]),
    docs: Some("https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"),
}template!(
24        Word, NameValueStr: "reason",
25        "https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"
26    );
27
28    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
29        Some(AttributeKind::MustUse {
30            span: cx.attr_span,
31            reason: match args {
32                ArgParser::NoArgs => None,
33                ArgParser::NameValue(name_value) => {
34                    let Some(value_str) = name_value.value_as_str() else {
35                        cx.expected_string_literal(
36                            name_value.value_span,
37                            Some(&name_value.value_as_lit()),
38                        );
39                        return None;
40                    };
41                    Some(value_str)
42                }
43                ArgParser::List(list) => {
44                    cx.expected_nv_or_no_args(list.span);
45                    return None;
46                }
47            },
48        })
49    }
50}