Change:
That's a mouthful! To exemplify: This doesn't compile with , even though it does without it. Note that the only difference between the two configurations is that the function on is a free function instead of a default method. With , this fails with: Tested on
cc me
I've been running into very similar errors all day while updating my libs to the latest nightly. Here's an example of a method that works fine along with one that does not (simplest example I could come up with).
This example works now. I think this was a dup of
I just updated to master and I'm still running into the same error - perhaps my error is a separate issue?
Edwardw's PR does seem to fix my issue however, perhaps it addresses something extra?
The original issue is still present if the example on the first post is compiled with . I tested on , which contains Edit: just compiled . Still reproducible

Discussion:
/// either identifying an `impl` (e.g., `impl Eq for int`) that /// provides the required vtable, or else finding a bound that is in /// scope. The eventual result is usually a `Selection` (defined below). <del> #[derive(Clone)] </del> <ins> #[derive(Clone, PartialEq, Eq)] </ins> pub struct Obligation<'tcx, T> { pub cause: ObligationCause<'tcx>, pub recursion_depth: uint,

pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; /// Why did we incur this obligation? Used for error reporting. <del> #[derive(Clone)] </del> <ins> #[derive(Clone, PartialEq, Eq)] </ins> pub struct ObligationCause<'tcx> { pub span: Span,

pub code: ObligationCauseCode<'tcx> } <del> #[derive(Clone)] </del> <ins> #[derive(Clone, PartialEq, Eq)] </ins> pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from span. MiscObligation,

CompareImplMethodObligation, } <del> #[derive(Clone)] </del> <ins> #[derive(Clone, PartialEq, Eq)] </ins> pub struct DerivedObligationCause<'tcx> { /// The trait reference of the parent obligation that led to the /// current obligation. Note that only trait obligations lead to

/// is `Obligation`, as one might expect. During trans, however, this /// is `()`, because trans only requires a shallow resolution of an /// impl, and nested obligations are satisfied later. <del> #[derive(Clone)] </del> <ins> #[derive(Clone, PartialEq, Eq)] </ins> pub struct VtableImplData<'tcx, N> { pub impl_def_id: ast::DefId, pub substs: subst::Substs<'tcx>,

pub err: ty::type_err<'tcx> } <ins> #[derive(PartialEq, Eq)] </ins> enum ProjectionTyCandidate<'tcx> { ParamEnv(ty::PolyProjectionPredicate<'tcx>), Impl(VtableImplData<'tcx, PredicateObligation<'tcx>>),

// We probably need some winnowing logic similar to select here. <ins> // Drop duplicates. // // Note: `candidates.vec` seems to be on the critical path of the // compiler. Replacing it with an hash set was also tried, which would // render the following dedup unnecessary. It led to cleaner code but // prolonged compiling time of `librustc` from 5m30s to 6m in one test, or // ~9% performance lost. if candidates.vec.len() > 1 { let mut i = 0; while i < candidates.vec.len() { let has_dup = (0..i).any(|j| candidates.vec[i] == candidates.vec[j]); if has_dup { candidates.vec.swap_remove(i); } else { i += 1; } } } </ins> if candidates.ambiguous || candidates.vec.len() > 1 { return Err(ProjectionTyError::TooManyCandidates); }

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. trait DigitCollection: Sized { type Iter: Iterator<Item = u8>; fn digit_iter(self) -> Self::Iter; fn digit_sum(self) -> u32 { self.digit_iter() .map(|digit: u8| digit as u32) .fold(0, |sum, digit| sum + digit) } } impl<I> DigitCollection for I where I: Iterator<Item=u8> { type Iter = I; fn digit_iter(self) -> I { self } } fn main() { let xs = vec![1u8, 2, 3, 4, 5]; assert_eq!(xs.into_iter().digit_sum(), 15); } </ins>