Skip to content

Commit b9035c2

Browse files
committed
auto merge of #15809 : pcwalton/rust/dedesugar-for, r=pnkfelix
librustc: Stop desugaring `for` expressions and translate them directly. This makes edge cases in which the `Iterator` trait was not in scope and/or `Option` or its variants were not in scope work properly. This breaks code that looks like: struct MyStruct { ... } impl MyStruct { fn next(&mut self) -> Option<int> { ... } } for x in MyStruct { ... } { ... } Change ad-hoc `next` methods like the above to implementations of the `Iterator` trait. For example: impl Iterator<int> for MyStruct { fn next(&mut self) -> Option<int> { ... } } Closes #15392. [breaking-change]
2 parents a455345 + caa564b commit b9035c2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+614
-163
lines changed

src/libcore/char.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
use mem::transmute;
1919
use option::{None, Option, Some};
20-
use iter::{Iterator, range_step};
20+
use iter::range_step;
21+
22+
#[cfg(stage0)]
23+
use iter::Iterator; // NOTE(stage0): Remove after snapshot.
2124

2225
// UTF-8 ranges and tags for encoding characters
2326
static TAG_CONT: u8 = 0b1000_0000u8;

src/libcore/fmt/float.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@
1313
use char;
1414
use collections::Collection;
1515
use fmt;
16-
use iter::{Iterator, range, DoubleEndedIterator};
16+
use iter::{range, DoubleEndedIterator};
1717
use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive};
1818
use num::{Zero, One, cast};
19-
use option::{None, Some};
2019
use result::Ok;
2120
use slice::{ImmutableVector, MutableVector};
2221
use slice;
2322
use str::StrSlice;
2423

24+
#[cfg(stage0)]
25+
use iter::Iterator; // NOTE(stage0): Remove after snapshot.
26+
#[cfg(stage0)]
27+
use option::{Some, None}; // NOTE(stage0): Remove after snapshot.
28+
2529
/// A flag that specifies whether to use exponential (scientific) notation.
2630
pub enum ExponentFormat {
2731
/// Do not use exponential notation.

src/libcore/fmt/num.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616

1717
use collections::Collection;
1818
use fmt;
19-
use iter::{Iterator, DoubleEndedIterator};
19+
use iter::DoubleEndedIterator;
2020
use num::{Int, cast, zero};
21-
use option::{Some, None};
2221
use slice::{ImmutableVector, MutableVector};
2322

23+
#[cfg(stage0)]
24+
use iter::Iterator; // NOTE(stage0): Remove after snapshot.
25+
#[cfg(stage0)]
26+
use option::{Some, None}; // NOTE(stage0): Remove after snapshot.
27+
2428
/// A type that represents a specific radix
2529
trait GenericRadix {
2630
/// The number of digits.

src/libcore/iter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ pub trait Extendable<A>: FromIterator<A> {
9595
/// is returned. A concrete Iterator implementation may choose to behave however
9696
/// it wishes, either by returning `None` infinitely, or by doing something
9797
/// else.
98+
#[lang="iterator"]
9899
pub trait Iterator<A> {
99100
/// Advance the iterator and return the next value. Return `None` when the end is reached.
100101
fn next(&mut self) -> Option<A>;

src/libcore/option.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,12 @@ use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
147147
use mem;
148148
use slice;
149149

150-
/// The `Option`
150+
// Note that this is not a lang item per se, but it has a hidden dependency on
151+
// `Iterator`, which is one. The compiler assumes that the `next` method of
152+
// `Iterator` is an enumeration with one type parameter and two variants,
153+
// which basically means it must be `Option`.
154+
155+
/// The `Option` type.
151156
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show)]
152157
pub enum Option<T> {
153158
/// No value

src/libcore/ptr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,14 @@
9090
use mem;
9191
use clone::Clone;
9292
use intrinsics;
93-
use iter::{range, Iterator};
93+
use iter::range;
9494
use option::{Some, None, Option};
9595

9696
use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
9797

98+
#[cfg(stage0)]
99+
use iter::Iterator; // NOTE(stage0): Remove after snapshot.
100+
98101
pub use intrinsics::copy_memory;
99102
pub use intrinsics::copy_nonoverlapping_memory;
100103
pub use intrinsics::set_memory;

src/libcore/str.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use iter::{Map, Iterator};
2828
use iter::{DoubleEndedIterator, ExactSize};
2929
use iter::range;
3030
use num::{CheckedMul, Saturating};
31-
use option::{None, Option, Some};
31+
use option::{Option, None, Some};
3232
use raw::Repr;
3333
use slice::ImmutableVector;
3434
use slice;
@@ -1027,9 +1027,12 @@ pub mod traits {
10271027
use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
10281028
use collections::Collection;
10291029
use iter::Iterator;
1030-
use option::{Option, Some, None};
1030+
use option::{Option, Some};
10311031
use str::{Str, StrSlice, eq_slice};
10321032

1033+
#[cfg(stage0)]
1034+
use option::None; // NOTE(stage0): Remove after snapshot.
1035+
10331036
impl<'a> Ord for &'a str {
10341037
#[inline]
10351038
fn cmp(&self, other: & &'a str) -> Ordering {

src/libcoretest/iter.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ fn test_iterator_take_while() {
137137
let ys = [0u, 1, 2, 3, 5, 13];
138138
let mut it = xs.iter().take_while(|&x| *x < 15u);
139139
let mut i = 0;
140-
for &x in it {
141-
assert_eq!(x, ys[i]);
140+
for x in it {
141+
assert_eq!(*x, ys[i]);
142142
i += 1;
143143
}
144144
assert_eq!(i, ys.len());
@@ -150,8 +150,8 @@ fn test_iterator_skip_while() {
150150
let ys = [15, 16, 17, 19];
151151
let mut it = xs.iter().skip_while(|&x| *x < 15u);
152152
let mut i = 0;
153-
for &x in it {
154-
assert_eq!(x, ys[i]);
153+
for x in it {
154+
assert_eq!(*x, ys[i]);
155155
i += 1;
156156
}
157157
assert_eq!(i, ys.len());

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@ impl<'a> CheckLoanCtxt<'a> {
440440
euv::AddrOf(..) |
441441
euv::AutoRef(..) |
442442
euv::ClosureInvocation(..) |
443+
euv::ForLoop(..) |
443444
euv::RefBinding(..) => {
444445
format!("previous borrow of `{}` occurs here",
445446
self.bccx.loan_path_to_string(&*old_loan.loan_path))
@@ -668,6 +669,11 @@ impl<'a> CheckLoanCtxt<'a> {
668669
return;
669670
}
670671

672+
// Initializations are OK.
673+
if mode == euv::Init {
674+
return
675+
}
676+
671677
// For immutable local variables, assignments are legal
672678
// if they cannot already have been assigned
673679
if self.is_local_variable_or_arg(assignee_cmt.clone()) {

src/librustc/middle/borrowck/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,8 @@ impl<'a> BorrowckCtxt<'a> {
651651
euv::OverloadedOperator |
652652
euv::AddrOf |
653653
euv::RefBinding |
654-
euv::AutoRef => {
654+
euv::AutoRef |
655+
euv::ForLoop => {
655656
format!("cannot borrow {} as mutable", descr)
656657
}
657658
euv::ClosureInvocation => {
@@ -712,6 +713,10 @@ impl<'a> BorrowckCtxt<'a> {
712713
BorrowViolation(euv::ClosureInvocation) => {
713714
"closure invocation"
714715
}
716+
717+
BorrowViolation(euv::ForLoop) => {
718+
"`for` loop"
719+
}
715720
};
716721

717722
match cause {

0 commit comments

Comments
 (0)