Skip to main content

rustc_structures/
lint.rs

1use std::fmt;
2
3#[cfg(feature = "nightly")]
4use rustc_macros::{Decodable, Encodable, StableHash};
5use rustc_span::{Symbol, sym};
6
7#[derive(#[automatically_derived]impl ::core::marker::Copy for LintName { }Copy, #[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for LintName {
}
#[automatically_derived]impl ::core::clone::Clone for LintName {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<Option<Symbol>>;
        let _: ::core::clone::AssertParamIsClone<Symbol>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::fmt::Debug for LintName {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "LintName tool name", &self.tool, &&self.name)
    }
}Debug, #[automatically_derived]impl ::core::cmp::Eq for LintName {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Option<Symbol>>;
        let _: ::core::cmp::AssertParamIsEq<Symbol>;
    }
}Eq, #[automatically_derived]impl ::core::hash::Hash for LintName {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.tool, state);
        ::core::hash::Hash::hash(&self.name, state)
    }
}Hash, #[automatically_derived]impl ::core::marker::StructuralPartialEq for LintName
    {
}
#[automatically_derived]impl ::core::cmp::PartialEq for LintName {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        self.tool == other.tool && self.name == other.name
    }
}PartialEq, #[automatically_derived]impl ::core::cmp::Ord for LintName {
    #[inline]
    fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.tool, &other.tool) {
            ::core::cmp::Ordering::Equal =>
                ::core::cmp::Ord::cmp(&self.name, &other.name),
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]impl ::core::cmp::PartialOrd for LintName {
    #[inline]
    fn partial_cmp(&self, other: &Self)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd)]
8#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for LintName {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    LintName { tool: ref __binding_0, name: ref __binding_1 } =>
                        {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LintName {
            fn encode(&self, __encoder: &mut __E) {
                let LintName { tool: ref __binding_0, name: ref __binding_1
                        } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LintName {
            fn decode(__decoder: &mut __D) -> Self {
                LintName {
                    tool: ::rustc_serialize::Decodable::decode(__decoder),
                    name: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable))]
9pub struct LintName {
10    /// The lint's tool name, if present.
11    pub tool: Option<Symbol>,
12    /// The lint's name, minus the tool name if any.
13    ///
14    /// For example:
15    /// - `clippy::blah` -> `blah`
16    /// - `unstable_imports` -> `unstable_imports`
17    /// - `custom_tool::blah::bleh` -> `blah::bleh`
18    pub name: Symbol,
19}
20
21impl LintName {
22    pub fn new(segments: impl Iterator<Item = Symbol>) -> LintName {
23        let segments = segments.collect::<Vec<_>>();
24        let (tool, name) = match &*segments {
25            [] => ::core::panicking::unreachable_default_msg()unreachable!(),
26            [lint_name] => (None, *lint_name),
27            [tool, lint_name] => (Some(*tool), *lint_name),
28            // Not reachable for any builtin lints,
29            // but reachable using `register_tool`.
30            [tool, lint_name, rest @ ..] => {
31                let mut lint_name = String::from(lint_name.as_str());
32                for seg in rest {
33                    lint_name.push_str("::");
34                    lint_name.push_str(seg.as_str());
35                }
36                (Some(*tool), Symbol::intern(&lint_name))
37            }
38        };
39        LintName { tool, name }
40    }
41
42    /// `lint` must not be empty.
43    pub fn from_str(lint: &str) -> LintName {
44        if lint.is_empty() {
45            if truecfg!(debug_assertions) {
46                ::rustc_span::macros::bug_impl(None, format_args!("`lint` is empty"),
    Location::caller())rustc_span::bug!("`lint` is empty")
47            } else {
48                return LintName { tool: None, name: sym::empty };
49            }
50        }
51        if let Some((tool, name)) = lint.split_once("::") {
52            LintName { tool: Some(Symbol::intern(tool)), name: Symbol::intern(name) }
53        } else {
54            LintName { tool: None, name: Symbol::intern(lint) }
55        }
56    }
57
58    pub fn to_lowercase(mut self) -> LintName {
59        fn lowercase(s: &mut Symbol) {
60            let lower = s.as_str().to_lowercase();
61            *s = Symbol::intern(&lower);
62        }
63        if let Some(tool) = &mut self.tool {
64            lowercase(tool);
65        }
66        lowercase(&mut self.name);
67        self
68    }
69
70    pub fn is(&self, lint: Symbol) -> bool {
71        lint == self.name && self.tool.is_none()
72    }
73}
74
75impl fmt::Display for LintName {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        if let Some(tool) = self.tool {
78            f.write_fmt(format_args!("{0}::", tool))write!(f, "{tool}::")?
79        }
80        f.write_fmt(format_args!("{0}", self.name))write!(f, "{}", self.name)?;
81        Ok(())
82    }
83}
84
85#[cfg(feature = "nightly")]
86impl rustc_error_messages::IntoDiagArg for LintName {
87    fn into_diag_arg(
88        self,
89        _: &mut Option<std::path::PathBuf>,
90    ) -> rustc_error_messages::DiagArgValue {
91        self.to_string().into_diag_arg(&mut None)
92    }
93}