Skip to content

Commit bc1de3e

Browse files
committed
Auto merge of #57293 - Zoxc:incr-passes3, r=<try>
[WIP] Make some lints incremental Blocked on #57253 r? @michaelwoerister
2 parents 1bc6bae + 2f518af commit bc1de3e

File tree

10 files changed

+148
-34
lines changed

10 files changed

+148
-34
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ define_dep_nodes!( <'tcx>
472472
[] UnsafetyCheckResult(DefId),
473473
[] UnsafeDeriveOnReprPacked(DefId),
474474

475+
[] LintMod(DefId),
475476
[] CheckModAttrs(DefId),
476477
[] CheckModLoops(DefId),
477478
[] CheckModUnstableApiUsage(DefId),

src/librustc/lint/context.rs

+74-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
2727
use session::{config, early_error, Session};
2828
use ty::{self, TyCtxt, Ty};
2929
use ty::layout::{LayoutError, LayoutOf, TyLayout};
30+
use ty::query::{Providers, queries};
31+
3032
use util::nodemap::FxHashMap;
3133

3234
use std::default::Default as StdDefault;
@@ -35,6 +37,7 @@ use syntax::edition;
3537
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
3638
use errors::DiagnosticBuilder;
3739
use hir;
40+
use hir::def_id::DefId;
3841
use hir::def_id::LOCAL_CRATE;
3942
use hir::intravisit as hir_visit;
4043
use syntax::util::lev_distance::find_best_match_for_name;
@@ -54,6 +57,7 @@ pub struct LintStore {
5457
pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
5558
early_passes: Option<Vec<EarlyLintPassObject>>,
5659
late_passes: Option<Vec<LateLintPassObject>>,
60+
late_module_passes: Option<Vec<LateLintPassObject>>,
5761

5862
/// Lints indexed by name.
5963
by_name: FxHashMap<String, TargetLint>,
@@ -150,6 +154,7 @@ impl LintStore {
150154
pre_expansion_passes: Some(vec![]),
151155
early_passes: Some(vec![]),
152156
late_passes: Some(vec![]),
157+
late_module_passes: Some(vec![]),
153158
by_name: Default::default(),
154159
future_incompatible: Default::default(),
155160
lint_groups: Default::default(),
@@ -192,9 +197,14 @@ impl LintStore {
192197
pub fn register_late_pass(&mut self,
193198
sess: Option<&Session>,
194199
from_plugin: bool,
200+
per_module: bool,
195201
pass: LateLintPassObject) {
196202
self.push_pass(sess, from_plugin, &pass);
197-
self.late_passes.as_mut().unwrap().push(pass);
203+
if per_module {
204+
self.late_module_passes.as_mut().unwrap().push(pass);
205+
} else {
206+
self.late_passes.as_mut().unwrap().push(pass);
207+
}
198208
}
199209

200210
// Helper method for register_early/late_pass
@@ -501,6 +511,7 @@ pub struct LateContext<'a, 'tcx: 'a> {
501511
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
502512

503513
/// Side-tables for the body we are in.
514+
// FIXME: Make this lazy to avoid running the TypeckTables query?
504515
pub tables: &'a ty::TypeckTables<'tcx>,
505516

506517
/// Parameter environment for the item we are in.
@@ -516,6 +527,9 @@ pub struct LateContext<'a, 'tcx: 'a> {
516527

517528
/// Generic type parameters in scope for the item we are in.
518529
pub generics: Option<&'tcx hir::Generics>,
530+
531+
/// We are only looking at one module
532+
only_module: bool,
519533
}
520534

521535
/// Context for lint checking of the AST, after expansion, before lowering to
@@ -787,6 +801,12 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
787801
pub fn current_lint_root(&self) -> ast::NodeId {
788802
self.last_ast_node_with_lint_attrs
789803
}
804+
805+
fn process_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: ast::NodeId) {
806+
run_lints!(self, check_mod, m, s, n);
807+
hir_visit::walk_mod(self, m, n);
808+
run_lints!(self, check_mod_post, m, s, n);
809+
}
790810
}
791811

792812
impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> {
@@ -918,9 +938,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
918938
}
919939

920940
fn visit_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: ast::NodeId) {
921-
run_lints!(self, check_mod, m, s, n);
922-
hir_visit::walk_mod(self, m, n);
923-
run_lints!(self, check_mod_post, m, s, n);
941+
if !self.only_module {
942+
self.process_mod(m, s, n);
943+
}
924944
}
925945

926946
fn visit_local(&mut self, l: &'tcx hir::Local) {
@@ -1191,6 +1211,50 @@ impl<'a> ast_visit::Visitor<'a> for EarlyContext<'a> {
11911211
}
11921212

11931213

1214+
pub fn lint_mod<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
1215+
// Look for the parents of the module and for attributes on them
1216+
// to populate last_ast_node_with_lint_attrs
1217+
1218+
// Restricts this to only items in this module
1219+
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
1220+
1221+
let store = &tcx.sess.lint_store;
1222+
let passes = store.borrow_mut().late_module_passes.take();
1223+
1224+
let mut cx = LateContext {
1225+
tcx,
1226+
tables: &ty::TypeckTables::empty(None),
1227+
param_env: ty::ParamEnv::empty(),
1228+
access_levels,
1229+
lint_sess: LintSession {
1230+
lints: store.borrow(),
1231+
passes,
1232+
},
1233+
// Invalid for modules.
1234+
// FIXME: Have the modules require the parent module's attribute
1235+
last_ast_node_with_lint_attrs: ast::CRATE_NODE_ID,
1236+
1237+
generics: None,
1238+
1239+
only_module: true,
1240+
};
1241+
1242+
let (module, span, node_id) = tcx.hir().get_module(module_def_id);
1243+
cx.process_mod(module, span, node_id);
1244+
1245+
// Put the lint store levels and passes back in the session.
1246+
let passes = cx.lint_sess.passes;
1247+
drop(cx.lint_sess.lints);
1248+
store.borrow_mut().late_module_passes = passes;
1249+
}
1250+
1251+
pub(crate) fn provide(providers: &mut Providers<'_>) {
1252+
*providers = Providers {
1253+
lint_mod,
1254+
..*providers
1255+
};
1256+
}
1257+
11941258
/// Perform lint checking on a crate.
11951259
///
11961260
/// Consumes the `lint_store` field of the `Session`.
@@ -1212,6 +1276,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12121276
},
12131277
last_ast_node_with_lint_attrs: ast::CRATE_NODE_ID,
12141278
generics: None,
1279+
only_module: false,
12151280
};
12161281

12171282
// Visit the whole crate.
@@ -1229,6 +1294,11 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12291294

12301295
// Put the lint store levels and passes back in the session.
12311296
tcx.sess.lint_store.borrow_mut().late_passes = passes;
1297+
1298+
// Run per-module lints
1299+
for &module in tcx.hir().krate().modules.keys() {
1300+
queries::lint_mod::ensure(tcx, tcx.hir().local_def_id(module));
1301+
}
12321302
}
12331303

12341304
pub fn check_ast_crate(

src/librustc/lint/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
721721

722722
pub fn provide(providers: &mut Providers<'_>) {
723723
providers.lint_levels = lint_levels;
724+
context::provide(providers);
724725
}
725726

726727
/// Returns whether `span` originates in a foreign crate's external macro.

src/librustc/ty/context.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2835,6 +2835,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28352835
// Once red/green incremental compilation lands we should be able to
28362836
// remove this because while the crate changes often the lint level map
28372837
// will change rarely.
2838+
// FIXME: How is this correct?
2839+
// Just remove it.
28382840
self.dep_graph.with_ignore(|| {
28392841
let sets = self.lint_levels(LOCAL_CRATE);
28402842
loop {

src/librustc/ty/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ define_queries! { <'tcx>
254254
},
255255

256256
Other {
257+
[] fn lint_mod: LintMod(DefId) -> (),
258+
257259
/// Checks the attributes in the module
258260
[] fn check_mod_attrs: CheckModAttrs(DefId) -> (),
259261

src/librustc/ty/query/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
12441244
DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
12451245
DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
12461246
DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
1247+
DepKind::LintMod => { force!(lint_mod, def_id!()); }
12471248
DepKind::CheckModAttrs => { force!(check_mod_attrs, def_id!()); }
12481249
DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); }
12491250
DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); }

src/librustc_driver/driver.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,7 @@ where
901901
ls.register_early_pass(Some(sess), true, pass);
902902
}
903903
for pass in late_lint_passes {
904-
ls.register_late_pass(Some(sess), true, pass);
904+
ls.register_late_pass(Some(sess), true, false, pass);
905905
}
906906

907907
for (name, (to, deprecated_name)) in lint_groups {

src/librustc_lint/lib.rs

+45-8
Original file line numberDiff line numberDiff line change
@@ -123,37 +123,74 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
123123
DeprecatedAttr,
124124
);
125125

126-
late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [
126+
// FIXME: Make a separate lint type which do not require typeck tables
127+
128+
late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedModuleLateLintPass, [
127129
HardwiredLints: HardwiredLints,
128130
WhileTrue: WhileTrue,
129131
ImproperCTypes: ImproperCTypes,
130132
VariantSizeDifferences: VariantSizeDifferences,
131133
BoxPointers: BoxPointers,
132-
UnusedAttributes: UnusedAttributes,
133134
PathStatements: PathStatements,
134135
UnusedResults: UnusedResults,
135-
NonSnakeCase: NonSnakeCase,
136136
NonUpperCaseGlobals: NonUpperCaseGlobals,
137137
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
138138
UnusedAllocation: UnusedAllocation,
139+
140+
// Depends on types used in type definitions
139141
MissingCopyImplementations: MissingCopyImplementations,
140-
UnstableFeatures: UnstableFeatures,
141-
InvalidNoMangleItems: InvalidNoMangleItems,
142+
142143
PluginAsLibrary: PluginAsLibrary,
144+
145+
// Depends on referenced function signatures in expressions
143146
MutableTransmutes: MutableTransmutes,
147+
148+
// Depends on types of fields, checks if they implement Drop
144149
UnionsWithDropFields: UnionsWithDropFields,
145-
UnreachablePub: UnreachablePub,
146-
UnnameableTestItems: UnnameableTestItems::new(),
150+
147151
TypeAliasBounds: TypeAliasBounds,
152+
153+
// May Depend on constants elsewhere
148154
UnusedBrokenConst: UnusedBrokenConst,
155+
149156
TrivialConstraints: TrivialConstraints,
150157
TypeLimits: TypeLimits::new(),
158+
]], ['tcx]);
159+
160+
store.register_late_pass(sess, false, true, box BuiltinCombinedModuleLateLintPass::new());
161+
162+
late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [
163+
164+
// Uses attr::is_used which is untracked, can't be an incremental module pass.
165+
// Doesn't require type tables. Make a separate combined pass for that?
166+
UnusedAttributes: UnusedAttributes,
167+
168+
169+
// Checks crate attributes. Find out how that would work.
170+
NonSnakeCase: NonSnakeCase,
171+
172+
173+
// Needs to look at crate attributes. Make sure that works
174+
UnstableFeatures: UnstableFeatures,
175+
176+
// Depends on access levels
177+
InvalidNoMangleItems: InvalidNoMangleItems,
178+
179+
// Depends on access levels
180+
UnreachablePub: UnreachablePub,
181+
182+
UnnameableTestItems: UnnameableTestItems::new(),
183+
184+
// Tracks attributes of parents
151185
MissingDoc: MissingDoc::new(),
186+
187+
// Depends on access levels
152188
MissingDebugImplementations: MissingDebugImplementations::new(),
189+
153190
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
154191
]], ['tcx]);
155192

156-
store.register_late_pass(sess, false, box BuiltinCombinedLateLintPass::new());
193+
store.register_late_pass(sess, false, false, box BuiltinCombinedLateLintPass::new());
157194

158195
add_lint_group!(sess,
159196
"nonstandard_style",

src/test/ui/lint/lint-group-nonstandard-style.stderr

+13-13
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,6 @@ LL | #[forbid(nonstandard_style)]
3737
| ^^^^^^^^^^^^^^^^^
3838
= note: #[forbid(non_snake_case)] implied by #[forbid(nonstandard_style)]
3939

40-
error: static variable `bad` should have an upper case name
41-
--> $DIR/lint-group-nonstandard-style.rs:14:16
42-
|
43-
LL | static bad: isize = 1; //~ ERROR should have an upper
44-
| ^^^ help: convert the identifier to upper case: `BAD`
45-
|
46-
note: lint level defined here
47-
--> $DIR/lint-group-nonstandard-style.rs:10:14
48-
|
49-
LL | #[forbid(nonstandard_style)]
50-
| ^^^^^^^^^^^^^^^^^
51-
= note: #[forbid(non_upper_case_globals)] implied by #[forbid(nonstandard_style)]
52-
5340
warning: function `CamelCase` should have a snake case name
5441
--> $DIR/lint-group-nonstandard-style.rs:20:12
5542
|
@@ -63,5 +50,18 @@ LL | #![warn(nonstandard_style)]
6350
| ^^^^^^^^^^^^^^^^^
6451
= note: #[warn(non_snake_case)] implied by #[warn(nonstandard_style)]
6552

53+
error: static variable `bad` should have an upper case name
54+
--> $DIR/lint-group-nonstandard-style.rs:14:16
55+
|
56+
LL | static bad: isize = 1; //~ ERROR should have an upper
57+
| ^^^ help: convert the identifier to upper case: `BAD`
58+
|
59+
note: lint level defined here
60+
--> $DIR/lint-group-nonstandard-style.rs:10:14
61+
|
62+
LL | #[forbid(nonstandard_style)]
63+
| ^^^^^^^^^^^^^^^^^
64+
= note: #[forbid(non_upper_case_globals)] implied by #[forbid(nonstandard_style)]
65+
6666
error: aborting due to 3 previous errors
6767

src/test/ui/lint/lint-impl-fn.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ LL | #[deny(while_true)]
1111
| ^^^^^^^^^^
1212

1313
error: denote infinite loops with `loop { ... }`
14-
--> $DIR/lint-impl-fn.rs:18:25
14+
--> $DIR/lint-impl-fn.rs:27:5
1515
|
16-
LL | fn foo(&self) { while true {} } //~ ERROR: infinite loops
17-
| ^^^^^^^^^^ help: use `loop`
16+
LL | while true {} //~ ERROR: infinite loops
17+
| ^^^^^^^^^^ help: use `loop`
1818
|
1919
note: lint level defined here
20-
--> $DIR/lint-impl-fn.rs:13:8
20+
--> $DIR/lint-impl-fn.rs:25:8
2121
|
2222
LL | #[deny(while_true)]
2323
| ^^^^^^^^^^
2424

2525
error: denote infinite loops with `loop { ... }`
26-
--> $DIR/lint-impl-fn.rs:27:5
26+
--> $DIR/lint-impl-fn.rs:18:25
2727
|
28-
LL | while true {} //~ ERROR: infinite loops
29-
| ^^^^^^^^^^ help: use `loop`
28+
LL | fn foo(&self) { while true {} } //~ ERROR: infinite loops
29+
| ^^^^^^^^^^ help: use `loop`
3030
|
3131
note: lint level defined here
32-
--> $DIR/lint-impl-fn.rs:25:8
32+
--> $DIR/lint-impl-fn.rs:13:8
3333
|
3434
LL | #[deny(while_true)]
3535
| ^^^^^^^^^^

0 commit comments

Comments
 (0)