Skip to content

Commit 2bbc33a

Browse files
committed
typeck: track any errors injected during writeback and taint tables appropriately.
1 parent ba72b15 commit 2bbc33a

File tree

3 files changed

+70
-6
lines changed

3 files changed

+70
-6
lines changed

src/librustc_typeck/check/writeback.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7575
wbcx.tables.upvar_list =
7676
mem::replace(&mut self.tables.borrow_mut().upvar_list, Default::default());
7777

78-
wbcx.tables.tainted_by_errors = self.is_tainted_by_errors();
78+
wbcx.tables.tainted_by_errors |= self.is_tainted_by_errors();
7979

8080
debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables);
8181

@@ -578,14 +578,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
578578
}
579579
}
580580

581-
fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T
581+
fn resolve<T>(&mut self, x: &T, span: &dyn Locatable) -> T
582582
where
583583
T: TypeFoldable<'tcx>,
584584
{
585-
let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body));
585+
let mut resolver = Resolver::new(self.fcx, span, self.body);
586+
let x = x.fold_with(&mut resolver);
586587
if cfg!(debug_assertions) && x.needs_infer() {
587588
span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x);
588589
}
590+
591+
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
592+
// to mark the `TypeckTables` as tainted in that case, so that downstream
593+
// users of the tables don't produce extra errors, or worse, ICEs.
594+
self.tables.tainted_by_errors |= resolver.replaced_with_error;
595+
589596
x
590597
}
591598
}
@@ -613,6 +620,9 @@ struct Resolver<'cx, 'tcx> {
613620
infcx: &'cx InferCtxt<'cx, 'tcx>,
614621
span: &'cx dyn Locatable,
615622
body: &'tcx hir::Body<'tcx>,
623+
624+
/// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`.
625+
replaced_with_error: bool,
616626
}
617627

618628
impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
@@ -621,7 +631,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
621631
span: &'cx dyn Locatable,
622632
body: &'tcx hir::Body<'tcx>,
623633
) -> Resolver<'cx, 'tcx> {
624-
Resolver { tcx: fcx.tcx, infcx: fcx, span, body }
634+
Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
625635
}
626636

627637
fn report_error(&self, t: Ty<'tcx>) {
@@ -644,6 +654,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
644654
Err(_) => {
645655
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
646656
self.report_error(t);
657+
self.replaced_with_error = true;
647658
self.tcx().types.err
648659
}
649660
}
@@ -661,6 +672,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
661672
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
662673
// FIXME: we'd like to use `self.report_error`, but it doesn't yet
663674
// accept a &'tcx ty::Const.
675+
self.replaced_with_error = true;
664676
self.tcx().consts.err
665677
}
666678
}

src/test/ui/issues/issue-66706.rs

+13
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,17 @@ fn b() {
1010
//~^ ERROR expected identifier, found reserved identifier `_`
1111
}
1212

13+
fn c() {
14+
[0; [|&_: _ &_| {}; 0 ].len()]
15+
//~^ ERROR expected `,`, found `&`
16+
//~| ERROR mismatched types
17+
}
18+
19+
fn d() {
20+
[0; match [|f @ &ref _| () ] {} ]
21+
//~^ ERROR expected identifier, found reserved identifier `_`
22+
//~| ERROR `match` is not allowed in a `const`
23+
//~| ERROR mismatched types
24+
}
25+
1326
fn main() {}

src/test/ui/issues/issue-66706.stderr

+41-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,29 @@ error: expected identifier, found reserved identifier `_`
1212
LL | [0; [|f @ &ref _| {} ; 0 ].len() ];
1313
| ^ expected identifier, found reserved identifier
1414

15+
error: expected `,`, found `&`
16+
--> $DIR/issue-66706.rs:14:17
17+
|
18+
LL | [0; [|&_: _ &_| {}; 0 ].len()]
19+
| -^ expected `,`
20+
| |
21+
| help: missing `,`
22+
23+
error: expected identifier, found reserved identifier `_`
24+
--> $DIR/issue-66706.rs:20:26
25+
|
26+
LL | [0; match [|f @ &ref _| () ] {} ]
27+
| ^ expected identifier, found reserved identifier
28+
29+
error[E0658]: `match` is not allowed in a `const`
30+
--> $DIR/issue-66706.rs:20:9
31+
|
32+
LL | [0; match [|f @ &ref _| () ] {} ]
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
34+
|
35+
= note: see issue #49146 <https://github.com/rust-lang/rust/issues/49146> for more information
36+
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
37+
1538
error[E0282]: type annotations needed
1639
--> $DIR/issue-66706.rs:2:11
1740
|
@@ -26,7 +49,23 @@ LL | fn a() {
2649
LL | [0; [|_: _ &_| ()].len()]
2750
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
2851

29-
error: aborting due to 4 previous errors
52+
error[E0308]: mismatched types
53+
--> $DIR/issue-66706.rs:14:5
54+
|
55+
LL | fn c() {
56+
| - help: try adding a return type: `-> [{integer}; _]`
57+
LL | [0; [|&_: _ &_| {}; 0 ].len()]
58+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
59+
60+
error[E0308]: mismatched types
61+
--> $DIR/issue-66706.rs:20:5
62+
|
63+
LL | fn d() {
64+
| - help: try adding a return type: `-> [{integer}; _]`
65+
LL | [0; match [|f @ &ref _| () ] {} ]
66+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found array `[{integer}; _]`
67+
68+
error: aborting due to 9 previous errors
3069

31-
Some errors have detailed explanations: E0282, E0308.
70+
Some errors have detailed explanations: E0282, E0308, E0658.
3271
For more information about an error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)