I am not sure if we can do anything about this, but I thought I should at least note the problem: In the code below, there is a iterator composition (iter().map(..).collect()) that is going wrong because of a missing Clone trait bound.
The fact that the code cannot be compiled is fine. My question is, can we make the error message better? Invocations of methods other than clone yield coherent error messages from rustc; why is clone different in this case? (is this an artifact of some impl<Bounds...> Clone for X floating around, for appropriate substitutions for Bounds and X?)
Test case:
#[allow(unused_imports)];
use std::hashmap::HashSetIterator;
use std::hashmap::HashSet;
#[cfg(and(not(illustrate_poor_error_msg),not(illustrate_fine_error_msg)))]
fn iter_to_vec<'a, 'b, X:Clone>(i: HashSetIterator<'b, X>) -> ~[X] {
// ^~~~~~
// missing clone is the only difference
let i = i.map(|x| x.clone());
// ^~~~~~
// Here is the call to clone
let mut i = i;
i.collect()
}
#[cfg(illustrate_poor_error_msg)]
fn iter_to_vec<'a, 'b, X >(i: HashSetIterator<'b, X>) -> ~[X] {
// ^~~~~~
// missing clone is the only difference
let i = i.map(|x| x.clone());
// ^~~~~~
// Here is the call to clone
let mut i = i;
i.collect()
}
#[cfg(illustrate_fine_error_msg)]
fn iter_to_vec<'a, 'b, X >(i: HashSetIterator<'b, X>) -> ~[X] {
// ^~~~~~
// missing clone is the only difference
let i = i.map(|x| x.enolc());
// ^~~~~~
// Here is a call to something other than clone
let mut i = i;
i.collect()
}
#[cfg(illustrate_original_poor_error_msg)]
fn set_to_vec<X:Eq+Hash >(s:&HashSet<X>) -> ~[X] {
// ^~~~~~
// missing clone is the only difference
let i = s.iter();
let mut i = i.map(|x| x.clone());
i.collect()
}
#[cfg(not(illustrate_orignal_poor_error_msg))]
fn set_to_vec<X:Eq+Hash+Clone>(s:&HashSet<X>) -> ~[X] {
// ^~~~~~
// (the aforementioned clone)
let i = s.iter();
let mut i = i.map(|x| x.clone());
i.collect()
}
fn main() {
let mut s = HashSet::new();
s.insert(1);
s.insert(100);
s.insert(10211201);
println(fmt!("%?", set_to_vec(&s)));
}
Transcript:
% RUST_LOG=rustc=1 rustc --version
/Users/pnkfelix/opt/rust-dbg/bin/rustc 0.8-pre (fd49f6d 2013-09-09 02:36:06 -0700)
host: x86_64-apple-darwin
% RUST_LOG=rustc=1 rustc --cfg illustrate_poor_error_msg /tmp/baz3.rs
/tmp/baz3.rs:25:4: 26:1 error: expected std::iter::FromIterator<&X>, but found std::iter::FromIterator<X> (expected &-ptr but found type parameter)
/tmp/baz3.rs:25 i.collect()
/tmp/baz3.rs:26 }
/tmp/baz3.rs:25:4: 26:1 error: expected std::iter::FromIterator<&X>, but found std::iter::FromIterator<X> (expected &-ptr but found type parameter)
/tmp/baz3.rs:25 i.collect()
/tmp/baz3.rs:26 }
error: aborting due to 2 previous errors
task <unnamed> failed at 'explicit failure', /Users/pnkfelix/Dev/Mozilla/rust.git/src/libsyntax/diagnostic.rs:95
task <unnamed> failed at 'explicit failure', /Users/pnkfelix/Dev/Mozilla/rust.git/src/librustc/rustc.rs:376
% RUST_LOG=rustc=1 rustc --cfg illustrate_fine_error_msg /tmp/baz3.rs
/tmp/baz3.rs:32:22: 32:32 error: type `&X` does not implement any method in scope named `enolc`
/tmp/baz3.rs:32 let i = i.map(|x| x.enolc());
^~~~~~~~~~
error: aborting due to previous error
task <unnamed> failed at 'explicit failure', /Users/pnkfelix/Dev/Mozilla/rust.git/src/libsyntax/diagnostic.rs:95
task <unnamed> failed at 'explicit failure', /Users/pnkfelix/Dev/Mozilla/rust.git/src/librustc/rustc.rs:376
%
I am not sure if we can do anything about this, but I thought I should at least note the problem: In the code below, there is a iterator composition (
iter().map(..).collect()) that is going wrong because of a missingClonetrait bound.The fact that the code cannot be compiled is fine. My question is, can we make the error message better? Invocations of methods other than
cloneyield coherent error messages from rustc; why isclonedifferent in this case? (is this an artifact of someimpl<Bounds...> Clone for Xfloating around, for appropriate substitutions for Bounds and X?)Test case:
Transcript: