Skip to content

Commit 0d9a11d

Browse files
committed
Normalize types bottom up. Fixes rust-lang#20666.
1 parent 75919c5 commit 0d9a11d

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/librustc/middle/traits/project.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
206206
// normalize it when we instantiate those bound regions (which
207207
// should occur eventually).
208208

209+
let ty = ty_fold::super_fold_ty(self, ty);
209210
match ty.sty {
210211
ty::ty_projection(ref data) if !data.has_escaping_regions() => { // (*)
211212

@@ -229,8 +230,9 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
229230
self.obligations.extend(obligations.into_iter());
230231
ty
231232
}
233+
232234
_ => {
233-
ty_fold::super_fold_ty(self, ty)
235+
ty
234236
}
235237
}
236238
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that we can resolve nested projection types. Issue #20666.
12+
13+
use std::slice;
14+
15+
trait Bound {}
16+
17+
impl<'a> Bound for &'a int {}
18+
19+
trait IntoIterator {
20+
type Iter: Iterator;
21+
22+
fn into_iter(self) -> Self::Iter;
23+
}
24+
25+
impl<'a, T> IntoIterator for &'a [T; 3] {
26+
type Iter = slice::Iter<'a, T>;
27+
28+
fn into_iter(self) -> slice::Iter<'a, T> {
29+
self.iter()
30+
}
31+
}
32+
33+
fn foo<X>(x: X) where
34+
X: IntoIterator,
35+
<<X as IntoIterator>::Iter as Iterator>::Item: Bound,
36+
{
37+
}
38+
39+
fn bar<T, I, X>(x: X) where
40+
T: Bound,
41+
I: Iterator<Item=T>,
42+
X: IntoIterator<Iter=I>,
43+
{
44+
45+
}
46+
47+
fn main() {
48+
foo(&[0i, 1, 2]);
49+
//~^ error: the trait `Bound` is not implemented for the type `<<&[int; 3] as IntoIterator>::Iter as core::iter::Iterator>::Item`
50+
bar(&[0i, 1, 2]);
51+
}

0 commit comments

Comments
 (0)