Skip to main content

rustc_middle/
lint.rs

1use std::cmp::min;
2
3use rustc_data_structures::fx::FxIndexMap;
4use rustc_data_structures::sorted_map::SortedMap;
5use rustc_errors::{Diag, Diagnostic, EmissionOverride, MultiSpan};
6use rustc_hir::{HirId, ItemLocalId};
7use rustc_lint_defs::{
8    EditionFcw, FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId,
9    StableLintExpectationId, UnstableLintExpectationId, builtin,
10};
11use rustc_macros::{Decodable, Encodable, StableHash};
12use rustc_session::Session;
13use rustc_span::{DUMMY_SP, ExpnKind, Span, Symbol, kw, sym};
14use rustc_structures::LintName;
15use tracing::instrument;
16
17use crate::ty::TyCtxt;
18
19/// How a lint level was set.
20#[derive(#[automatically_derived]#[doc(hidden)]unsafe impl ::core::clone::TrivialClone
    for LintLevelSource {
}
#[automatically_derived]impl ::core::clone::Clone for LintLevelSource {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<LintName>;
        let _: ::core::clone::AssertParamIsClone<Span>;
        let _: ::core::clone::AssertParamIsClone<Option<Symbol>>;
        let _: ::core::clone::AssertParamIsClone<Level>;
        *self
    }
}Clone, #[automatically_derived]impl ::core::marker::Copy for LintLevelSource { }Copy, #[automatically_derived]impl ::core::marker::StructuralPartialEq for
    LintLevelSource {
}
#[automatically_derived]impl ::core::cmp::PartialEq for LintLevelSource {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::Node { name: __self_0, span: __self_1, reason: __self_2
                    }, Self::Node {
                    name: __arg1_0, span: __arg1_1, reason: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (Self::CommandLine(__self_0, __self_1),
                    Self::CommandLine(__arg1_0, __arg1_1)) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]impl ::core::cmp::Eq for LintLevelSource {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<LintName>;
        let _: ::core::cmp::AssertParamIsEq<Span>;
        let _: ::core::cmp::AssertParamIsEq<Option<Symbol>>;
        let _: ::core::cmp::AssertParamIsEq<Level>;
    }
}Eq, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LintLevelSource {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        LintLevelSource::Default => { 0usize }
                        LintLevelSource::Node {
                            name: ref __binding_0,
                            span: ref __binding_1,
                            reason: ref __binding_2 } => {
                            1usize
                        }
                        LintLevelSource::CommandLine(ref __binding_0,
                            ref __binding_1) => {
                            2usize
                        }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    LintLevelSource::Default => {}
                    LintLevelSource::Node {
                        name: ref __binding_0,
                        span: ref __binding_1,
                        reason: ref __binding_2 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                    }
                    LintLevelSource::CommandLine(ref __binding_0,
                        ref __binding_1) => {
                        ::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 LintLevelSource {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { LintLevelSource::Default }
                    1usize => {
                        LintLevelSource::Node {
                            name: ::rustc_serialize::Decodable::decode(__decoder),
                            span: ::rustc_serialize::Decodable::decode(__decoder),
                            reason: ::rustc_serialize::Decodable::decode(__decoder),
                        }
                    }
                    2usize => {
                        LintLevelSource::CommandLine(::rustc_serialize::Decodable::decode(__decoder),
                            ::rustc_serialize::Decodable::decode(__decoder))
                    }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `LintLevelSource`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            LintLevelSource {
            #[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 {
                    LintLevelSource::Default =>
                        0u8.stable_hash(__hcx, __hasher),
                    LintLevelSource::Node {
                        name: ref __binding_0,
                        span: ref __binding_1,
                        reason: ref __binding_2 } =>
                        1u8.stable_hash(__hcx, __hasher),
                    LintLevelSource::CommandLine(ref __binding_0,
                        ref __binding_1) => 2u8.stable_hash(__hcx, __hasher),
                }
                match *self {
                    LintLevelSource::Default => {}
                    LintLevelSource::Node {
                        name: ref __binding_0,
                        span: ref __binding_1,
                        reason: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                    LintLevelSource::CommandLine(ref __binding_0,
                        ref __binding_1) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, #[automatically_derived]impl ::core::fmt::Debug for LintLevelSource {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Default => ::core::fmt::Formatter::write_str(f, "Default"),
            Self::Node { name: __self_0, span: __self_1, reason: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Node name span reason", __self_0, __self_1, &__self_2),
            Self::CommandLine(__self_0, __self_1) =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "CommandLine", __self_0, &__self_1),
        }
    }
}Debug)]
21pub enum LintLevelSource {
22    /// Lint is at the default level as declared in rustc.
23    Default,
24
25    /// Lint level was set by an attribute.
26    Node {
27        name: LintName,
28        span: Span,
29        /// RFC 2383 reason
30        reason: Option<Symbol>,
31    },
32
33    /// Lint level was set by a command-line flag.
34    /// The provided `Level` is the level specified on the command line.
35    /// (The actual level may be lower due to `--cap-lints`.)
36    CommandLine(LintName, Level),
37}
38
39impl LintLevelSource {
40    pub fn name(self) -> LintName {
41        match self {
42            LintLevelSource::Default => LintName { tool: None, name: kw::Default },
43            LintLevelSource::Node { name, .. } => name,
44            LintLevelSource::CommandLine(name, _) => name,
45        }
46    }
47
48    pub fn span(self) -> Span {
49        match self {
50            LintLevelSource::Default => DUMMY_SP,
51            LintLevelSource::Node { span, .. } => span,
52            LintLevelSource::CommandLine(_, _) => DUMMY_SP,
53        }
54    }
55}
56
57/// Convenience helper for things that are frequently used together.
58#[derive(#[automatically_derived]impl<Id: ::core::marker::Copy> ::core::marker::Copy
    for LevelSpec<Id> {
}Copy, #[automatically_derived]impl<Id: ::core::clone::Clone> ::core::clone::Clone
    for LevelSpec<Id> {
    #[inline]
    fn clone(&self) -> Self {
        LevelSpec {
            level: ::core::clone::Clone::clone(&self.level),
            lint_id: ::core::clone::Clone::clone(&self.lint_id),
            src: ::core::clone::Clone::clone(&self.src),
        }
    }
}Clone, #[automatically_derived]impl<Id: ::core::fmt::Debug> ::core::fmt::Debug for
    LevelSpec<Id> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "LevelSpec level lint_id src", &self.level, &self.lint_id,
            &&self.src)
    }
}Debug, const _: () =
    {
        impl<Id> ::rustc_data_structures::stable_hash::StableHash for
            LevelSpec<Id> where
            Id: ::rustc_data_structures::stable_hash::StableHash {
            #[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 {
                    LevelSpec {
                        level: ref __binding_0,
                        lint_id: ref __binding_1,
                        src: ref __binding_2 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<Id, __E: ::rustc_span::SpanEncoder>
            ::rustc_serialize::Encodable<__E> for LevelSpec<Id> where
            Id: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                let LevelSpec {
                        level: ref __binding_0,
                        lint_id: ref __binding_1,
                        src: ref __binding_2 } = *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);
            }
        }
    };Encodable, const _: () =
    {
        impl<Id, __D: ::rustc_span::SpanDecoder>
            ::rustc_serialize::Decodable<__D> for LevelSpec<Id> where
            Id: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                LevelSpec {
                    level: ::rustc_serialize::Decodable::decode(__decoder),
                    lint_id: ::rustc_serialize::Decodable::decode(__decoder),
                    src: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
59pub struct LevelSpec<Id = LintExpectationId> {
60    // This field *must* be private. It must be set in tandem with `lint_id`, only in
61    // `LevelSpec::new`, because only certain `level`/`lint_id` combinations are valid. See
62    // `LevelSpec::new` for those combinations.
63    //
64    // If you are thinking right now that `level` and `lint_id` should be combined into a single
65    // type that excludes the invalid combinations, that's a reasonable thought, but in practice
66    // it's painful because `level` needs to be used by itself, without `lint_id`, in many places.
67    // Making the fields private prevents invalid combinations while retaining the flexibility of
68    // two separate fields.
69    level: Level,
70
71    // This field *must* be private. See the comment on `level`.
72    lint_id: Option<Id>,
73
74    pub src: LintLevelSource,
75}
76
77pub type UnstableLevelSpec = LevelSpec<UnstableLintExpectationId>;
78pub type StableLevelSpec = LevelSpec<StableLintExpectationId>;
79
80impl<Id: Copy> LevelSpec<Id> {
81    // Panics if an invalid `level`/`lint_id` combination is given.
82    pub fn new(level: Level, lint_id: Option<Id>, src: LintLevelSource) -> LevelSpec<Id> {
83        match (level, lint_id) {
84            (Level::Allow | Level::Warn | Level::Deny | Level::Forbid, None) => {}
85            (Level::Expect, Some(_)) => {}
86            (Level::ForceWarn, _) => {}
87            _ => {
    ::core::panicking::panic_fmt(format_args!("invalid level/lint_id combination"));
}panic!("invalid level/lint_id combination"),
88        }
89        LevelSpec { level, lint_id, src }
90    }
91
92    pub fn level(self) -> Level {
93        self.level
94    }
95
96    pub fn is_allow(self) -> bool {
97        self.level == Level::Allow
98    }
99
100    pub fn is_expect(self) -> bool {
101        self.level == Level::Expect
102    }
103
104    pub fn lint_id(self) -> Option<Id> {
105        self.lint_id
106    }
107}
108
109impl From<UnstableLevelSpec> for LevelSpec {
110    fn from(level: UnstableLevelSpec) -> LevelSpec {
111        let LevelSpec { level, lint_id, src } = level;
112        let lint_id = lint_id.map(LintExpectationId::Unstable);
113        LevelSpec { level, lint_id, src }
114    }
115}
116
117impl From<StableLevelSpec> for LevelSpec {
118    fn from(level: StableLevelSpec) -> LevelSpec {
119        let LevelSpec { level, lint_id, src } = level;
120        let lint_id = lint_id.map(LintExpectationId::Stable);
121        LevelSpec { level, lint_id, src }
122    }
123}
124
125/// Return type for the `shallow_lint_levels_on` query.
126///
127/// This map represents lints levels given by the attributes for *a single HirId*.
128#[derive(#[automatically_derived]impl ::core::default::Default for ShallowLintLevelMap
    {
    #[inline]
    fn default() -> Self {
        ShallowLintLevelMap {
            specs: ::core::default::Default::default(),
            expectations: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]impl ::core::fmt::Debug for ShallowLintLevelMap {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "ShallowLintLevelMap specs expectations", &self.specs,
            &&self.expectations)
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            ShallowLintLevelMap {
            #[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 {
                    ShallowLintLevelMap {
                        specs: ref __binding_0, expectations: ref __binding_1 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
129pub struct ShallowLintLevelMap {
130    // All the specs for this HirId. This is accessed frequently, e.g. for every lint emitted.
131    pub specs: SortedMap<ItemLocalId, FxIndexMap<LintId, StableLevelSpec>>,
132
133    // Additional information about the `expect` specs for this HirId. This is consulted only once
134    // per compilation session, in `check_expectations`/`lint_expectations`.
135    pub expectations: Vec<(StableLintExpectationId, LintExpectation)>,
136}
137
138/// Verify the effect of special annotations: `warnings` lint level and lint caps.
139///
140/// The return of this function is suitable for diagnostics.
141pub fn reveal_actual_level_spec<Id: Copy>(
142    sess: &Session,
143    lint: LintId,
144    probe_for_lint_level_spec: impl Fn(LintId) -> Option<LevelSpec<Id>>,
145) -> LevelSpec<Id> {
146    let level_spec = probe_for_lint_level_spec(lint);
147
148    // If `level` is none then we actually assume the default level for this lint.
149    let mut level_spec = level_spec.unwrap_or_else(|| {
150        LevelSpec::new(lint.lint.default_level(sess.edition()), None, LintLevelSource::Default)
151    });
152
153    // If we're about to issue a warning, check at the last minute for any
154    // directives against the `warnings` lint group. If, for example, there's an
155    // `allow(warnings)` in scope then we want to respect that instead.
156    if level_spec.level == Level::Warn {
157        if let Some(configured_level_spec) =
158            probe_for_lint_level_spec(LintId::of(builtin::WARNINGS))
159        {
160            let respect_warnings_lint_group = match configured_level_spec.level {
161                // -Wwarnings is a no-op.
162                Level::Warn => false,
163                // Some warnings cannot be denied from the `warnings` lint group, only individually.
164                Level::Deny | Level::Forbid => !lint.lint.ignore_deny_warnings,
165                // All warnings respect -Awarnings.
166                Level::Allow => true,
167                // Not sure what the right behavior is here, but, sure, why not.
168                // See tests/ui/lint/rfc-2383-lint-reason/expect_warnings.rs.
169                Level::Expect => true,
170                Level::ForceWarn => {
171                    sess.dcx().delayed_bug("cannot --force-warn the `warnings` lint group");
172                    false
173                }
174            };
175            if respect_warnings_lint_group {
176                level_spec = configured_level_spec;
177            }
178        }
179    }
180
181    // Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn
182    if !#[allow(non_exhaustive_omitted_patterns)] match level_spec.src {
    LintLevelSource::CommandLine(_, Level::ForceWarn) => true,
    _ => false,
}matches!(level_spec.src, LintLevelSource::CommandLine(_, Level::ForceWarn)) {
183        level_spec.level = min(level_spec.level, sess.opts.lint_cap.unwrap_or(Level::Forbid));
184    };
185
186    // Ensure that we never exceed driver level.
187    if let Some(driver_level) = sess.driver_lint_caps.get(&lint) {
188        level_spec.level = min(level_spec.level, *driver_level);
189    }
190
191    level_spec
192}
193
194impl ShallowLintLevelMap {
195    /// Perform a deep probe in the HIR tree looking for the actual level spec for the lint.
196    /// This lint level spec is not usable for diagnostics, it needs to be corrected by
197    /// `reveal_actual_level` beforehand.
198    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("probe_for_lint_level_spec",
                                "rustc_middle::lint", ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/lint.rs"),
                                ::tracing_core::__macro_support::Option::Some(198u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_middle::lint"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("id")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("id");
                                                    NAME.as_str()
                                                },
                                                {
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("start")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("start");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&id)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&start)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: Option<StableLevelSpec> =
                            loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        if let Some(map) = self.specs.get(&start.local_id) &&
                                let Some(level_spec) = map.get(&id) {
                            return Some(*level_spec);
                        }
                        let mut owner = start.owner;
                        let mut specs = &self.specs;
                        for parent in tcx.hir_parent_id_iter(start) {
                            if parent.owner != owner {
                                owner = parent.owner;
                                specs = &tcx.shallow_lint_levels_on(owner).specs;
                            }
                            if let Some(map) = specs.get(&parent.local_id) &&
                                    let Some(level_spec) = map.get(&id) {
                                return Some(*level_spec);
                            }
                        }
                        None
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/lint.rs:198",
                        "rustc_middle::lint", ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/lint.rs"),
                        ::tracing_core::__macro_support::Option::Some(198u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::lint"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(level = "trace", skip(self, tcx), ret)]
199    fn probe_for_lint_level_spec(
200        &self,
201        tcx: TyCtxt<'_>,
202        id: LintId,
203        start: HirId,
204    ) -> Option<StableLevelSpec> {
205        if let Some(map) = self.specs.get(&start.local_id)
206            && let Some(level_spec) = map.get(&id)
207        {
208            return Some(*level_spec);
209        }
210
211        let mut owner = start.owner;
212        let mut specs = &self.specs;
213
214        for parent in tcx.hir_parent_id_iter(start) {
215            if parent.owner != owner {
216                owner = parent.owner;
217                specs = &tcx.shallow_lint_levels_on(owner).specs;
218            }
219            if let Some(map) = specs.get(&parent.local_id)
220                && let Some(level_spec) = map.get(&id)
221            {
222                return Some(*level_spec);
223            }
224        }
225
226        None
227    }
228
229    /// Fetch and return the user-visible lint level spec for the given lint at the given HirId.
230    {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
            ::tracing::Level::TRACE <=
                ::tracing::level_filters::LevelFilter::current() || { false }
    {
    __tracing_attr_span =
        {
            use ::tracing::__macro_support::Callsite as _;
            static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                {
                    static META: ::tracing::Metadata<'static> =
                        {
                            ::tracing_core::metadata::Metadata::new("lint_level_spec_at_node",
                                "rustc_middle::lint", ::tracing::Level::TRACE,
                                ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/lint.rs"),
                                ::tracing_core::__macro_support::Option::Some(230u32),
                                ::tracing_core::__macro_support::Option::Some("rustc_middle::lint"),
                                ::tracing_core::field::FieldSet::new(&[{
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("lint")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("lint");
                                                    NAME.as_str()
                                                },
                                                {
                                                    const NAME:
                                                        ::tracing::__macro_support::FieldName<{
                                                            ::tracing::__macro_support::FieldName::len("cur")
                                                        }> =
                                                        ::tracing::__macro_support::FieldName::new("cur");
                                                    NAME.as_str()
                                                }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                ::tracing::metadata::Kind::SPAN)
                        };
                    ::tracing::callsite::DefaultCallsite::new(&META)
                };
            let mut interest = ::tracing::subscriber::Interest::never();
            if ::tracing::Level::TRACE <=
                                ::tracing::level_filters::STATIC_MAX_LEVEL &&
                            ::tracing::Level::TRACE <=
                                ::tracing::level_filters::LevelFilter::current() &&
                        { interest = __CALLSITE.interest(); !interest.is_never() }
                    &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest) {
                let meta = __CALLSITE.metadata();
                ::tracing::Span::new(meta,
                    &{
                            #[allow(unused_imports)]
                            use ::tracing::field::{debug, display, Value};
                            meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&lint)
                                                        as &dyn ::tracing::field::Value)),
                                            (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&cur)
                                                        as &dyn ::tracing::field::Value))])
                        })
            } else {
                let span =
                    ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                {};
                span
            }
        };
    __tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
    (move ||
                {

                    #[allow(unknown_lints, unreachable_code, clippy ::
                    diverging_sub_expression, clippy :: empty_loop, clippy ::
                    let_unit_value, clippy :: let_with_type_underscore, clippy
                    :: needless_return, clippy :: unreachable)]
                    if false {
                        let __tracing_attr_fake_return: StableLevelSpec = loop {};
                        return __tracing_attr_fake_return;
                    }
                    {
                        reveal_actual_level_spec(tcx.sess, lint,
                            |lint| { self.probe_for_lint_level_spec(tcx, lint, cur) })
                    }
                })();
{
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/lint.rs:230",
                        "rustc_middle::lint", ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/f5cedb83a788ea9581097abc36a2a8503a7f541c/compiler/rustc_middle/src/lint.rs"),
                        ::tracing_core::__macro_support::Option::Some(230u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_middle::lint"),
                        ::tracing_core::field::FieldSet::new(&[{
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("return")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("return");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};
x;#[instrument(level = "trace", skip(self, tcx), ret)]
231    pub fn lint_level_spec_at_node(
232        &self,
233        tcx: TyCtxt<'_>,
234        lint: LintId,
235        cur: HirId,
236    ) -> StableLevelSpec {
237        reveal_actual_level_spec(tcx.sess, lint, |lint| {
238            self.probe_for_lint_level_spec(tcx, lint, cur)
239        })
240    }
241}
242
243impl TyCtxt<'_> {
244    /// Fetch and return the user-visible lint level spec for the given lint at the given HirId.
245    pub fn lint_level_spec_at_node(self, lint: &'static Lint, id: HirId) -> StableLevelSpec {
246        self.shallow_lint_levels_on(id.owner).lint_level_spec_at_node(self, LintId::of(lint), id)
247    }
248}
249
250/// This struct represents a lint expectation and holds all required information
251/// to emit the `unfulfilled_lint_expectations` lint if it is unfulfilled after
252/// the `LateLintPass` has completed.
253#[derive(#[automatically_derived]impl ::core::clone::Clone for LintExpectation {
    #[inline]
    fn clone(&self) -> Self {
        LintExpectation {
            reason: ::core::clone::Clone::clone(&self.reason),
            emission_span: ::core::clone::Clone::clone(&self.emission_span),
            is_unfulfilled_lint_expectations: ::core::clone::Clone::clone(&self.is_unfulfilled_lint_expectations),
            lint_tool: ::core::clone::Clone::clone(&self.lint_tool),
        }
    }
}Clone, #[automatically_derived]impl ::core::fmt::Debug for LintExpectation {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "LintExpectation reason emission_span is_unfulfilled_lint_expectations lint_tool",
            &self.reason, &self.emission_span,
            &self.is_unfulfilled_lint_expectations, &&self.lint_tool)
    }
}Debug, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for LintExpectation {
            fn encode(&self, __encoder: &mut __E) {
                let LintExpectation {
                        reason: ref __binding_0,
                        emission_span: ref __binding_1,
                        is_unfulfilled_lint_expectations: ref __binding_2,
                        lint_tool: ref __binding_3 } = *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);
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for LintExpectation {
            fn decode(__decoder: &mut __D) -> Self {
                LintExpectation {
                    reason: ::rustc_serialize::Decodable::decode(__decoder),
                    emission_span: ::rustc_serialize::Decodable::decode(__decoder),
                    is_unfulfilled_lint_expectations: ::rustc_serialize::Decodable::decode(__decoder),
                    lint_tool: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            LintExpectation {
            #[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 {
                    LintExpectation {
                        reason: ref __binding_0,
                        emission_span: ref __binding_1,
                        is_unfulfilled_lint_expectations: ref __binding_2,
                        lint_tool: ref __binding_3 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
254pub struct LintExpectation {
255    /// The reason for this expectation that can optionally be added as part of
256    /// the attribute. It will be displayed as part of the lint message.
257    pub reason: Option<Symbol>,
258    /// The [`Span`] of the attribute that this expectation originated from.
259    pub emission_span: Span,
260    /// Lint messages for the `unfulfilled_lint_expectations` lint will be
261    /// adjusted to include an additional note. Therefore, we have to track if
262    /// the expectation is for the lint.
263    pub is_unfulfilled_lint_expectations: bool,
264    /// This will hold the name of the tool that this lint belongs to. For
265    /// the lint `clippy::some_lint` the tool would be `clippy`, the same
266    /// goes for `rustdoc`. This will be `None` for rustc lints
267    pub lint_tool: Option<Symbol>,
268}
269
270impl LintExpectation {
271    pub fn new(
272        reason: Option<Symbol>,
273        emission_span: Span,
274        is_unfulfilled_lint_expectations: bool,
275        lint_tool: Option<Symbol>,
276    ) -> Self {
277        Self { reason, emission_span, is_unfulfilled_lint_expectations, lint_tool }
278    }
279}
280
281fn explain_lint_level_source(
282    sess: &Session,
283    lint: &'static Lint,
284    level: Level,
285    src: LintLevelSource,
286    err: &mut Diag<'_>,
287) {
288    // Find the name of the lint group that contains the given lint.
289    // Assumes the lint only belongs to one group.
290    let lint_group_name = |lint| {
291        let lint_groups_iter = sess.lint_groups_iter();
292        let lint_id = LintId::of(lint);
293        lint_groups_iter
294            .filter(|lint_group| !lint_group.is_externally_loaded)
295            .find(|lint_group| {
296                lint_group
297                    .lints
298                    .iter()
299                    .find(|lint_group_lint| **lint_group_lint == lint_id)
300                    .is_some()
301            })
302            .map(|lint_group| lint_group.name)
303    };
304    let name = LintName::from_str(&lint.name_lower());
305    if let Level::Allow = level {
306        // Do not point at `#[allow(compat_lint)]` as the reason for a compatibility lint
307        // triggering. (#121009)
308        return;
309    }
310    match src {
311        LintLevelSource::Default => {
312            let level_str = level.as_str();
313            match lint_group_name(lint) {
314                Some(group_name) => {
315                    err.note_once(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`#[{0}({1})]` (part of `#[{0}({2})]`) on by default",
                level_str, name, group_name))
    })format!("`#[{level_str}({name})]` (part of `#[{level_str}({group_name})]`) on by default"));
316                }
317                None => {
318                    err.note_once(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`#[{0}({1})]` on by default",
                level_str, name))
    })format!("`#[{level_str}({name})]` on by default"));
319                }
320            }
321        }
322        LintLevelSource::CommandLine(lint_flag_val, orig_level) => {
323            let flag = orig_level.to_cmd_flag();
324            let hyphen_case_lint_name = name.to_string().replace('_', "-");
325            if lint_flag_val == name {
326                err.note_once(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("requested on the command line with `{0} {1}`",
                flag, hyphen_case_lint_name))
    })format!(
327                    "requested on the command line with `{flag} {hyphen_case_lint_name}`"
328                ));
329            } else {
330                let hyphen_case_flag_val = lint_flag_val.to_string().replace('_', "-");
331                err.note_once(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0} {1}` implied by `{0} {2}`",
                flag, hyphen_case_lint_name, hyphen_case_flag_val))
    })format!(
332                    "`{flag} {hyphen_case_lint_name}` implied by `{flag} {hyphen_case_flag_val}`"
333                ));
334                if #[allow(non_exhaustive_omitted_patterns)] match orig_level {
    Level::Warn | Level::Deny => true,
    _ => false,
}matches!(orig_level, Level::Warn | Level::Deny) {
335                    let help = if name.is(sym::dead_code) {
336                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("to override `{0} {1}` add `#[expect({2})]` or `#[allow({2})]`",
                flag, hyphen_case_flag_val, name))
    })format!(
337                            "to override `{flag} {hyphen_case_flag_val}` add `#[expect({name})]` or `#[allow({name})]`"
338                        )
339                    } else {
340                        ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("to override `{0} {1}` add `#[allow({2})]`",
                flag, hyphen_case_flag_val, name))
    })format!(
341                            "to override `{flag} {hyphen_case_flag_val}` add `#[allow({name})]`"
342                        )
343                    };
344                    err.help_once(help);
345                }
346            }
347        }
348        LintLevelSource::Node { name: lint_attr_name, span, reason, .. } => {
349            if let Some(rationale) = reason {
350                err.note(rationale.to_string());
351            }
352            err.span_note_once(span, "the lint level is defined here");
353            if lint_attr_name != name {
354                let level_str = level.as_str();
355                err.note_once(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`#[{0}({1})]` implied by `#[{0}({2})]`",
                level_str, name, lint_attr_name))
    })format!(
356                    "`#[{level_str}({name})]` implied by `#[{level_str}({lint_attr_name})]`"
357                ));
358            }
359        }
360    }
361
362    if let Some(warnings_group) = sess
363        .opts
364        .lint_opts
365        .iter()
366        .find_map(|(opt, level)| (opt == "warnings").then_some(level))
367        .copied()
368        && warnings_group >= Level::Deny
369        && level < warnings_group
370    {
371        err.note_once(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the `{0}` lint ignores `-D warnings`",
                name))
    })format!("the `{name}` lint ignores `-D warnings`"));
372    }
373}
374
375/// The innermost function for emitting lints implementing the [`trait@Diagnostic`] trait.
376///
377/// If you are looking to implement a lint, look for higher level functions,
378/// for example:
379///
380/// - [`TyCtxt::emit_node_span_lint`]
381/// - `LintContext::opt_span_lint`
382#[track_caller]
383pub fn emit_lint_base<'a, D: Diagnostic<'a> + 'a>(
384    sess: &'a Session,
385    lint: &'static Lint,
386    level_spec: impl Into<LevelSpec>,
387    span: Option<MultiSpan>,
388    decorate: D,
389) {
390    // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
391    // the "real" work.
392    #[track_caller]
393    fn emit_lint_base_impl<'a>(
394        sess: &'a Session,
395        lint: &'static Lint,
396        level_spec: LevelSpec,
397        span: Option<MultiSpan>,
398        decorate: Box<
399            dyn FnOnce(rustc_errors::DiagCtxtHandle<'a>, rustc_errors::Level) -> Diag<'a> + 'a,
400        >,
401    ) {
402        let LevelSpec { level, lint_id, src } = level_spec;
403
404        // Check for future incompatibility lints and issue a stronger warning.
405        let future_incompatible = lint.future_incompatible;
406
407        let has_future_breakage = future_incompatible.map_or(
408            // Default allow lints trigger too often for testing.
409            sess.opts.unstable_opts.future_incompat_test && lint.default_level != Level::Allow,
410            |incompat| incompat.report_in_deps,
411        );
412
413        // Convert lint level to error level.
414        let err_level = match level {
415            Level::Allow => {
416                if has_future_breakage {
417                    rustc_errors::Level::Warning(Some(EmissionOverride::Allowed))
418                } else {
419                    return;
420                }
421            }
422            Level::Expect => {
423                // This case is special as we actually allow the lint itself in this context, but
424                // we can't return early like in the case for `Level::Allow` because we still
425                // need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`.
426                //
427                // We also cannot mark the lint expectation as fulfilled here right away, because
428                // it can still be cancelled in the decorate function. So we create a `Diag` and
429                // continue as we would for `Level::Warn`.
430                rustc_errors::Level::Warning(Some(EmissionOverride::Expected {
431                    lint_id: lint_id.unwrap(),
432                }))
433            }
434            Level::ForceWarn => {
435                rustc_errors::Level::Warning(Some(EmissionOverride::Forced { lint_id }))
436            }
437            Level::Warn => rustc_errors::Level::Warning(None),
438            Level::Deny | Level::Forbid => rustc_errors::Level::Error,
439        };
440
441        let disable_suggestions = if let Some(ref span) = span
442            // If this code originates in a foreign macro, aka something that this crate
443            // did not itself author, then it's likely that there's nothing this crate
444            // can do about it. We probably want to skip the lint entirely.
445            && span.primary_spans().iter().any(|s| s.in_external_macro(sess.source_map()))
446        {
447            true
448        } else {
449            false
450        };
451
452        if disable_suggestions {
453            // If this is a future incompatible that is not an edition fixing lint
454            // it'll become a hard error, so we have to emit *something*. Also,
455            // if this lint occurs in the expansion of a macro from an external crate,
456            // allow individual lints to opt-out from being reported.
457            let incompatible = future_incompatible.is_some_and(|f| f.reason.edition().is_none());
458
459            // In rustc, for the find_attr macro, we want to always emit this.
460            // This completely circumvents normal lint checking, which usually doesn't happen for macros from other crates.
461            // However, we kind of want that when using find_attr from another rustc crate. So we cheat a little.
462            let is_in_find_attr = sess.enable_internal_lints()
463                && span.as_ref().is_some_and(|span| {
464                    span.primary_spans().iter().any(|s| {
465                        s.source_callee().is_some_and(|i| {
466                            #[allow(non_exhaustive_omitted_patterns)] match i.kind {
    ExpnKind::Macro(_, name) if name.as_str() == "find_attr" => true,
    _ => false,
}matches!(i.kind, ExpnKind::Macro(_, name) if name.as_str() == "find_attr")
467                        })
468                    })
469                });
470
471            if !incompatible && !lint.report_in_external_macro && !is_in_find_attr {
472                // Don't continue further, since we don't want to have
473                // `diag_span_note_once` called for a diagnostic that isn't emitted.
474                return;
475            }
476        }
477        // Finally, run `decorate`. `decorate` can call `trimmed_path_str` (directly or indirectly),
478        // so we need to make sure when we do call `decorate` that the diagnostic is eventually
479        // emitted or we'll get a `must_produce_diag` ICE.
480        //
481        // When is a diagnostic *eventually* emitted? Well, that is determined by 2 factors:
482        // 1. If the corresponding `rustc_errors::Level` is beyond warning, i.e. `Error`, then the
483        //    diagnostic will be emitted regardless of CLI options.
484        // 2. If the corresponding `rustc_errors::Level` is warning, then that can be affected by
485        //    `-A warnings` or `--cap-lints=xxx` on the command line. In which case, the diagnostic
486        //    will be emitted if `can_emit_warnings` is true.
487        let skip =
488            err_level == rustc_errors::Level::Warning(None) && !sess.dcx().can_emit_warnings();
489
490        let mut err: Diag<'_> = if !skip {
491            decorate(sess.dcx(), err_level)
492        } else {
493            Diag::new(sess.dcx(), err_level, "")
494        };
495
496        if let Some(span) = span
497            && err.span.primary_span().is_none()
498        {
499            // We can't use `err.span()` because it overwrites the labels, so we need to do it
500            // manually.
501            for primary in span.primary_spans() {
502                err.span.push_primary_span(*primary);
503            }
504            for (label_span, label) in span.span_labels_raw() {
505                err.span.push_span_diag(*label_span, label.clone());
506            }
507            for span in span.span_context() {
508                err.span.push_span_context(*span);
509            }
510        }
511
512        if disable_suggestions {
513            // Any suggestions made here are likely to be incorrect, so anything we
514            // emit shouldn't be automatically fixed by rustfix.
515            err.disable_suggestions();
516        }
517
518        err.is_lint(lint.name_lower(), has_future_breakage, lint.rust_version);
519        // Lint diagnostics that are covered by the expect level will not be emitted outside
520        // the compiler. It is therefore not necessary to add any information for the user.
521        // This will therefore directly call the decorate function which will in turn emit
522        // the diagnostic.
523        if let Level::Expect = level {
524            err.emit();
525            return;
526        }
527
528        if let Some(future_incompatible) = future_incompatible {
529            let explanation = match future_incompatible.reason {
530                FutureIncompatibilityReason::FutureReleaseError(_) => {
531                    "this was previously accepted by the compiler but is being phased out; \
532                         it will become a hard error in a future release!"
533                        .to_owned()
534                }
535                FutureIncompatibilityReason::FutureReleaseSemanticsChange(_) => {
536                    "this will change its meaning in a future release!".to_owned()
537                }
538                FutureIncompatibilityReason::EditionError(EditionFcw { edition, .. }) => {
539                    let current_edition = sess.edition();
540                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this is accepted in the current edition (Rust {0}) but is a hard error in Rust {1}!",
                current_edition, edition))
    })format!(
541                        "this is accepted in the current edition (Rust {current_edition}) but is a hard error in Rust {edition}!"
542                    )
543                }
544                FutureIncompatibilityReason::EditionSemanticsChange(EditionFcw {
545                    edition, ..
546                }) => {
547                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this changes meaning in Rust {0}",
                edition))
    })format!("this changes meaning in Rust {edition}")
548                }
549                FutureIncompatibilityReason::EditionAndFutureReleaseError(EditionFcw {
550                    edition,
551                    ..
552                }) => {
553                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this was previously accepted by the compiler but is being phased out; it will become a hard error in Rust {0} and in a future release in all editions!",
                edition))
    })format!(
554                        "this was previously accepted by the compiler but is being phased out; \
555                         it will become a hard error in Rust {edition} and in a future release in all editions!"
556                    )
557                }
558                FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(
559                    EditionFcw { edition, .. },
560                ) => {
561                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this changes meaning in Rust {0} and in a future release in all editions!",
                edition))
    })format!(
562                        "this changes meaning in Rust {edition} and in a future release in all editions!"
563                    )
564                }
565                FutureIncompatibilityReason::Custom(reason, _) => reason.to_owned(),
566            };
567
568            if future_incompatible.explain_reason {
569                err.warn(explanation);
570            }
571
572            let citation =
573                ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("for more information, see {0}",
                future_incompatible.reason.reference()))
    })format!("for more information, see {}", future_incompatible.reason.reference());
574            err.note(citation);
575        }
576
577        explain_lint_level_source(sess, lint, level, src, &mut err);
578        err.emit();
579    }
580    emit_lint_base_impl(
581        sess,
582        lint,
583        level_spec.into(),
584        span,
585        Box::new(move |dcx, level| decorate.into_diag(dcx, level)),
586    );
587}