Skip to content

Commit

Permalink
librustc: Use the correct categorized mutable type for the pattern in
Browse files Browse the repository at this point in the history
`for` loop heads.

This breaks code like:

    let x = Some(box 1i);
        for &a in x.iter() {
    }

Change this code to obey the borrow checking rules. For example:

    let x = Some(box 1i);
        for &ref a in x.iter() {
    }

Closes #16205.

[breaking-change]
  • Loading branch information
pcwalton committed Aug 12, 2014
1 parent c7d0b52 commit 7579185
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -399,10 +399,16 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
ast::ExprForLoop(ref pat, ref head, ref blk, _) => {
// The pattern lives as long as the block.
debug!("walk_expr for loop case: blk id={}", blk.id);
self.walk_expr(&**head);
self.consume_expr(&**head);

let head_cmt = return_if_err!(self.mc.cat_expr(&**head));
self.walk_pat(head_cmt, pat.clone());
// Fetch the type of the value that the iteration yields to
// produce the pattern's categorized mutable type.
let pattern_type = ty::node_id_to_type(self.tcx(), pat.id);
let pat_cmt = self.mc.cat_rvalue(pat.id,
pat.span,
ty::ReScope(blk.id),
pattern_type);
self.walk_pat(pat_cmt, pat.clone());

self.walk_block(&**blk);
}
Expand Down Expand Up @@ -835,6 +841,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
}
ast::PatIdent(ast::BindByValue(_), _, _) => {
let mode = copy_or_move(typer.tcx(), cmt_pat.ty, PatBindingMove);
debug!("walk_pat binding consuming pat");
delegate.consume_pat(pat, cmt_pat, mode);
}
_ => {
Expand Down
33 changes: 33 additions & 0 deletions src/test/compile-fail/borrowck-for-loop-correct-cmt-for-pattern.rs
@@ -0,0 +1,33 @@
// 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.

// Issue #16205.

struct Foo {
a: [Box<int>, ..3],
}

fn main() {
let mut y = 1i;
let x = Some(&mut y);
for &a in x.iter() { //~ ERROR cannot move out
}

let f = Foo {
a: [box 3, box 4, box 5],
};
for &a in f.a.iter() { //~ ERROR cannot move out
}

let x = Some(box 1i);
for &a in x.iter() { //~ ERROR cannot move out
}
}

5 comments on commit 7579185

@bors
Copy link
Contributor

@bors bors commented on 7579185 Aug 13, 2014

Choose a reason for hiding this comment

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

saw approval from nikomatsakis
at pcwalton@7579185

@bors
Copy link
Contributor

@bors bors commented on 7579185 Aug 13, 2014

Choose a reason for hiding this comment

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

merging pcwalton/rust/borrowck-for-moves = 7579185 into auto

@bors
Copy link
Contributor

@bors bors commented on 7579185 Aug 13, 2014

Choose a reason for hiding this comment

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

pcwalton/rust/borrowck-for-moves = 7579185 merged ok, testing candidate = ee87234

@bors
Copy link
Contributor

@bors bors commented on 7579185 Aug 13, 2014

Choose a reason for hiding this comment

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

fast-forwarding master to auto = ee87234

Please sign in to comment.