Skip to content

Commit 21b276f

Browse files
Zoxcbrson
authored andcommitted
Change the for-loop desugar so the break does not affect type inference. Fixes rust-lang#42618
1 parent 785e82c commit 21b276f

File tree

2 files changed

+31
-12
lines changed

2 files changed

+31
-12
lines changed

src/libcore/iter/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,12 @@
191191
//! {
192192
//! let result = match IntoIterator::into_iter(values) {
193193
//! mut iter => loop {
194-
//! let x = match iter.next() {
195-
//! Some(val) => val,
194+
//! let next;
195+
//! match iter.next() {
196+
//! Some(val) => next = val,
196197
//! None => break,
197198
//! };
199+
//! let x = next;
198200
//! let () = { println!("{}", x); };
199201
//! },
200202
//! };

src/librustc/hir/lowering.rs

+27-10
Original file line numberDiff line numberDiff line change
@@ -2168,11 +2168,13 @@ impl<'a> LoweringContext<'a> {
21682168
// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
21692169
// mut iter => {
21702170
// [opt_ident]: loop {
2171-
// let <pat> = match ::std::iter::Iterator::next(&mut iter) {
2172-
// ::std::option::Option::Some(val) => val,
2171+
// let next;
2172+
// match ::std::iter::Iterator::next(&mut iter) {
2173+
// ::std::option::Option::Some(val) => next = val,
21732174
// ::std::option::Option::None => break
21742175
// };
2175-
// SemiExpr(<body>);
2176+
// let <pat> = next;
2177+
// StmtExpr(<body>);
21762178
// }
21772179
// }
21782180
// };
@@ -2184,13 +2186,18 @@ impl<'a> LoweringContext<'a> {
21842186

21852187
let iter = self.str_to_ident("iter");
21862188

2187-
// `::std::option::Option::Some(val) => val`
2189+
let next_ident = self.str_to_ident("next");
2190+
let next_pat = self.pat_ident(e.span, next_ident);
2191+
2192+
// `::std::option::Option::Some(val) => next = val`
21882193
let pat_arm = {
21892194
let val_ident = self.str_to_ident("val");
21902195
let val_pat = self.pat_ident(e.span, val_ident);
21912196
let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id));
2197+
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
2198+
let assign = P(self.expr(e.span, hir::ExprAssign(next_expr, val_expr), ThinVec::new()));
21922199
let some_pat = self.pat_some(e.span, val_pat);
2193-
self.arm(hir_vec![some_pat], val_expr)
2200+
self.arm(hir_vec![some_pat], assign)
21942201
};
21952202

21962203
// `::std::option::Option::None => break`
@@ -2220,10 +2227,20 @@ impl<'a> LoweringContext<'a> {
22202227
hir::MatchSource::ForLoopDesugar),
22212228
ThinVec::new()))
22222229
};
2230+
let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id()));
2231+
2232+
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
2233+
2234+
// `let next`
2235+
let next_let = self.stmt_let_pat(e.span,
2236+
None,
2237+
next_pat,
2238+
hir::LocalSource::ForLoopDesugar);
22232239

2240+
// `let <pat> = next`
22242241
let pat = self.lower_pat(pat);
22252242
let pat_let = self.stmt_let_pat(e.span,
2226-
match_expr,
2243+
Some(next_expr),
22272244
pat,
22282245
hir::LocalSource::ForLoopDesugar);
22292246

@@ -2232,7 +2249,7 @@ impl<'a> LoweringContext<'a> {
22322249
let body_expr = P(self.expr_block(body_block, ThinVec::new()));
22332250
let body_stmt = respan(e.span, hir::StmtExpr(body_expr, self.next_id()));
22342251

2235-
let loop_block = P(self.block_all(e.span, hir_vec![pat_let, body_stmt], None));
2252+
let loop_block = P(self.block_all(e.span, hir_vec![next_let, match_stmt, pat_let, body_stmt], None));
22362253

22372254
// `[opt_ident]: loop { ... }`
22382255
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
@@ -2599,14 +2616,14 @@ impl<'a> LoweringContext<'a> {
25992616

26002617
fn stmt_let_pat(&mut self,
26012618
sp: Span,
2602-
ex: P<hir::Expr>,
2619+
ex: Option<P<hir::Expr>>,
26032620
pat: P<hir::Pat>,
26042621
source: hir::LocalSource)
26052622
-> hir::Stmt {
26062623
let local = P(hir::Local {
26072624
pat: pat,
26082625
ty: None,
2609-
init: Some(ex),
2626+
init: ex,
26102627
id: self.next_id(),
26112628
span: sp,
26122629
attrs: ThinVec::new(),
@@ -2624,7 +2641,7 @@ impl<'a> LoweringContext<'a> {
26242641
self.pat_ident(sp, ident)
26252642
};
26262643
let pat_id = pat.id;
2627-
(self.stmt_let_pat(sp, ex, pat, hir::LocalSource::Normal), pat_id)
2644+
(self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), pat_id)
26282645
}
26292646

26302647
fn block_expr(&mut self, expr: P<hir::Expr>) -> hir::Block {

0 commit comments

Comments
 (0)