Change:
cc I think this is related to . Here's the example code: It errors with:
I just got similar ICE with extern mod. a.rs: b.rs: Building b.rs gives (Yes, I was using .) It worked on rust revision but not on revision .
Another variant: produces:
Seems likely to be related, yes. I'll take a look today. Probably something funky in the handling of static methods. Possibly related to what was trying to address in (though maybe not -- I'm sad to say I ddn't fully understand the problem there, was too caught up in trying to finish with !)
Here's an example relevant to me:
So these examples are a mix of problems, but they are all related to . The only one of these examples I expect to not ICE is the first one. The others don't work because of . The basic problem is that you cannot have a function which has a lifetime parameter that appears in a trait bound (yet -- I want to fix this, see for details). Interestingly, the reason that we have this problem with the first example, is that static functions like get translated into functions with lifetime parameters that appear within a trait bound. That is, the type for looks to the compiler like: You can see here that appears in the bound for . Anyway, I have the fix for this. This is good because it got me thinking about and I think it's not too hard to extend the fix to cover that case as well. But I'll push the limited fix for just this bug for now.
Thanks for looking into this. I started playing around with your branch to fix this and I ran into another ICE. Is there something new, or is it also caused by ? Errors with:
On Sat, Nov 16, 2013 at 10:01:08PM -0800, Erick Tryzelaar wrote: . I will see how quickly I can prepare a fix for this. The key identifying point is: right here (I a comment)

Discussion:
location_info, type_param_defs.repr(vcx.tcx()), substs.repr(vcx.tcx())); <del> let _i = indenter(); </del> // We do this backwards for reasons discussed above. assert_eq!(substs.tps.len(), type_param_defs.len());

trait_ty_generics: &ty::Generics) { // If declaration is // <del> //     trait<'a,'b,'c,A,B,C> { //        fn foo<'d,'e,'f,D,E,F>(...) -> Self; </del> <ins> //     trait Trait<'a,'b,'c,a,b,c> { //        fn foo<'d,'e,'f,d,e,f>(...) -> Self; </ins> //     } // // and we will create a function like // <del> //     fn foo<'a,'b,'c,'d,'e,'f,A',B',C',D',E',F',G'>(...) -> D' {} </del> <ins> //     fn foo<'a,'b,'c,   // First the lifetime params from trait //            'd,'e,'f,   // Then lifetime params from `foo()` //            a,b,c,      // Then type params from trait //            D:Trait<'a,'b,'c,a,b,c>, // Then this sucker //            E,F,G       // Then type params from `foo()`, offset by 1 //           >(...) -> D' {} </ins> // // Note that `Self` is replaced with an explicit type <del> // parameter D' that is sandwiched in between the trait params </del> <ins> // parameter D that is sandwiched in between the trait params </ins> // and the method params, and thus the indices of the method // type parameters are offset by 1 (that is, the method <del> // parameters are mapped from D, E, F to E', F', and G').  The </del> <ins> // parameters are mapped from d, e, f to E, F, and G).  The </ins> // choice of this ordering is somewhat arbitrary. // <ins> // Note also that the bound for `D` is `Trait<'a,'b,'c,a,b,c>`. // This implies that the lifetime parameters that were inherited // from the trait (i.e., `'a`, `'b`, and `'c`) all must be early // bound, since they appear in a trait bound. // </ins> // Also, this system is rather a hack that should be replaced // with a more uniform treatment of Self (which is partly // underway).

}); // Convert the regions 'a, 'b, 'c defined on the trait into <del> // bound regions on the fn. let rps_from_trait = trait_ty_generics.region_param_defs.iter().map(|d| { ty::ReLateBound(m.fty.sig.binder_id, ty::BrNamed(d.def_id, d.ident)) }).collect(); </del> <ins> // bound regions on the fn. Note that because these appear in the // bound for `Self` they must be early bound. let new_early_region_param_defs = trait_ty_generics.region_param_defs; let rps_from_trait = trait_ty_generics.region_param_defs.iter(). enumerate(). map(|(index,d)| ty::ReEarlyBound(d.def_id.node, index, d.ident)). collect(); </ins> // build up the substitution from <ins> //     'a,'b,'c => 'a,'b,'c </ins> //     A,B,C => A',B',C' //     Self => D' //     D,E,F => E',F',G'

ty_param_bounds_and_ty { generics: ty::Generics { type_param_defs: @new_type_param_defs, <del> region_param_defs: @[], // fn items </del> <ins> region_param_defs: new_early_region_param_defs </ins> }, ty: ty });

<ins> // Copyright 2013 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. // Test that we are able to compile calls to associated fns like // `decode()` where the bound on the `Self` parameter references a // lifetime parameter of the trait. This example indicates why trait // lifetime parameters must be early bound in the type of the // associated item. pub enum Value<'v> { A(&'v str), B, } pub trait Decoder<'v> { fn read(&mut self) -> Value<'v>; } pub trait Decodable<'v, D: Decoder<'v>> { fn decode(d: &mut D) -> Self; } impl<'v, D: Decoder<'v>> Decodable<'v, D> for () { fn decode(d: &mut D) -> () { match d.read() { A(..) => (), B => Decodable::decode(d), } } } pub fn main() { } </ins>