Skip to main content

rustc_attr_ir/
lint.rs

1use rustc_macros::{Decodable, Encodable, PrintAttribute, StableHash};
2use rustc_span::{Span, Symbol, sym};
3use rustc_structures::LintName;
4
5use crate::{HashIgnoredAttrId, PrintAttribute};
6
7#[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::debug_c_like_enum_write_str(f,
            "Allow Warn Deny Forbid Expect",
            match self {
                LintCheckKind::Allow => 0usize,
                LintCheckKind::Warn => 6usize,
                LintCheckKind::Deny => 11usize,
                LintCheckKind::Forbid => 16usize,
                LintCheckKind::Expect => 23usize,
            })
    }
}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) {
                match *self {
                    LintCheckKind::Allow => 0u8.stable_hash(__hcx, __hasher),
                    LintCheckKind::Warn => 1u8.stable_hash(__hcx, __hasher),
                    LintCheckKind::Deny => 2u8.stable_hash(__hcx, __hasher),
                    LintCheckKind::Forbid => 3u8.stable_hash(__hcx, __hasher),
                    LintCheckKind::Expect => 4u8.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)]
8pub enum LintCheckKind {
9    Allow,
10    Warn,
11    Deny,
12    Forbid,
13    Expect,
14}
15
16impl LintCheckKind {
17    pub fn sym(self) -> Symbol {
18        match self {
19            LintCheckKind::Allow => sym::allow,
20            LintCheckKind::Warn => sym::warn,
21            LintCheckKind::Deny => sym::deny,
22            LintCheckKind::Forbid => sym::forbid,
23            LintCheckKind::Expect => sym::expect,
24        }
25    }
26}
27
28/// A lint check attribute.
29///
30/// For example `#[deny(clippy::blah, reason = "reason")]` is lowered into this.
31///
32/// These are smooshed and flattened together;
33/// ```rust
34/// #[allow(dead_code)]
35/// #[deny(unused, unsafe_code)]
36/// # const _: () = ();
37/// ```
38/// is lowered into
39/// ```text
40/// #[attr = LintCheck([
41///    LintCheck { lint_name: "dead_code", kind: Allow },
42///    LintCheck { lint_name: "unused", kind: Deny },
43///    LintCheck { lint_name: "unsafe_code", kind: Deny },
44/// ])]
45/// ```
46#[derive(#[automatically_derived]impl ::core::clone::Clone for LintCheck {
    #[inline]
    fn clone(&self) -> Self {
        LintCheck {
            lint_name: ::core::clone::Clone::clone(&self.lint_name),
            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),
            lint_span: ::core::clone::Clone::clone(&self.lint_span),
            tool_span: ::core::clone::Clone::clone(&self.tool_span),
        }
    }
}Clone, #[automatically_derived]impl ::core::fmt::Debug for LintCheck {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            "LintCheck lint_name kind reason attr_id attr_span lint_span tool_span";
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.lint_name, &self.kind, &self.reason, &self.attr_id,
                        &self.attr_span, &self.lint_span, &&self.tool_span];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, 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 {
                        lint_name: ref __binding_0,
                        kind: ref __binding_1,
                        reason: ref __binding_2,
                        attr_id: ref __binding_3,
                        attr_span: ref __binding_4,
                        lint_span: ref __binding_5,
                        tool_span: ref __binding_6 } => {
                        { __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); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LintCheck {
            fn encode(&self, __encoder: &mut __E) {
                let LintCheck {
                        lint_name: ref __binding_0,
                        kind: ref __binding_1,
                        reason: ref __binding_2,
                        attr_id: ref __binding_3,
                        attr_span: ref __binding_4,
                        lint_span: ref __binding_5,
                        tool_span: ref __binding_6 } = *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);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LintCheck {
            fn decode(__decoder: &mut __D) -> Self {
                LintCheck {
                    lint_name: ::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),
                    lint_span: ::rustc_serialize::Decodable::decode(__decoder),
                    tool_span: ::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 {
                        lint_name,
                        kind,
                        reason,
                        attr_id,
                        attr_span,
                        lint_span,
                        tool_span } = self;
                __p.word("LintCheck");
                if true && !lint_name.should_render() && !kind.should_render()
                                        && !reason.should_render() && !attr_id.should_render() &&
                                !attr_span.should_render() && !lint_span.should_render() &&
                        !tool_span.should_render() {
                    return;
                }
                __p.nbsp();
                __p.word("{");
                let mut __printed_anything = false;
                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 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 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 tool_span.should_render() {
                    if __printed_anything { __p.word_space(","); }
                    __p.word("tool_span");
                    __p.word(":");
                    __p.nbsp();
                    __printed_anything = true;
                }
                tool_span.print_attribute(__p);
                __p.word("}");
            }
        }
    };PrintAttribute)]
47pub struct LintCheck {
48    pub lint_name: LintName,
49    pub kind: LintCheckKind,
50    pub reason: Option<Symbol>,
51    /// Needed by `LintExpectationId` to track fulfilled expectations
52    pub attr_id: HashIgnoredAttrId,
53    /// The span of the attribute this lintcheck came from.
54    ///
55    /// Like mentioned above, multiple lint attributes and multiple lints
56    /// inside one attribute are all smooshed and flattened together, so
57    /// multiple `LintCheck`s can have the same `attr_span`.
58    pub attr_span: Span,
59    /// The span of the entire lint name.
60    ///
61    /// #[deny(foo::bar::baz)]
62    ///        ^^^^^^^^^^^^^
63    pub lint_span: Span,
64    pub tool_span: Option<Span>,
65}