Change:
causes a stack overflow.
This is a stack overflow inside middle::traits::project::normalizeprojectiontype

Discussion:
projection_ty: projection_ty, ty: ty_var }); <del> let obligation = Obligation::with_depth(cause, depth+1, projection.to_predicate()); </del> <ins> let obligation = Obligation::with_depth( cause, depth + 1, projection.to_predicate()); </ins> Normalized { value: ty_var, obligations: vec!(obligation)

obligations); if projected_ty.has_projection_types() { <del> let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth); </del> <ins> let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth+1); </ins> let normalized_ty = normalizer.fold(&projected_ty); debug!("normalize_projection_type: normalized_ty={:?} depth={}",

/// contexts around the same size. n_llvm_insns: Cell<usize>, <ins> /// Depth of the current type-of computation - used to bail out type_of_depth: Cell<usize>, </ins> trait_cache: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, traits::Vtable<'tcx, ()>>>, }

unwind_resume_hooked: Cell::new(false), intrinsics: RefCell::new(FnvHashMap()), n_llvm_insns: Cell::new(0), <ins> type_of_depth: Cell::new(0), </ins> trait_cache: RefCell::new(FnvHashMap()), };

obj)) } <ins> pub fn enter_type_of(&self, ty: Ty<'tcx>) -> TypeOfDepthLock<'b, 'tcx> { let current_depth = self.local.type_of_depth.get(); debug!("enter_type_of({:?}) at depth {:?}", ty, current_depth); if current_depth > self.sess().recursion_limit.get() { self.sess().fatal( &format!("overflow representing the type `{}`", ty)) } self.local.type_of_depth.set(current_depth + 1); TypeOfDepthLock(self.local) } </ins> pub fn check_overflow(&self) -> bool { self.shared.check_overflow }

} } <ins> pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>); impl<'a, 'tcx> Drop for TypeOfDepthLock<'a, 'tcx> { fn drop(&mut self) { self.0.type_of_depth.set(self.0.type_of_depth.get() - 1); } } </ins> /// Declare any llvm intrinsics that you might need fn declare_intrinsic(ccx: &CrateContext, key: &str) -> Option<ValueRef> { macro_rules! ifn {

} debug!("sizing_type_of {:?}", t); <ins> let _recursion_lock = cx.enter_type_of(t); </ins> let llsizingty = match t.sty { _ if !type_is_sized(cx.tcx(), t) => { Type::struct_(cx, &[Type::i8p(cx), Type::i8p(cx)], false)

<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 Foo { type A; } struct FooStruct; impl Foo for FooStruct { //~^ ERROR overflow evaluating the requirement `<FooStruct as Foo>::A` type A = <FooStruct as Foo>::A; } fn main() {} </ins>

<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. // error-pattern: overflow representing the type `S` trait Mirror { type It; } impl<T> Mirror for T { type It = Self; } struct S(Option<<S as Mirror>::It>); fn main() { let _s = S(None); } </ins>

<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. pub struct Outer<T: Trait>(T); pub struct Inner<'a> { value: &'a bool } pub trait Trait { type Error; fn ready(self) -> Self::Error; } impl<'a> Trait for Inner<'a> { type Error = Outer<Inner<'a>>; fn ready(self) -> Outer<Inner<'a>> { Outer(self) } } fn main() { let value = true; let inner = Inner { value: &value }; assert_eq!(inner.ready().0.value, &value); } </ins>