Closed
Description
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
%