Skip to content

Commit 1d7ce9f

Browse files
Rollup merge of #147876 - Shunpoco:lint-check-tainted-error, r=oli-obk
Check tainted_by_error in LateLint ## Context This PR continues from #138679 (comment). In the last PR, I introduced typeck result's tainted_by_error in check_pat. But as we've discussed, I should put the check to a better place which all lints get benefit from the check. ## Change Since visit_nested_body in late.rs is the starting point of late lint for a nested body, I moved the error check to the function. I also rename one ui test case which I introduced in the last PR. I think the new name describes what the test wants to check more. This PR fixes #138361 . Note that we need to use actually_rustdoc to call typeck_body() in visit_nested_body. Otherwise rustdoc returns an error. However, as its comment describes we shouldn't use actually_rustdoc if there is an alternative solution. So far I only come up with using actually_rustdoc (this change), or checking tainted_by_error in each check_xxx functions (e.g., check on check_pat in #138679, and on check_expr for #138361).
2 parents c64de18 + db6e110 commit 1d7ce9f

7 files changed

Lines changed: 44 additions & 14 deletions

‎compiler/rustc_lint/src/builtin.rs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,7 @@ declare_lint_pass!(NonShorthandFieldPatterns => [NON_SHORTHAND_FIELD_PATTERNS]);
148148

149149
impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
150150
fn check_pat(&mut self, cx: &LateContext<'_>, pat: &hir::Pat<'_>) {
151-
// The result shouldn't be tainted, otherwise it will cause ICE.
152-
if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind
153-
&& cx.typeck_results().tainted_by_errors.is_none()
154-
{
151+
if let PatKind::Struct(ref qpath, field_pats, _) = pat.kind {
155152
let variant = cx
156153
.typeck_results()
157154
.pat_ty(pat)

‎compiler/rustc_lint/src/late.rs‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,15 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
9999
// The body and typeck results are also set in `visit_fn`.
100100
// Only fetch the results if this is for a new body.
101101
if old_enclosing_body != Some(body_id) && !self.actually_rustdoc {
102-
self.context.typeck_results = Some(self.context.tcx.typeck_body(body_id));
102+
let typeck_results = self.context.tcx.typeck_body(body_id);
103+
104+
// To avoid ICE, skip visiting the body if the typeck_results is tainted.
105+
if typeck_results.tainted_by_errors.is_some() {
106+
self.context.enclosing_body = old_enclosing_body;
107+
self.context.typeck_results = old_typeck_results;
108+
return;
109+
}
110+
self.context.typeck_results = Some(typeck_results);
103111
}
104112

105113
let body = self.context.tcx.hir_body(body_id);
@@ -189,7 +197,16 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas
189197
let old_enclosing_body = self.context.enclosing_body.replace(body_id);
190198
let old_typeck_results = self.context.typeck_results;
191199
if !self.actually_rustdoc {
192-
self.context.typeck_results = Some(self.context.tcx.typeck_body(body_id));
200+
let typeck_results = self.context.tcx.typeck_body(body_id);
201+
202+
// To avoid ICE, skip visiting the body if the typeck_results is tainted.
203+
if typeck_results.tainted_by_errors.is_some() {
204+
self.context.enclosing_body = old_enclosing_body;
205+
self.context.typeck_results = old_typeck_results;
206+
return;
207+
}
208+
209+
self.context.typeck_results = Some(typeck_results);
193210
}
194211
let body = self.context.tcx.hir_body(body_id);
195212
lint_callback!(self, check_fn, fk, decl, body, span, id);

‎tests/crashes/138361.rs‎

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.rs renamed to tests/ui/consts/long-constant-evaluation-cause-dead-code.rs

File renamed without changes.

tests/ui/consts/do-not-ice-long-constant-evaluation-in-for-loop.stderr renamed to tests/ui/consts/long-constant-evaluation-cause-dead-code.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error: constant evaluation is taking a long time
2-
--> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14
2+
--> $DIR/long-constant-evaluation-cause-dead-code.rs:10:14
33
|
44
LL | [(); loop {}];
55
| ^^^^^^^
66
|
77
= note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
88
If your compilation actually takes a long time, you can safely allow the lint
99
help: the constant being evaluated
10-
--> $DIR/do-not-ice-long-constant-evaluation-in-for-loop.rs:10:14
10+
--> $DIR/long-constant-evaluation-cause-dead-code.rs:10:14
1111
|
1212
LL | [(); loop {}];
1313
| ^^^^^^^
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// The test confirms ICE-138361 is fixed.
2+
fn main() {
3+
[0; loop{}]; //~ ERROR constant evaluation is taking a long time
4+
std::mem::transmute(4)
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error: constant evaluation is taking a long time
2+
--> $DIR/long-constant-evaluation-cause-ice-in-sty.rs:3:7
3+
|
4+
LL | [0; loop{}];
5+
| ^^^^^^
6+
|
7+
= note: this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
8+
If your compilation actually takes a long time, you can safely allow the lint
9+
help: the constant being evaluated
10+
--> $DIR/long-constant-evaluation-cause-ice-in-sty.rs:3:7
11+
|
12+
LL | [0; loop{}];
13+
| ^^^^^^
14+
= note: `#[deny(long_running_const_eval)]` on by default
15+
16+
error: aborting due to 1 previous error
17+

0 commit comments

Comments
 (0)