Skip to main content

rustc_attr_ir/
lint.rs

1use rustc_macros::{Decodable, Encodable, PrintAttribute, StableHash};
2use rustc_span::{Ident, Span, Symbol, sym};
3
4use crate::{HashIgnoredAttrId, PrintAttribute};
5#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LintCheckKind { }
#[automatically_derived]
impl ::core::clone::Clone for LintCheckKind {
    #[inline]
    fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LintCheckKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for LintCheckKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                LintCheckKind::Allow => "Allow",
                LintCheckKind::Warn => "Warn",
                LintCheckKind::Deny => "Deny",
                LintCheckKind::Forbid => "Forbid",
                LintCheckKind::Expect => "Expect",
            })
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            LintCheckKind {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    LintCheckKind::Allow => {}
                    LintCheckKind::Warn => {}
                    LintCheckKind::Deny => {}
                    LintCheckKind::Forbid => {}
                    LintCheckKind::Expect => {}
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LintCheckKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        LintCheckKind::Allow => { 0usize }
                        LintCheckKind::Warn => { 1usize }
                        LintCheckKind::Deny => { 2usize }
                        LintCheckKind::Forbid => { 3usize }
                        LintCheckKind::Expect => { 4usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LintCheckKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { LintCheckKind::Allow }
                    1usize => { LintCheckKind::Warn }
                    2usize => { LintCheckKind::Deny }
                    3usize => { LintCheckKind::Forbid }
                    4usize => { LintCheckKind::Expect }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `LintCheckKind`, expected 0..5, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for LintCheckKind {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                match self {
                    Self::Allow => { __p.word("Allow") }
                    Self::Warn => { __p.word("Warn") }
                    Self::Deny => { __p.word("Deny") }
                    Self::Forbid => { __p.word("Forbid") }
                    Self::Expect => { __p.word("Expect") }
                }
            }
        }
    };PrintAttribute)]
6pub enum LintCheckKind {
7    Allow,
8    Warn,
9    Deny,
10    Forbid,
11    Expect,
12}
13
14impl LintCheckKind {
15    pub fn sym(self) -> Symbol {
16        match self {
17            LintCheckKind::Allow => sym::allow,
18            LintCheckKind::Warn => sym::warn,
19            LintCheckKind::Deny => sym::deny,
20            LintCheckKind::Forbid => sym::forbid,
21            LintCheckKind::Expect => sym::expect,
22        }
23    }
24}
25
26/// A lint check attribute.
27///
28/// For example `#[deny(clippy::blah, reason = "reason")]` is lowered into this.
29///
30/// These are smooshed and flattened together;
31/// ```rust
32/// #[allow(dead_code)]
33/// #[deny(unused, unsafe_code)]
34/// # const _: () = ();
35/// ```
36/// is lowered into
37/// ```text
38/// #[attr = LintCheck([
39///    LintCheck { lint_name: "dead_code", kind: Allow },
40///    LintCheck { lint_name: "unused", kind: Deny },
41///    LintCheck { lint_name: "unsafe_code", kind: Deny },
42/// ])]
43/// ```
44#[derive(#[automatically_derived]
impl ::core::clone::Clone for LintCheck {
    #[inline]
    fn clone(&self) -> Self {
        LintCheck {
            tool: ::core::clone::Clone::clone(&self.tool),
            lint_name: ::core::clone::Clone::clone(&self.lint_name),
            lint_span: ::core::clone::Clone::clone(&self.lint_span),
            kind: ::core::clone::Clone::clone(&self.kind),
            reason: ::core::clone::Clone::clone(&self.reason),
            attr_id: ::core::clone::Clone::clone(&self.attr_id),
            attr_span: ::core::clone::Clone::clone(&self.attr_span),
            rest: ::core::clone::Clone::clone(&self.rest),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for LintCheck {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["tool", "lint_name", "lint_span", "kind", "reason", "attr_id",
                        "attr_span", "rest"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.tool, &self.lint_name, &self.lint_span, &self.kind,
                        &self.reason, &self.attr_id, &self.attr_span, &&self.rest];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "LintCheck",
            names, values)
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for LintCheck {
            #[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 {
                    LintCheck {
                        tool: ref __binding_0,
                        lint_name: ref __binding_1,
                        lint_span: ref __binding_2,
                        kind: ref __binding_3,
                        reason: ref __binding_4,
                        attr_id: ref __binding_5,
                        attr_span: ref __binding_6,
                        rest: ref __binding_7 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        { __binding_5.stable_hash(__hcx, __hasher); }
                        { __binding_6.stable_hash(__hcx, __hasher); }
                        { __binding_7.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LintCheck {
            fn encode(&self, __encoder: &mut __E) {
                let LintCheck {
                        tool: ref __binding_0,
                        lint_name: ref __binding_1,
                        lint_span: ref __binding_2,
                        kind: ref __binding_3,
                        reason: ref __binding_4,
                        attr_id: ref __binding_5,
                        attr_span: ref __binding_6,
                        rest: ref __binding_7 } = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_6,
                    __encoder);
                ::rustc_serialize::Encodable::<__E>::encode(__binding_7,
                    __encoder);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LintCheck {
            fn decode(__decoder: &mut __D) -> Self {
                LintCheck {
                    tool: ::rustc_serialize::Decodable::decode(__decoder),
                    lint_name: ::rustc_serialize::Decodable::decode(__decoder),
                    lint_span: ::rustc_serialize::Decodable::decode(__decoder),
                    kind: ::rustc_serialize::Decodable::decode(__decoder),
                    reason: ::rustc_serialize::Decodable::decode(__decoder),
                    attr_id: ::rustc_serialize::Decodable::decode(__decoder),
                    attr_span: ::rustc_serialize::Decodable::decode(__decoder),
                    rest: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        #[allow(unused)]
        impl PrintAttribute for LintCheck {
            fn should_render(&self) -> bool { true }
            fn print_attribute(&self,
                __p: &mut rustc_ast_pretty::pp::Printer) {
                let Self {
                        tool,
                        lint_name,
                        lint_span,
                        kind,
                        reason,
                        attr_id,
                        attr_span,
                        rest } = self;
                __p.word("LintCheck");
                if true && !tool.should_render() && !lint_name.should_render()
                                            && !lint_span.should_render() && !kind.should_render() &&
                                    !reason.should_render() && !attr_id.should_render() &&
                            !attr_span.should_render() && !rest.should_render() {
                    return;
                }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                if tool.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("tool");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                tool.print_attribute(__p);
                if lint_name.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("lint_name");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                lint_name.print_attribute(__p);
                if lint_span.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("lint_span");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                lint_span.print_attribute(__p);
                if kind.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("kind");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                kind.print_attribute(__p);
                if reason.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("reason");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                reason.print_attribute(__p);
                if attr_id.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("attr_id");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                attr_id.print_attribute(__p);
                if attr_span.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("attr_span");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                attr_span.print_attribute(__p);
                if rest.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("rest");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                rest.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
45pub struct LintCheck {
46    /// The lint's tool name, if present.
47    pub tool: Option<Ident>,
48    /// The lint's name.
49    ///
50    /// With e.g. `clippy::blah` this will be `blah`.
51    /// Any extra segments are stored in `rest`.
52    pub lint_name: Symbol,
53    /// The span of the lint name.
54    ///
55    /// For example `#[deny(foo, bar, reason = "reason")]`
56    /// produces multiple `LintCheck`s, one with a span pointing to `foo`
57    /// and another pointing to `bar`.
58    pub lint_span: Span,
59    pub kind: LintCheckKind,
60    pub reason: Option<Symbol>,
61    /// Needed by `LintExpectationId` to track fulfilled expectations
62    pub attr_id: HashIgnoredAttrId,
63    /// The span of the attribute this lintcheck came from.
64    ///
65    /// Like mentioned above, multiple lint attributes and multiple lints
66    /// inside one attribute are all smooshed and flattened together, so
67    /// multiple `LintCheck`s can have the same `attr_span`.
68    pub attr_span: Span,
69    /// Any extra segments of the lint name (not including `tool` and `lint_name`),
70    /// this should be rare and indicates misuse of the attribute as nothing supports
71    /// 3+ segment lints like `#[allow(tool::two::three)]`.
72    pub rest: Option<Box<[Symbol]>>,
73}