Skip to content

Iterator composition: Poor error message when Clone trait bound is missing #9082

Closed
@pnkfelix

Description

@pnkfelix

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
% 

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions