Skip to content

Commit dbb655a

Browse files
committed
Change the for-loop desugar so the break does not affect type inference. Fixes #42618
1 parent 3f8b936 commit dbb655a

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
@@ -2170,11 +2170,13 @@ impl<'a> LoweringContext<'a> {
21702170
// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
21712171
// mut iter => {
21722172
// [opt_ident]: loop {
2173-
// let <pat> = match ::std::iter::Iterator::next(&mut iter) {
2174-
// ::std::option::Option::Some(val) => val,
2173+
// let next;
2174+
// match ::std::iter::Iterator::next(&mut iter) {
2175+
// ::std::option::Option::Some(val) => next = val,
21752176
// ::std::option::Option::None => break
21762177
// };
2177-
// SemiExpr(<body>);
2178+
// let <pat> = next;
2179+
// StmtExpr(<body>);
21782180
// }
21792181
// }
21802182
// };
@@ -2186,13 +2188,18 @@ impl<'a> LoweringContext<'a> {
21862188

21872189
let iter = self.str_to_ident("iter");
21882190

2189-
// `::std::option::Option::Some(val) => val`
2191+
let next_ident = self.str_to_ident("next");
2192+
let next_pat = self.pat_ident(e.span, next_ident);
2193+
2194+
// `::std::option::Option::Some(val) => next = val`
21902195
let pat_arm = {
21912196
let val_ident = self.str_to_ident("val");
21922197
let val_pat = self.pat_ident(e.span, val_ident);
21932198
let val_expr = P(self.expr_ident(e.span, val_ident, val_pat.id));
2199+
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
2200+
let assign = P(self.expr(e.span, hir::ExprAssign(next_expr, val_expr), ThinVec::new()));
21942201
let some_pat = self.pat_some(e.span, val_pat);
2195-
self.arm(hir_vec![some_pat], val_expr)
2202+
self.arm(hir_vec![some_pat], assign)
21962203
};
21972204

21982205
// `::std::option::Option::None => break`
@@ -2222,10 +2229,20 @@ impl<'a> LoweringContext<'a> {
22222229
hir::MatchSource::ForLoopDesugar),
22232230
ThinVec::new()))
22242231
};
2232+
let match_stmt = respan(e.span, hir::StmtExpr(match_expr, self.next_id()));
2233+
2234+
let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));
2235+
2236+
// `let next`
2237+
let next_let = self.stmt_let_pat(e.span,
2238+
None,
2239+
next_pat,
2240+
hir::LocalSource::ForLoopDesugar);
22252241

2242+
// `let <pat> = next`
22262243
let pat = self.lower_pat(pat);
22272244
let pat_let = self.stmt_let_pat(e.span,
2228-
match_expr,
2245+
Some(next_expr),
22292246
pat,
22302247
hir::LocalSource::ForLoopDesugar);
22312248

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

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

22392256
// `[opt_ident]: loop { ... }`
22402257
let loop_expr = hir::ExprLoop(loop_block, self.lower_opt_sp_ident(opt_ident),
@@ -2601,14 +2618,14 @@ impl<'a> LoweringContext<'a> {
26012618

26022619
fn stmt_let_pat(&mut self,
26032620
sp: Span,
2604-
ex: P<hir::Expr>,
2621+
ex: Option<P<hir::Expr>>,
26052622
pat: P<hir::Pat>,
26062623
source: hir::LocalSource)
26072624
-> hir::Stmt {
26082625
let local = P(hir::Local {
26092626
pat: pat,
26102627
ty: None,
2611-
init: Some(ex),
2628+
init: ex,
26122629
id: self.next_id(),
26132630
span: sp,
26142631
attrs: ThinVec::new(),
@@ -2626,7 +2643,7 @@ impl<'a> LoweringContext<'a> {
26262643
self.pat_ident(sp, ident)
26272644
};
26282645
let pat_id = pat.id;
2629-
(self.stmt_let_pat(sp, ex, pat, hir::LocalSource::Normal), pat_id)
2646+
(self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), pat_id)
26302647
}
26312648

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

0 commit comments

Comments
 (0)