-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: remove blanket ext implementations #502
Conversation
A (rather unsurprising) +1 from me. |
I'm sorry for taking so long to get back to you on this RFC; I've gotten quite behind. While I think the concern here is legitimate for sure, I agree with the comments @thestinger made in your links above: the right way to solve this problem, in general, is through "specialization". That is, we clearly need a way to provide blanket implementations that can also be overridden for more specific types. This is a frequently requested feature, and I suspect it will be investigated soon after 1.0. On the other hand, the downside of your proposal here is not too serious, since the extra impl is easy to write, and if you forget it, you will quickly be reminded when you try to use your iterator. Moreover, even if you've published an API without the So, this is a balance between locking into a solution that's better short-term (as proposed here) or long-term (banking on specialization). Given that specialization is almost certain to happen, I personally lean toward the long-term approach here. |
My proposal for handling the iterator optimizations can be done without any new language features. There's no need to have an ugly design with both duplicated implementations and absolutely no way of handling methods like |
@thestinger Ah, sorry, I missed your second comment on the thread and assumed you were talking about specialization. |
@aturon I'd also like to note that the linked stackoverflow question has a solution in some cases: if the function is implemented on the struct, it will be preferred over the trait. This helps in this case at least, but doesn't help in generic code. (updated with thiez comment below) |
@skade it wouldn't be preferred in generic code. For example: fn count_iter<T: Iterator>(t: T) -> usize { t.count() }
#[derive(Copy)]
struct MyItr;
impl MyItr {
fn count(self) -> usize { println!("MyItr.count was called!"); 0 }
}
impl Iterator for MyItr {
type Item = bool;
fn next(&mut self) -> Option<bool> { None }
}
fn main() {
let it = MyItr;
println!("{}",count_iter(vec![1,2,3,4].into_iter()));
println!("{}",count_iter(it));
println!("{}",it.count());
} Will only print the silly message once, for the last statement. |
@Thiez Right. I didn't express that properly, updated the comment. Thank you! |
FWIW, it's looking likely that we'll be able to merge back in |
Excellent, that should solve this issue nicely. |
I'm going to go ahead and close this RFC for now; once the |
Rendered
Previous discussions:
rust-lang/rust#19435 (comment)
#445 (comment)
/~https://github.com/rust-lang/meeting-minutes/blob/master/weekly-meetings/2014-11-25.md#extension-traits
Considering that I cannot get a good answer on how to work around issues with the new system, I think this is worth revisiting.
http://stackoverflow.com/questions/27267767/working-around-the-limitations-of-extension-traits