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#[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 Default,
24
25 Node {
27 name: LintName,
28 span: Span,
29 reason: Option<Symbol>,
31 },
32
33 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#[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 level: Level,
70
71 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 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#[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 pub specs: SortedMap<ItemLocalId, FxIndexMap<LintId, StableLevelSpec>>,
132
133 pub expectations: Vec<(StableLintExpectationId, LintExpectation)>,
136}
137
138pub 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 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 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 Level::Warn => false,
163 Level::Deny | Level::Forbid => !lint.lint.ignore_deny_warnings,
165 Level::Allow => true,
167 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 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 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 {}
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 {}
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 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#[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 pub reason: Option<Symbol>,
258 pub emission_span: Span,
260 pub is_unfulfilled_lint_expectations: bool,
264 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 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 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#[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 #[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 let future_incompatible = lint.future_incompatible;
406
407 let has_future_breakage = future_incompatible.map_or(
408 sess.opts.unstable_opts.future_incompat_test && lint.default_level != Level::Allow,
410 |incompat| incompat.report_in_deps,
411 );
412
413 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 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 && 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 let incompatible = future_incompatible.is_some_and(|f| f.reason.edition().is_none());
458
459 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 return;
475 }
476 }
477 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 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 err.disable_suggestions();
516 }
517
518 err.is_lint(lint.name_lower(), has_future_breakage, lint.rust_version);
519 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}