Skip to content

Commit a733192

Browse files
committed
Make rustc_hir_analysis not depend on rustc_lint.
`rustc_hir_analysis` depends on `rustc_lint` in just a single function: `emit_delayed_lint`, which is used by the "emit_ast_lowering_delayed_lints" checking section within `rustc_hir_analysis::check_crate`. This commit moves that function and section to out of `rustc_hir_analysis::check_crate`, into `rustc_interface`, eliminating the dependency. This seems reasonable because the delayed lint errors aren't really related to HIR analysis. They were in there just because HIR analysis follows AST lowering. This means `rustc_hir_analysis` and `rustc_lint` can both start compiling as soon as `rustc_trait_selection` finishes. This also changes the error order in one test, which doesn't matter. The commit also changes `emit_delayed_lint` to `emit_delayed_lints`, factoring out some code duplicated in rustdoc.
1 parent 80d0e4b commit a733192

File tree

6 files changed

+62
-73
lines changed

6 files changed

+62
-73
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4021,7 +4021,6 @@ dependencies = [
40214021
"rustc_hir",
40224022
"rustc_index",
40234023
"rustc_infer",
4024-
"rustc_lint",
40254024
"rustc_lint_defs",
40264025
"rustc_macros",
40274026
"rustc_middle",

compiler/rustc_hir_analysis/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ rustc_feature = { path = "../rustc_feature" }
1919
rustc_hir = { path = "../rustc_hir" }
2020
rustc_index = { path = "../rustc_index" }
2121
rustc_infer = { path = "../rustc_infer" }
22-
rustc_lint = { path = "../rustc_lint" }
2322
rustc_lint_defs = { path = "../rustc_lint_defs" }
2423
rustc_macros = { path = "../rustc_macros" }
2524
rustc_middle = { path = "../rustc_middle" }

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ pub use errors::NoVariantNamed;
8585
use rustc_abi::{CVariadicStatus, ExternAbi};
8686
use rustc_hir as hir;
8787
use rustc_hir::def::DefKind;
88-
use rustc_hir::lints::DelayedLint;
89-
use rustc_lint::DecorateAttrLint;
9088
use rustc_middle::mir::interpret::GlobalId;
9189
use rustc_middle::query::Providers;
9290
use rustc_middle::ty::{Const, Ty, TyCtxt};
@@ -147,23 +145,6 @@ pub fn provide(providers: &mut Providers) {
147145
};
148146
}
149147

150-
pub fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
151-
match lint {
152-
DelayedLint::AttributeParsing(attribute_lint) => {
153-
tcx.emit_node_span_lint(
154-
attribute_lint.lint_id.lint,
155-
attribute_lint.id,
156-
attribute_lint.span,
157-
DecorateAttrLint {
158-
sess: tcx.sess,
159-
tcx: Some(tcx),
160-
diagnostic: &attribute_lint.kind,
161-
},
162-
);
163-
}
164-
}
165-
}
166-
167148
pub fn check_crate(tcx: TyCtxt<'_>) {
168149
let _prof_timer = tcx.sess.timer("type_check_crate");
169150

@@ -182,42 +163,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
182163
let _: R = tcx.ensure_result().crate_inherent_impls_overlap_check(());
183164
});
184165

185-
tcx.sess.time("emit_ast_lowering_delayed_lints", || {
186-
// sanity check in debug mode that all lints are really noticed
187-
// and we really will emit them all in the loop right below.
188-
//
189-
// during ast lowering, when creating items, foreign items, trait items and impl items
190-
// we store in them whether they have any lints in their owner node that should be
191-
// picked up by `hir_crate_items`. However, theoretically code can run between that
192-
// boolean being inserted into the item and the owner node being created.
193-
// We don't want any new lints to be emitted there
194-
// (though honestly, you have to really try to manage to do that but still),
195-
// but this check is there to catch that.
196-
#[cfg(debug_assertions)]
197-
{
198-
// iterate over all owners
199-
for owner_id in tcx.hir_crate_items(()).owners() {
200-
// if it has delayed lints
201-
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
202-
if !delayed_lints.lints.is_empty() {
203-
// assert that delayed_lint_items also picked up this item to have lints
204-
assert!(
205-
tcx.hir_crate_items(()).delayed_lint_items().any(|i| i == owner_id)
206-
);
207-
}
208-
}
209-
}
210-
}
211-
212-
for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
213-
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
214-
for lint in &delayed_lints.lints {
215-
emit_delayed_lint(lint, tcx);
216-
}
217-
}
218-
}
219-
});
220-
221166
tcx.par_hir_body_owners(|item_def_id| {
222167
let def_kind = tcx.def_kind(item_def_id);
223168
// Make sure we evaluate all static and (non-associated) const items, even if unused.

compiler/rustc_interface/src/passes.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@ use rustc_hir::attrs::AttributeKind;
2121
use rustc_hir::def_id::{LOCAL_CRATE, StableCrateId, StableCrateIdMap};
2222
use rustc_hir::definitions::Definitions;
2323
use rustc_hir::limit::Limit;
24+
use rustc_hir::lints::DelayedLint;
2425
use rustc_hir::{Attribute, MaybeOwner, find_attr};
2526
use rustc_incremental::setup_dep_graph;
26-
use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store};
27+
use rustc_lint::{
28+
BufferedEarlyLint, DecorateAttrLint, EarlyCheckNode, LintStore, unerased_lint_store,
29+
};
2730
use rustc_metadata::EncodedMetadata;
2831
use rustc_metadata::creader::CStore;
2932
use rustc_middle::arena::Arena;
@@ -1025,6 +1028,29 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
10251028
)
10261029
}
10271030

1031+
pub fn emit_delayed_lints(tcx: TyCtxt<'_>) {
1032+
for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
1033+
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
1034+
for lint in &delayed_lints.lints {
1035+
match lint {
1036+
DelayedLint::AttributeParsing(attribute_lint) => {
1037+
tcx.emit_node_span_lint(
1038+
attribute_lint.lint_id.lint,
1039+
attribute_lint.id,
1040+
attribute_lint.span,
1041+
DecorateAttrLint {
1042+
sess: tcx.sess,
1043+
tcx: Some(tcx),
1044+
diagnostic: &attribute_lint.kind,
1045+
},
1046+
);
1047+
}
1048+
}
1049+
}
1050+
}
1051+
}
1052+
}
1053+
10281054
/// Runs all analyses that we guarantee to run, even if errors were reported in earlier analyses.
10291055
/// This function never fails.
10301056
fn run_required_analyses(tcx: TyCtxt<'_>) {
@@ -1074,6 +1100,32 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10741100
]);
10751101
});
10761102

1103+
sess.time("emit_ast_lowering_delayed_lints", || {
1104+
// Sanity check in debug mode that all lints are really noticed and we really will emit
1105+
// them all in the loop right below.
1106+
//
1107+
// During ast lowering, when creating items, foreign items, trait items and impl items,
1108+
// we store in them whether they have any lints in their owner node that should be
1109+
// picked up by `hir_crate_items`. However, theoretically code can run between that
1110+
// boolean being inserted into the item and the owner node being created. We don't want
1111+
// any new lints to be emitted there (you have to really try to manage that but still),
1112+
// but this check is there to catch that.
1113+
#[cfg(debug_assertions)]
1114+
{
1115+
let hir_items = tcx.hir_crate_items(());
1116+
for owner_id in hir_items.owners() {
1117+
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
1118+
if !delayed_lints.lints.is_empty() {
1119+
// Assert that delayed_lint_items also picked up this item to have lints.
1120+
assert!(hir_items.delayed_lint_items().any(|i| i == owner_id));
1121+
}
1122+
}
1123+
}
1124+
}
1125+
1126+
emit_delayed_lints(tcx);
1127+
});
1128+
10771129
rustc_hir_analysis::check_crate(tcx);
10781130
// Freeze definitions as we don't add new ones at this point.
10791131
// We need to wait until now since we synthesize a by-move body

src/librustdoc/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -904,13 +904,7 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
904904
return;
905905
}
906906

907-
for owner_id in tcx.hir_crate_items(()).delayed_lint_items() {
908-
if let Some(delayed_lints) = tcx.opt_ast_lowering_delayed_lints(owner_id) {
909-
for lint in &delayed_lints.lints {
910-
rustc_hir_analysis::emit_delayed_lint(lint, tcx);
911-
}
912-
}
913-
}
907+
rustc_interface::passes::emit_delayed_lints(tcx);
914908

915909
if render_opts.dep_info().is_some() {
916910
rustc_interface::passes::write_dep_info(tcx);

tests/ui/lint/inline-trait-and-foreign-items.stderr

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,6 @@ LL | #[inline]
3838
|
3939
= help: `#[inline]` can only be applied to functions
4040

41-
error: unconstrained opaque type
42-
--> $DIR/inline-trait-and-foreign-items.rs:26:14
43-
|
44-
LL | type U = impl Trait;
45-
| ^^^^^^^^^^
46-
|
47-
= note: `U` must be used in combination with a concrete type within the same impl
48-
4941
warning: `#[inline]` attribute cannot be used on associated consts
5042
--> $DIR/inline-trait-and-foreign-items.rs:7:5
5143
|
@@ -69,5 +61,13 @@ LL | #[inline]
6961
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
7062
= help: `#[inline]` can only be applied to functions
7163

64+
error: unconstrained opaque type
65+
--> $DIR/inline-trait-and-foreign-items.rs:26:14
66+
|
67+
LL | type U = impl Trait;
68+
| ^^^^^^^^^^
69+
|
70+
= note: `U` must be used in combination with a concrete type within the same impl
71+
7272
error: aborting due to 6 previous errors; 2 warnings emitted
7373

0 commit comments

Comments
 (0)