Skip to content

Commit 080e703

Browse files
committed
Auto merge of #57293 - Zoxc:incr-passes3, r=<try>
Make some lints incremental Blocked on #57253 r? @michaelwoerister
2 parents 3163c58 + 943e0b4 commit 080e703

File tree

12 files changed

+165
-54
lines changed

12 files changed

+165
-54
lines changed

src/librustc/dep_graph/dep_node.rs

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

477+
[] LintMod(DefId),
477478
[] CheckModAttrs(DefId),
478479
[] CheckModLoops(DefId),
479480
[] CheckModUnstableApiUsage(DefId),

src/librustc/hir/map/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -585,17 +585,17 @@ impl<'hir> Map<'hir> {
585585
&self.forest.krate.attrs
586586
}
587587

588-
pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId)
589-
{
588+
pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
590589
let node_id = self.as_local_node_id(module).unwrap();
590+
let hir_id = self.node_to_hir_id(node_id);
591591
self.read(node_id);
592592
match self.find_entry(node_id).unwrap().node {
593593
Node::Item(&Item {
594594
span,
595595
node: ItemKind::Mod(ref m),
596596
..
597-
}) => (m, span, node_id),
598-
Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id),
597+
}) => (m, span, hir_id),
598+
Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
599599
_ => panic!("not a module")
600600
}
601601
}
@@ -1018,7 +1018,7 @@ impl<'hir> Map<'hir> {
10181018
/// corresponding to the Node ID
10191019
pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] {
10201020
self.read(id); // reveals attributes on the node
1021-
let attrs = match self.find(id) {
1021+
let attrs = match self.find_entry(id).map(|entry| entry.node) {
10221022
Some(Node::Local(l)) => Some(&l.attrs[..]),
10231023
Some(Node::Item(i)) => Some(&i.attrs[..]),
10241024
Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
@@ -1032,6 +1032,7 @@ impl<'hir> Map<'hir> {
10321032
// unit/tuple structs take the attributes straight from
10331033
// the struct definition.
10341034
Some(Node::StructCtor(_)) => return self.attrs(self.get_parent(id)),
1035+
Some(Node::Crate) => Some(&self.forest.krate.attrs[..]),
10351036
_ => None
10361037
};
10371038
attrs.unwrap_or(&[])

src/librustc/lint/context.rs

+77-9
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
2727
use crate::session::{config, early_error, Session};
2828
use crate::ty::{self, TyCtxt, Ty};
2929
use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
30+
use crate::ty::query::Providers;
3031
use crate::util::nodemap::FxHashMap;
3132
use crate::util::common::time;
3233

@@ -36,8 +37,9 @@ use syntax::edition;
3637
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
3738
use errors::DiagnosticBuilder;
3839
use crate::hir;
39-
use crate::hir::def_id::LOCAL_CRATE;
40+
use crate::hir::def_id::{DefId, LOCAL_CRATE};
4041
use crate::hir::intravisit as hir_visit;
42+
use crate::hir::intravisit::Visitor;
4143
use syntax::util::lev_distance::find_best_match_for_name;
4244
use syntax::visit as ast_visit;
4345

@@ -55,6 +57,7 @@ pub struct LintStore {
5557
pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
5658
early_passes: Option<Vec<EarlyLintPassObject>>,
5759
late_passes: Option<Vec<LateLintPassObject>>,
60+
late_module_passes: Option<Vec<LateLintPassObject>>,
5861

5962
/// Lints indexed by name.
6063
by_name: FxHashMap<String, TargetLint>,
@@ -150,6 +153,7 @@ impl LintStore {
150153
pre_expansion_passes: Some(vec![]),
151154
early_passes: Some(vec![]),
152155
late_passes: Some(vec![]),
156+
late_module_passes: Some(vec![]),
153157
by_name: Default::default(),
154158
future_incompatible: Default::default(),
155159
lint_groups: Default::default(),
@@ -199,9 +203,14 @@ impl LintStore {
199203
pub fn register_late_pass(&mut self,
200204
sess: Option<&Session>,
201205
from_plugin: bool,
206+
per_module: bool,
202207
pass: LateLintPassObject) {
203208
self.push_pass(sess, from_plugin, &pass);
204-
self.late_passes.as_mut().unwrap().push(pass);
209+
if per_module {
210+
self.late_module_passes.as_mut().unwrap().push(pass);
211+
} else {
212+
self.late_passes.as_mut().unwrap().push(pass);
213+
}
205214
}
206215

207216
// Helper method for register_early/late_pass
@@ -508,6 +517,7 @@ pub struct LateContext<'a, 'tcx: 'a> {
508517
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
509518

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

513523
/// Parameter environment for the item we are in.
@@ -523,6 +533,9 @@ pub struct LateContext<'a, 'tcx: 'a> {
523533

524534
/// Generic type parameters in scope for the item we are in.
525535
pub generics: Option<&'tcx hir::Generics>,
536+
537+
/// We are only looking at one module
538+
only_module: bool,
526539
}
527540

528541
/// Context for lint checking of the AST, after expansion, before lowering to
@@ -803,6 +816,12 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
803816
pub fn current_lint_root(&self) -> hir::HirId {
804817
self.last_node_with_lint_attrs
805818
}
819+
820+
fn process_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: hir::HirId) {
821+
run_lints!(self, check_mod, m, s, n);
822+
hir_visit::walk_mod(self, m, n);
823+
run_lints!(self, check_mod_post, m, s, n);
824+
}
806825
}
807826

808827
impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> {
@@ -934,9 +953,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
934953
}
935954

936955
fn visit_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: hir::HirId) {
937-
run_lints!(self, check_mod, m, s, n);
938-
hir_visit::walk_mod(self, m, n);
939-
run_lints!(self, check_mod_post, m, s, n);
956+
if !self.only_module {
957+
self.process_mod(m, s, n);
958+
}
940959
}
941960

942961
fn visit_local(&mut self, l: &'tcx hir::Local) {
@@ -1201,11 +1220,48 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
12011220
}
12021221
}
12031222

1223+
pub fn lint_mod<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
1224+
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
12041225

1205-
/// Performs lint checking on a crate.
1206-
///
1207-
/// Consumes the `lint_store` field of the `Session`.
1208-
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
1226+
let store = &tcx.sess.lint_store;
1227+
let passes = store.borrow_mut().late_module_passes.take();
1228+
1229+
let mut cx = LateContext {
1230+
tcx,
1231+
tables: &ty::TypeckTables::empty(None),
1232+
param_env: ty::ParamEnv::empty(),
1233+
access_levels,
1234+
lint_sess: LintSession {
1235+
lints: store.borrow(),
1236+
passes,
1237+
},
1238+
last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(),
1239+
generics: None,
1240+
only_module: true,
1241+
};
1242+
1243+
let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
1244+
cx.process_mod(module, span, hir_id);
1245+
1246+
// Visit the crate attributes
1247+
if hir_id == hir::CRATE_HIR_ID {
1248+
walk_list!(cx, visit_attribute, cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID));
1249+
}
1250+
1251+
// Put the lint store levels and passes back in the session.
1252+
let passes = cx.lint_sess.passes;
1253+
drop(cx.lint_sess.lints);
1254+
store.borrow_mut().late_module_passes = passes;
1255+
}
1256+
1257+
pub(crate) fn provide(providers: &mut Providers<'_>) {
1258+
*providers = Providers {
1259+
lint_mod,
1260+
..*providers
1261+
};
1262+
}
1263+
1264+
fn lint_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12091265
let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
12101266

12111267
let krate = tcx.hir().krate();
@@ -1223,6 +1279,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12231279
},
12241280
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
12251281
generics: None,
1282+
only_module: false,
12261283
};
12271284

12281285
// Visit the whole crate.
@@ -1242,6 +1299,17 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
12421299
tcx.sess.lint_store.borrow_mut().late_passes = passes;
12431300
}
12441301

1302+
/// Performs lint checking on a crate.
1303+
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
1304+
// Run per-module lints
1305+
for &module in tcx.hir().krate().modules.keys() {
1306+
tcx.ensure().lint_mod(tcx.hir().local_def_id(module));
1307+
}
1308+
1309+
// Run whole crate non-incremental lints
1310+
lint_crate(tcx);
1311+
}
1312+
12451313
struct EarlyLintPassObjects<'a> {
12461314
lints: &'a mut [EarlyLintPassObject],
12471315
}

src/librustc/lint/mod.rs

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

830830
pub fn provide(providers: &mut Providers<'_>) {
831831
providers.lint_levels = lint_levels;
832+
context::provide(providers);
832833
}
833834

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

src/librustc/ty/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ define_queries! { <'tcx>
267267
},
268268

269269
Other {
270+
[] fn lint_mod: LintMod(DefId) -> (),
271+
270272
/// Checks the attributes in the module
271273
[] fn check_mod_attrs: CheckModAttrs(DefId) -> (),
272274

src/librustc/ty/query/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
12621262
DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
12631263
DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
12641264
DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
1265+
DepKind::LintMod => { force!(lint_mod, def_id!()); }
12651266
DepKind::CheckModAttrs => { force!(check_mod_attrs, def_id!()); }
12661267
DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); }
12671268
DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); }

src/librustc_interface/passes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ pub fn register_plugins<'a>(
328328
ls.register_early_pass(Some(sess), true, false, pass);
329329
}
330330
for pass in late_lint_passes {
331-
ls.register_late_pass(Some(sess), true, pass);
331+
ls.register_late_pass(Some(sess), true, false, pass);
332332
}
333333

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

src/librustc_lint/lib.rs

+43-9
Original file line numberDiff line numberDiff line change
@@ -125,37 +125,71 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
125125
store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new());
126126
}
127127

128-
late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [
128+
late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedModuleLateLintPass, [
129129
HardwiredLints: HardwiredLints,
130130
WhileTrue: WhileTrue,
131131
ImproperCTypes: ImproperCTypes,
132132
VariantSizeDifferences: VariantSizeDifferences,
133133
BoxPointers: BoxPointers,
134-
UnusedAttributes: UnusedAttributes,
135134
PathStatements: PathStatements,
135+
136+
// Depends on referenced function signatures in expressions
136137
UnusedResults: UnusedResults,
137-
NonSnakeCase: NonSnakeCase,
138+
138139
NonUpperCaseGlobals: NonUpperCaseGlobals,
139140
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
140141
UnusedAllocation: UnusedAllocation,
142+
143+
// Depends on types used in type definitions
141144
MissingCopyImplementations: MissingCopyImplementations,
142-
UnstableFeatures: UnstableFeatures,
143-
InvalidNoMangleItems: InvalidNoMangleItems,
145+
144146
PluginAsLibrary: PluginAsLibrary,
147+
148+
// Depends on referenced function signatures in expressions
145149
MutableTransmutes: MutableTransmutes,
150+
151+
// Depends on types of fields, checks if they implement Drop
146152
UnionsWithDropFields: UnionsWithDropFields,
147-
UnreachablePub: UnreachablePub,
148-
UnnameableTestItems: UnnameableTestItems::new(),
153+
149154
TypeAliasBounds: TypeAliasBounds,
155+
156+
// May Depend on constants elsewhere
150157
UnusedBrokenConst: UnusedBrokenConst,
158+
151159
TrivialConstraints: TrivialConstraints,
152160
TypeLimits: TypeLimits::new(),
161+
162+
NonSnakeCase: NonSnakeCase,
163+
InvalidNoMangleItems: InvalidNoMangleItems,
164+
165+
// Depends on access levels
166+
UnreachablePub: UnreachablePub,
167+
168+
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
169+
]], ['tcx]);
170+
171+
store.register_late_pass(sess, false, true, box BuiltinCombinedModuleLateLintPass::new());
172+
173+
late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [
174+
// Uses attr::is_used which is untracked, can't be an incremental module pass.
175+
UnusedAttributes: UnusedAttributes,
176+
177+
// Needs to run after UnusedAttributes as it marks all `feature` attributes as used.
178+
UnstableFeatures: UnstableFeatures,
179+
180+
// Tracks state across modules
181+
UnnameableTestItems: UnnameableTestItems::new(),
182+
183+
// Tracks attributes of parents
153184
MissingDoc: MissingDoc::new(),
185+
186+
// Depends on access levels
187+
// FIXME: Turn the computation of types which implement Debug into a query
188+
// and change this to a module lint pass
154189
MissingDebugImplementations: MissingDebugImplementations::new(),
155-
ExplicitOutlivesRequirements: ExplicitOutlivesRequirements,
156190
]], ['tcx]);
157191

158-
store.register_late_pass(sess, false, box BuiltinCombinedLateLintPass::new());
192+
store.register_late_pass(sess, false, false, box BuiltinCombinedLateLintPass::new());
159193

160194
add_lint_group!(sess,
161195
"nonstandard_style",

src/librustc_lint/nonstandard_style.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,15 @@ impl LintPass for NonSnakeCase {
267267
}
268268

269269
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
270-
fn check_crate(&mut self, cx: &LateContext<'_, '_>, cr: &hir::Crate) {
270+
fn check_mod(&mut self, cx: &LateContext<'_, '_>, _: &'tcx hir::Mod, _: Span, id: hir::HirId) {
271+
if id != hir::CRATE_HIR_ID {
272+
return;
273+
}
274+
271275
let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
272276
Some(Ident::from_str(name))
273277
} else {
274-
attr::find_by_name(&cr.attrs, "crate_name")
278+
attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), "crate_name")
275279
.and_then(|attr| attr.meta())
276280
.and_then(|meta| {
277281
meta.name_value_literal().and_then(|lit| {

src/librustc_privacy/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1782,8 +1782,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
17821782
current_item: hir::DUMMY_HIR_ID,
17831783
empty_tables: &empty_tables,
17841784
};
1785-
let (module, span, node_id) = tcx.hir().get_module(module_def_id);
1786-
let hir_id = tcx.hir().node_to_hir_id(node_id);
1785+
let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
17871786
intravisit::walk_mod(&mut visitor, module, hir_id);
17881787

17891788
// Check privacy of explicitly written types and traits as well as

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 {} }
17-
| ^^^^^^^^^^ help: use `loop`
16+
LL | while true {}
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 {}
29-
| ^^^^^^^^^^ help: use `loop`
28+
LL | fn foo(&self) { while true {} }
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)