Skip to content

Change the for-loop desugar so the break does not affect type inference. Fixes #42618 #42634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 22, 2017
Prev Previous commit
Next Next commit
Make the next variable mutable to allow for ref mut in for patterns.
  • Loading branch information
Zoxc committed Jun 16, 2017
commit bd7cc779b65e658ff5b6bbd9d2bdd8ed07ea38f2
14 changes: 7 additions & 7 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2170,12 +2170,12 @@ impl<'a> LoweringContext<'a> {
// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
// mut iter => {
// [opt_ident]: loop {
// let next;
// let mut _next;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the _next name disable a "unused mut" warning?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does

// match ::std::iter::Iterator::next(&mut iter) {
// ::std::option::Option::Some(val) => next = val,
// ::std::option::Option::Some(val) => _next = val,
// ::std::option::Option::None => break
// };
// let <pat> = next;
// let <pat> = _next;
// StmtExpr(<body>);
// }
// }
Expand All @@ -2188,8 +2188,8 @@ impl<'a> LoweringContext<'a> {

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

let next_ident = self.str_to_ident("next");
let next_pat = self.pat_ident(e.span, next_ident);
let next_ident = self.str_to_ident("_next");
let next_pat = self.pat_ident_binding_mode(e.span, next_ident, hir::BindByValue(hir::MutMutable));

// `::std::option::Option::Some(val) => next = val`
let pat_arm = {
Expand Down Expand Up @@ -2235,13 +2235,13 @@ impl<'a> LoweringContext<'a> {

let next_expr = P(self.expr_ident(e.span, next_ident, next_pat.id));

// `let next`
// `let mut _next`
let next_let = self.stmt_let_pat(e.span,
None,
next_pat,
hir::LocalSource::ForLoopDesugar);

// `let <pat> = next`
// `let <pat> = _next`
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(e.span,
Some(next_expr),
Expand Down
15 changes: 15 additions & 0 deletions src/test/run-pass/for-loop-mut-ref-element.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Tests that for loops can bind elements as mutable references

fn main() {
for ref mut _a in std::iter::once(true) {}
}