Normalize types bottom up. Fixes #20666.
This commit is contained in:
parent
75919c554a
commit
0d9a11d6ad
@ -206,6 +206,7 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
|
||||
// normalize it when we instantiate those bound regions (which
|
||||
// should occur eventually).
|
||||
|
||||
let ty = ty_fold::super_fold_ty(self, ty);
|
||||
match ty.sty {
|
||||
ty::ty_projection(ref data) if !data.has_escaping_regions() => { // (*)
|
||||
|
||||
@ -229,8 +230,9 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
|
||||
self.obligations.extend(obligations.into_iter());
|
||||
ty
|
||||
}
|
||||
|
||||
_ => {
|
||||
ty_fold::super_fold_ty(self, ty)
|
||||
ty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
src/test/run-pass/associated-types-nested-projections.rs
Normal file
51
src/test/run-pass/associated-types-nested-projections.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// 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.
|
||||
|
||||
// Test that we can resolve nested projection types. Issue #20666.
|
||||
|
||||
use std::slice;
|
||||
|
||||
trait Bound {}
|
||||
|
||||
impl<'a> Bound for &'a int {}
|
||||
|
||||
trait IntoIterator {
|
||||
type Iter: Iterator;
|
||||
|
||||
fn into_iter(self) -> Self::Iter;
|
||||
}
|
||||
|
||||
impl<'a, T> IntoIterator for &'a [T; 3] {
|
||||
type Iter = slice::Iter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> slice::Iter<'a, T> {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
fn foo<X>(x: X) where
|
||||
X: IntoIterator,
|
||||
<<X as IntoIterator>::Iter as Iterator>::Item: Bound,
|
||||
{
|
||||
}
|
||||
|
||||
fn bar<T, I, X>(x: X) where
|
||||
T: Bound,
|
||||
I: Iterator<Item=T>,
|
||||
X: IntoIterator<Iter=I>,
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(&[0i, 1, 2]);
|
||||
//~^ error: the trait `Bound` is not implemented for the type `<<&[int; 3] as IntoIterator>::Iter as core::iter::Iterator>::Item`
|
||||
bar(&[0i, 1, 2]);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user