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