-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
iterator-related cleanup #8326
iterator-related cleanup #8326
Conversation
I'm obviously very much against removing Constant allegations of cuteness aside, r- from me |
I fully intend to support the same zero-parameter sugar in There's nothing to gain from having an alternate way of looping lacking a way to break and making you encounter closure capture errors. There is a cognitive overhead to have many different looping conventions in the standard library - |
@thestinger, could |
@alexcrichton: yeah, it could just be a wrapper around We used used to have a I decided just to copy Python's convention for now because |
I'm confused why this can't just be pub trait Times {
fn times(self) -> SomeIteratorOverUnit;
}
impl Times for uint {
fn times(self) -> SomeIteratorOverUnit {
range(0, self).transform(|_| ())
}
} |
@alexcrichton: As a function, it can be implemented once generically for all types. As a trait, it adds yet another numeric trait every unsigned numeric type will have to implement. You need an implementation for If we use traits that way, they're actually doing the opposite of code reuse. There will be third-party numeric types, so it makes the language less friendly to them by increasing the size of a minimal implementation. |
There's also no benefit from turning the result from an integer into |
I'm still confused what the problem is, if you want it generically why won't this work impl<T: Required + Traits + For + Range> Times for T {
fn times(self) -> SomeIteratorOverUnit {
range(0, self)
}
} |
@alexcrichton: it will work, but if it's going to be in prelude it will reserve that name as a method (for types it can satisfy), which may not be wanted |
I wouldn't necessarily be in favor of it being in the prelude. This is more of a "cute" language feature than something core which should be present in every module's namespace in my opinion. |
I would really rather just have |
to match the convention used by `range`, since `iterator::count` is already namespaced enough and won't be ambiguous
This module provided adaptors for the old internal iterator protocol, but they proved to be quite unreadable and are not generic enough to handle borrowed pointers well. Since Rust no longer defines an internal iteration protocol, I don't think there's going to be any reuse via these adaptors.
This results in throwing away alias analysis information, because LLVM does *not* implement reasoning about these conversions yet. We specialize zero-size types since a `getelementptr` offset will return us the same pointer, making it broken as a simple counter.
This allows LLVM to optimize vector iterators to an `getelementptr` and `icmp` pair, instead of `getelementptr` and *two* comparisons. Code snippet: ~~~ fn foo(xs: &mut [f64]) { for x in xs.mut_iter() { *x += 10.0; } } ~~~ LLVM IR at stage0: ~~~ ; Function Attrs: noinline uwtable define void @"_ZN3foo17_68e1b25bca131dba7_0$x2e0E"({ i64, %tydesc*, i8*, i8*, i8 }* nocapture, { double*, i64 }* nocapture) #1 { "function top level": %2 = getelementptr inbounds { double*, i64 }* %1, i64 0, i32 0 %3 = load double** %2, align 8 %4 = getelementptr inbounds { double*, i64 }* %1, i64 0, i32 1 %5 = load i64* %4, align 8 %6 = ptrtoint double* %3 to i64 %7 = and i64 %5, -8 %8 = add i64 %7, %6 %9 = inttoptr i64 %8 to double* %10 = icmp eq double* %3, %9 %11 = icmp eq double* %3, null %or.cond6 = or i1 %10, %11 br i1 %or.cond6, label %match_case, label %match_else match_else: ; preds = %"function top level", %match_else %12 = phi double* [ %13, %match_else ], [ %3, %"function top level" ] %13 = getelementptr double* %12, i64 1 %14 = load double* %12, align 8 %15 = fadd double %14, 1.000000e+01 store double %15, double* %12, align 8 %16 = icmp eq double* %13, %9 %17 = icmp eq double* %13, null %or.cond = or i1 %16, %17 br i1 %or.cond, label %match_case, label %match_else match_case: ; preds = %match_else, %"function top level" ret void } ~~~ Optimized LLVM IR at stage1/stage2: ~~~ ; Function Attrs: noinline uwtable define void @"_ZN3foo17_68e1b25bca131dba7_0$x2e0E"({ i64, %tydesc*, i8*, i8*, i8 }* nocapture, { double*, i64 }* nocapture) #1 { "function top level": %2 = getelementptr inbounds { double*, i64 }* %1, i64 0, i32 0 %3 = load double** %2, align 8 %4 = getelementptr inbounds { double*, i64 }* %1, i64 0, i32 1 %5 = load i64* %4, align 8 %6 = lshr i64 %5, 3 %7 = getelementptr inbounds double* %3, i64 %6 %8 = icmp eq i64 %6, 0 %9 = icmp eq double* %3, null %or.cond6 = or i1 %8, %9 br i1 %or.cond6, label %match_case, label %match_else match_else: ; preds = %"function top level", %match_else %.sroa.0.0.in7 = phi double* [ %10, %match_else ], [ %3, %"function top level" ] %10 = getelementptr inbounds double* %.sroa.0.0.in7, i64 1 %11 = load double* %.sroa.0.0.in7, align 8 %12 = fadd double %11, 1.000000e+01 store double %12, double* %.sroa.0.0.in7, align 8 %13 = icmp eq double* %10, %7 br i1 %13, label %match_case, label %match_else match_case: ; preds = %match_else, %"function top level" ret void } ~~~
I'm happy at the prospect of being able to omit the As for implementation, I really don't care. My only concern is the API. I agree that Honestly I don't care if it gets used in the compiler, so I'm still indifferent to the bulk of this PR. But I do insist that this API be made available, whether with |
The main commit regarding |
I plan on opening the An Iterator-based |
The `extra::iter` module wasn't actually included in `extra.rs` when it was moved from `std`... I assume no one is going to miss it.
…xFrednet warn if we find multiple clippy configs Fixes rust-lang#8323 --- *Please write a short comment explaining your change (or "none" for internal only changes)* changelog: warn if we find multiple clippy configs
The
extra::iter
module wasn't actually included inextra.rs
when it was moved fromstd
... I assume no one is going to miss it.