,
+ ex: Option>,
pat: P,
source: hir::LocalSource)
-> hir::Stmt {
let local = P(hir::Local {
pat: pat,
ty: None,
- init: Some(ex),
+ init: ex,
id: self.next_id(),
span: sp,
attrs: ThinVec::new(),
@@ -2626,7 +2652,7 @@ impl<'a> LoweringContext<'a> {
self.pat_ident(sp, ident)
};
let pat_id = pat.id;
- (self.stmt_let_pat(sp, ex, pat, hir::LocalSource::Normal), pat_id)
+ (self.stmt_let_pat(sp, Some(ex), pat, hir::LocalSource::Normal), pat_id)
}
fn block_expr(&mut self, expr: P) -> hir::Block {
diff --git a/src/test/compile-fail/for-loop-unconstrained-element-type.rs b/src/test/compile-fail/for-loop-unconstrained-element-type.rs
new file mode 100644
index 0000000000000..fb5553166bafb
--- /dev/null
+++ b/src/test/compile-fail/for-loop-unconstrained-element-type.rs
@@ -0,0 +1,19 @@
+// Copyright 2017 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that `for` loops don't introduce artificial
+// constraints on the type of the binding (`i`).
+// Subtle changes in the desugaring can cause the
+// type of elements in the vector to (incorrectly)
+// fallback to `!` or `()`.
+
+fn main() {
+ for i in Vec::new() { } //~ ERROR type annotations needed
+}
diff --git a/src/test/run-pass/for-loop-lifetime-of-unbound-values.rs b/src/test/run-pass/for-loop-lifetime-of-unbound-values.rs
new file mode 100644
index 0000000000000..7a088b5133472
--- /dev/null
+++ b/src/test/run-pass/for-loop-lifetime-of-unbound-values.rs
@@ -0,0 +1,43 @@
+// Copyright 2017 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test when destructors run in a for loop. The intention is
+// that the value for each iteration is dropped *after* the loop
+// body has executed. This is true even when the value is assigned
+// to a `_` pattern (and hence ignored).
+
+use std::cell::Cell;
+
+struct Flag<'a>(&'a Cell);
+
+impl<'a> Drop for Flag<'a> {
+ fn drop(&mut self) {
+ self.0.set(false)
+ }
+}
+
+fn main() {
+ let alive2 = Cell::new(true);
+ for _i in std::iter::once(Flag(&alive2)) {
+ // The Flag value should be alive in the for loop body
+ assert_eq!(alive2.get(), true);
+ }
+ // The Flag value should be dead outside of the loop
+ assert_eq!(alive2.get(), false);
+
+ let alive = Cell::new(true);
+ for _ in std::iter::once(Flag(&alive)) {
+ // The Flag value should be alive in the for loop body even if it wasn't
+ // bound by the for loop
+ assert_eq!(alive.get(), true);
+ }
+ // The Flag value should be dead outside of the loop
+ assert_eq!(alive.get(), false);
+}
diff --git a/src/test/run-pass/for-loop-mut-ref-element.rs b/src/test/run-pass/for-loop-mut-ref-element.rs
new file mode 100644
index 0000000000000..14ce23b07242c
--- /dev/null
+++ b/src/test/run-pass/for-loop-mut-ref-element.rs
@@ -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 or the MIT license
+// , 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) {}
+}
\ No newline at end of file
diff --git a/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs b/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs
new file mode 100644
index 0000000000000..b36afcf87b3ee
--- /dev/null
+++ b/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs
@@ -0,0 +1,20 @@
+// Copyright 2017 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 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that the type of `sum` falls back to `i32` here,
+// and that the for loop desugaring doesn't inferfere with
+// that.
+
+fn main() {
+ let mut sum = 0;
+ for i in Vec::new() {
+ sum += i;
+ }
+}