Normalize types bottom up. Fixes #20666.

This commit is contained in:
Niko Matsakis 2015-01-08 12:02:15 -05:00
parent 75919c554a
commit 0d9a11d6ad
2 changed files with 54 additions and 1 deletions

View File

@ -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
}
}
}

View 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]);
}