Skip to content

Commit c86bd14

Browse files
committed
Do not run lints that cannot emit
1 parent 030a12c commit c86bd14

File tree

22 files changed

+5827
-51
lines changed

22 files changed

+5827
-51
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ Session.vim
3030
!/tests/run-make/thumb-none-qemu/example/.cargo
3131

3232
## Configuration
33-
/config.toml
3433
/Makefile
3534
config.mk
3635
config.stamp

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4342,6 +4342,7 @@ dependencies = [
43424342
"rustc_hir",
43434343
"rustc_hir_pretty",
43444344
"rustc_index",
4345+
"rustc_lint_defs",
43454346
"rustc_macros",
43464347
"rustc_query_system",
43474348
"rustc_serialize",

compiler/rustc_builtin_macros/src/compile_error.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ pub(crate) fn expand_compile_error<'cx>(
1818
Err(guar) => return ExpandResult::Ready(DummyResult::any(sp, guar)),
1919
};
2020

21-
#[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")]
22-
#[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
21+
// #[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")]
22+
// #[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
2323
let guar = cx.dcx().span_err(sp, var.to_string());
2424

2525
ExpandResult::Ready(DummyResult::any(sp, guar))

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,10 @@ pub(crate) struct EnvNotDefinedWithUserMessage {
428428
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessage {
429429
#[track_caller]
430430
fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
431-
#[expect(
432-
rustc::untranslatable_diagnostic,
433-
reason = "cannot translate user-provided messages"
434-
)]
431+
// #[expect(
432+
// rustc::untranslatable_diagnostic,
433+
// reason = "cannot translate user-provided messages"
434+
// )]
435435
let mut diag = Diag::new(dcx, level, self.msg_from_user.to_string());
436436
diag.span(self.span);
437437
diag

compiler/rustc_lint/src/builtin.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy};
7474
use crate::nonstandard_style::{method_context, MethodLateContext};
7575

7676
use std::fmt::Write;
77+
use std::default::Default;
7778

7879
// hardwired lints from rustc_lint_defs
7980
pub use rustc_session::lint::builtin::*;
@@ -462,6 +463,7 @@ declare_lint! {
462463
report_in_external_macro
463464
}
464465

466+
#[derive(Default)]
465467
pub struct MissingDoc;
466468

467469
impl_lint_pass!(MissingDoc => [MISSING_DOCS]);
@@ -903,8 +905,8 @@ pub struct DeprecatedAttr {
903905

904906
impl_lint_pass!(DeprecatedAttr => []);
905907

906-
impl DeprecatedAttr {
907-
pub fn new() -> DeprecatedAttr {
908+
impl Default for DeprecatedAttr {
909+
fn default() -> Self {
908910
DeprecatedAttr { depr_attrs: deprecated_attributes() }
909911
}
910912
}

compiler/rustc_lint/src/early.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@ impl LintPass for RuntimeCombinedEarlyLintPass<'_> {
316316
fn name(&self) -> &'static str {
317317
panic!()
318318
}
319+
fn get_lints(&self) -> crate::LintVec {
320+
panic!()
321+
}
319322
}
320323

321324
macro_rules! impl_early_lint_pass {

compiler/rustc_lint/src/late.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//! upon. As the ast is traversed, this keeps track of the current lint level
1515
//! for all lint attributes.
1616
17-
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore};
17+
use crate::{passes::LateLintPassObject, LateContext, LateLintPass, LintStore, LintId};
1818
use rustc_data_structures::stack::ensure_sufficient_stack;
1919
use rustc_data_structures::sync::{join, Lrc};
2020
use rustc_hir as hir;
@@ -325,6 +325,9 @@ impl LintPass for RuntimeCombinedLateLintPass<'_, '_> {
325325
fn name(&self) -> &'static str {
326326
panic!()
327327
}
328+
fn get_lints(&self) -> crate::LintVec {
329+
panic!()
330+
}
328331
}
329332

330333
macro_rules! impl_late_lint_pass {
@@ -360,13 +363,22 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
360363
// Note: `passes` is often empty. In that case, it's faster to run
361364
// `builtin_lints` directly rather than bundling it up into the
362365
// `RuntimeCombinedLateLintPass`.
363-
let late_module_passes = &unerased_lint_store(tcx.sess).late_module_passes;
364-
if late_module_passes.is_empty() {
365-
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
366-
} else {
367-
let mut passes: Vec<_> = late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
368-
passes.push(Box::new(builtin_lints));
369-
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
366+
let store = unerased_lint_store(tcx.sess);
367+
368+
if store.late_module_passes.is_empty() {
369+
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
370+
} else {
371+
let passes: Vec<_> = store
372+
.late_module_passes
373+
.iter()
374+
.map(|mk_pass| (mk_pass)(tcx))
375+
.collect();
376+
let emittable_lints = tcx.lints_that_can_emit(());
377+
let mut filtered_passes: Vec<Box<dyn LateLintPass<'tcx>>> = passes.into_iter().filter(|pass| {
378+
LintPass::get_lints(pass).iter().any(|&lint| emittable_lints.contains(&LintId::of(lint)))
379+
}).collect();
380+
filtered_passes.push(Box::new(builtin_lints));
381+
let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] };
370382
late_lint_mod_inner(tcx, module_def_id, context, pass);
371383
}
372384
}
@@ -397,7 +409,7 @@ fn late_lint_mod_inner<'tcx, T: LateLintPass<'tcx>>(
397409

398410
fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) {
399411
// Note: `passes` is often empty.
400-
let mut passes: Vec<_> =
412+
let passes: Vec<_> =
401413
unerased_lint_store(tcx.sess).late_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
402414

403415
if passes.is_empty() {
@@ -415,7 +427,20 @@ fn late_lint_crate<'tcx>(tcx: TyCtxt<'tcx>) {
415427
only_module: false,
416428
};
417429

418-
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
430+
let hashmap = tcx.lints_that_can_emit(());
431+
432+
let mut filtered_passes: Vec<Box<dyn LateLintPass<'tcx>>> = passes.into_iter().filter(|pass| {
433+
LintPass::get_lints(pass).iter().any(|&lint| hashmap.contains(&LintId::of(lint)))
434+
}).collect();
435+
436+
// let mut passes: Vec<std::boxed::Box<dyn LateLintPass<'tcx>>> = passes
437+
// .into_iter()
438+
// .filter(|pass| {
439+
// LintPass::get_lints(pass).iter().any(|&lint| )
440+
// })
441+
// .collect();
442+
443+
let pass = RuntimeCombinedLateLintPass { passes: &mut filtered_passes[..] };
419444
late_lint_crate_inner(tcx, context, pass);
420445
}
421446

compiler/rustc_lint/src/levels.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,42 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
151151
builder.provider.expectations
152152
}
153153

154+
/// Walk the whole crate collecting nodes where lint levels change
155+
/// (e.g. `#[allow]` attributes), and joins that list with the warn-by-default
156+
/// (and not allowed in the crate) and CLI lints. The final result is a builder
157+
/// that has information about just lints that can be emitted (leaving out
158+
/// globally-allowed lints)
159+
pub fn lints_that_can_emit(
160+
tcx: TyCtxt<'_>,
161+
(): ()
162+
) -> Vec<LintId> {
163+
let store = unerased_lint_store(&tcx.sess);
164+
165+
// let mut builder = LintLevelsBuilder {
166+
// sess: tcx.sess,
167+
// features: tcx.features(),
168+
// provider:
169+
// warn_about_weird_lints: false,
170+
// store,
171+
// registered_tools: &tcx.registered_tools(()),
172+
// };
173+
let specs = tcx.shallow_lint_levels_on(hir::CRATE_HIR_ID.owner);
174+
let lints = store.get_lints();
175+
176+
let mut hashmap: Vec<LintId> = Vec::new();
177+
hashmap.reserve((lints.len() >> 1) * usize::from(tcx.sess.opts.lint_cap.is_some())); // Avoid allocations, it's better to
178+
179+
for &lint in lints {
180+
let lint_id = LintId::of(lint);
181+
let actual_level = specs.probe_for_lint_level(tcx, lint_id, hir::CRATE_HIR_ID).0.unwrap_or(lint.default_level);
182+
if actual_level > Level::Allow {
183+
hashmap.push(lint_id);
184+
}
185+
}
186+
187+
hashmap
188+
}
189+
154190
#[instrument(level = "trace", skip(tcx), ret)]
155191
fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap {
156192
let store = unerased_lint_store(tcx.sess);
@@ -253,7 +289,7 @@ impl LintLevelsProvider for LintLevelQueryMap<'_> {
253289
}
254290
}
255291

256-
struct QueryMapExpectationsWrapper<'tcx> {
292+
pub(crate) struct QueryMapExpectationsWrapper<'tcx> {
257293
tcx: TyCtxt<'tcx>,
258294
/// HirId of the currently investigated element.
259295
cur: HirId,
@@ -1133,7 +1169,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
11331169
}
11341170

11351171
pub(crate) fn provide(providers: &mut Providers) {
1136-
*providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers };
1172+
*providers = Providers { shallow_lint_levels_on, lint_expectations, lints_that_can_emit, ..*providers };
11371173
}
11381174

11391175
pub fn parse_lint_and_tool_name(lint_name: &str) -> (Option<Symbol>, &str) {

compiler/rustc_lint/src/lib.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#![feature(rustdoc_internals)]
3131
#![feature(array_windows)]
3232
#![feature(box_patterns)]
33+
#![feature(box_into_inner)]
3334
#![feature(control_flow_enum)]
3435
#![feature(extract_if)]
3536
#![feature(if_let_guard)]
@@ -136,6 +137,9 @@ pub fn provide(providers: &mut Providers) {
136137
}
137138

138139
fn lint_mod(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
140+
if let Some(lint_cap) = tcx.sess.opts.lint_cap && lint_cap == Level::Allow {
141+
return;
142+
}
139143
late_lint_mod(tcx, module_def_id, BuiltinCombinedModuleLateLintPass::new());
140144
}
141145

@@ -154,15 +158,15 @@ early_lint_methods!(
154158
[
155159
pub BuiltinCombinedEarlyLintPass,
156160
[
157-
UnusedParens: UnusedParens::new(),
161+
UnusedParens: UnusedParens::default(),
158162
UnusedBraces: UnusedBraces,
159163
UnusedImportBraces: UnusedImportBraces,
160164
UnsafeCode: UnsafeCode,
161165
SpecialModuleName: SpecialModuleName,
162166
AnonymousParameters: AnonymousParameters,
163167
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
164168
NonCamelCaseTypes: NonCamelCaseTypes,
165-
DeprecatedAttr: DeprecatedAttr::new(),
169+
DeprecatedAttr: DeprecatedAttr::default(),
166170
WhileTrue: WhileTrue,
167171
NonAsciiIdents: NonAsciiIdents,
168172
HiddenUnicodeCodepoints: HiddenUnicodeCodepoints,
@@ -542,23 +546,23 @@ fn register_builtins(store: &mut LintStore) {
542546
}
543547

544548
fn register_internals(store: &mut LintStore) {
545-
store.register_lints(&LintPassImpl::get_lints());
549+
store.register_lints(&LintPassImpl::default().get_lints());
546550
store.register_early_pass(|| Box::new(LintPassImpl));
547-
store.register_lints(&DefaultHashTypes::get_lints());
551+
store.register_lints(&DefaultHashTypes::default().get_lints());
548552
store.register_late_mod_pass(|_| Box::new(DefaultHashTypes));
549-
store.register_lints(&QueryStability::get_lints());
553+
store.register_lints(&QueryStability::default().get_lints());
550554
store.register_late_mod_pass(|_| Box::new(QueryStability));
551-
store.register_lints(&ExistingDocKeyword::get_lints());
555+
store.register_lints(&ExistingDocKeyword::default().get_lints());
552556
store.register_late_mod_pass(|_| Box::new(ExistingDocKeyword));
553-
store.register_lints(&TyTyKind::get_lints());
557+
store.register_lints(&TyTyKind::default().get_lints());
554558
store.register_late_mod_pass(|_| Box::new(TyTyKind));
555-
store.register_lints(&Diagnostics::get_lints());
559+
store.register_lints(&Diagnostics::default().get_lints());
556560
store.register_late_mod_pass(|_| Box::new(Diagnostics));
557-
store.register_lints(&BadOptAccess::get_lints());
561+
store.register_lints(&BadOptAccess::default().get_lints());
558562
store.register_late_mod_pass(|_| Box::new(BadOptAccess));
559-
store.register_lints(&PassByValue::get_lints());
563+
store.register_lints(&PassByValue::default().get_lints());
560564
store.register_late_mod_pass(|_| Box::new(PassByValue));
561-
store.register_lints(&SpanUseEqCtxt::get_lints());
565+
store.register_lints(&SpanUseEqCtxt::default().get_lints());
562566
store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt));
563567
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
564568
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and

compiler/rustc_lint/src/passes.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ macro_rules! declare_combined_late_lint_pass {
108108

109109
$v fn get_lints() -> $crate::LintVec {
110110
let mut lints = Vec::new();
111-
$(lints.extend_from_slice(&$pass::get_lints());)*
111+
$(lints.extend_from_slice(&$pass::default().get_lints());)*
112112
lints
113113
}
114114
}
@@ -122,6 +122,9 @@ macro_rules! declare_combined_late_lint_pass {
122122
fn name(&self) -> &'static str {
123123
panic!()
124124
}
125+
fn get_lints(&self) -> LintVec {
126+
panic!()
127+
}
125128
}
126129
)
127130
}
@@ -218,7 +221,7 @@ macro_rules! declare_combined_early_lint_pass {
218221

219222
$v fn get_lints() -> $crate::LintVec {
220223
let mut lints = Vec::new();
221-
$(lints.extend_from_slice(&$pass::get_lints());)*
224+
$(lints.extend_from_slice(&$pass::default().get_lints());)*
222225
lints
223226
}
224227
}
@@ -232,6 +235,9 @@ macro_rules! declare_combined_early_lint_pass {
232235
fn name(&self) -> &'static str {
233236
panic!()
234237
}
238+
fn get_lints(&self) -> LintVec {
239+
panic!()
240+
}
235241
}
236242
)
237243
}

compiler/rustc_lint/src/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ declare_lint! {
170170
"detects ambiguous wide pointer comparisons"
171171
}
172172

173-
#[derive(Copy, Clone)]
173+
#[derive(Copy, Clone, Default)]
174174
pub struct TypeLimits {
175175
/// Id of the last visited negated expression
176176
negated_expr_id: Option<hir::HirId>,

compiler/rustc_lint/src/unused.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,8 +1018,8 @@ pub struct UnusedParens {
10181018
parens_in_cast_in_lt: Vec<ast::NodeId>,
10191019
}
10201020

1021-
impl UnusedParens {
1022-
pub fn new() -> Self {
1021+
impl Default for UnusedParens {
1022+
fn default() -> Self {
10231023
Self { with_self_ty_parens: false, parens_in_cast_in_lt: Vec::new() }
10241024
}
10251025
}

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,7 @@ pub type LintVec = Vec<&'static Lint>;
870870

871871
pub trait LintPass {
872872
fn name(&self) -> &'static str;
873+
fn get_lints(&self) -> LintVec;
873874
}
874875

875876
/// Implements `LintPass for $ty` with the given list of `Lint` statics.
@@ -878,9 +879,7 @@ macro_rules! impl_lint_pass {
878879
($ty:ty => [$($lint:expr),* $(,)?]) => {
879880
impl $crate::LintPass for $ty {
880881
fn name(&self) -> &'static str { stringify!($ty) }
881-
}
882-
impl $ty {
883-
pub fn get_lints() -> $crate::LintVec { vec![$($lint),*] }
882+
fn get_lints(&self) -> $crate::LintVec { vec![$($lint),*] }
884883
}
885884
};
886885
}
@@ -890,7 +889,18 @@ macro_rules! impl_lint_pass {
890889
#[macro_export]
891890
macro_rules! declare_lint_pass {
892891
($(#[$m:meta])* $name:ident => [$($lint:expr),* $(,)?]) => {
893-
$(#[$m])* #[derive(Copy, Clone)] pub struct $name;
892+
$(#[$m])* #[derive(Copy, Clone, Default)] pub struct $name;
894893
$crate::impl_lint_pass!($name => [$($lint),*]);
895894
};
896895
}
896+
897+
#[allow(rustc::lint_pass_impl_without_macro)]
898+
impl<P: LintPass + ?Sized> LintPass for Box<P> {
899+
fn name(&self) -> &'static str {
900+
(**self).name()
901+
}
902+
903+
fn get_lints(&self) -> LintVec {
904+
(**self).get_lints()
905+
}
906+
}

compiler/rustc_middle/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ rustc_graphviz = { path = "../rustc_graphviz" }
2727
rustc_hir = { path = "../rustc_hir" }
2828
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
2929
rustc_index = { path = "../rustc_index" }
30+
rustc_lint_defs = { path = "../rustc_lint_defs" }
3031
rustc_macros = { path = "../rustc_macros" }
3132
rustc_query_system = { path = "../rustc_query_system" }
3233
rustc_serialize = { path = "../rustc_serialize" }

0 commit comments

Comments
 (0)