Skip to content

Commit f15dd86

Browse files
authored
Unrolled build for rust-lang#140827
Rollup merge of rust-lang#140827 - compiler-errors:gather-locals-twice, r=oli-obk Do not ICE when reassigning in GatherLocalsVisitor on the bad path Fixes rust-lang#140785 Fixes rust-lang#140730 See comment in code. r? oli-obk
2 parents 2a5da7a + a4707a4 commit f15dd86

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

compiler/rustc_hir_typeck/src/gather_locals.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,26 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
105105
}
106106

107107
fn assign(&mut self, span: Span, nid: HirId, ty_opt: Option<Ty<'tcx>>) -> Ty<'tcx> {
108+
// We evaluate expressions twice occasionally in diagnostics for better
109+
// type information or because it needs type information out-of-order.
110+
// In order to not ICE and not lead to knock-on ambiguity errors, if we
111+
// try to re-assign a type to a local, then just take out the previous
112+
// type and delay a bug.
113+
if let Some(&local) = self.fcx.locals.borrow_mut().get(&nid) {
114+
self.fcx.dcx().span_delayed_bug(span, "evaluated expression more than once");
115+
return local;
116+
}
117+
108118
match ty_opt {
109119
None => {
110120
// Infer the variable's type.
111121
let var_ty = self.fcx.next_ty_var(span);
112-
assert_eq!(self.fcx.locals.borrow_mut().insert(nid, var_ty), None);
122+
self.fcx.locals.borrow_mut().insert(nid, var_ty);
113123
var_ty
114124
}
115125
Some(typ) => {
116126
// Take type that the user specified.
117-
assert_eq!(self.fcx.locals.borrow_mut().insert(nid, typ), None);
127+
self.fcx.locals.borrow_mut().insert(nid, typ);
118128
typ
119129
}
120130
}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/140785>.
2+
3+
fn main() {
4+
() += { let x; };
5+
//~^ ERROR binary assignment operation `+=` cannot be applied to type `()`
6+
//~| ERROR invalid left-hand side of assignment
7+
}
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0368]: binary assignment operation `+=` cannot be applied to type `()`
2+
--> $DIR/gather-locals-twice.rs:4:5
3+
|
4+
LL | () += { let x; };
5+
| --^^^^^^^^^^^^^^
6+
| |
7+
| cannot use `+=` on type `()`
8+
9+
error[E0067]: invalid left-hand side of assignment
10+
--> $DIR/gather-locals-twice.rs:4:8
11+
|
12+
LL | () += { let x; };
13+
| -- ^^
14+
| |
15+
| cannot assign to this expression
16+
17+
error: aborting due to 2 previous errors
18+
19+
Some errors have detailed explanations: E0067, E0368.
20+
For more information about an error, try `rustc --explain E0067`.

0 commit comments

Comments
 (0)