Skip to content

Commit 4f05ec7

Browse files
committed
Patch projection to not be so eager to unify type variables. This code
is still probably wrong since it fails to incorporate the ambiguity resolution measures that `select` uses. Also, made more complicated by the fact that trait object types do not impl their own traits yet.
1 parent 84f5ad8 commit 4f05ec7

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

src/librustc/middle/traits/project.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,14 @@ pub fn project_type<'cx,'tcx>(
125125
ambiguous: false,
126126
};
127127

128-
let () = assemble_candidates_from_param_env(selcx,
129-
obligation,
130-
&mut candidates);
131-
132128
let () = assemble_candidates_from_object_type(selcx,
133129
obligation,
134130
&mut candidates);
135131

136132
if candidates.vec.is_empty() {
137-
// FIXME(#20297) -- In `select.rs` there is similar logic that
138-
// gives precedence to where-clauses, but it's a bit more
139-
// fine-grained. I was lazy here and just always give
140-
// precedence to where-clauses or other such sources over
141-
// actually dredging through impls. This logic probably should
142-
// be tightened up.
133+
let () = assemble_candidates_from_param_env(selcx,
134+
obligation,
135+
&mut candidates);
143136

144137
let () = try!(assemble_candidates_from_impls(selcx,
145138
obligation,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2014 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 how resolving a projection interacts with inference. In this
12+
// case, we were eagerly unifying the type variable for the iterator
13+
// type with `I` from the where clause, ignoring the in-scope `impl`
14+
// for `ByRef`. The right answer was to consider the result ambiguous
15+
// until more type information was available.
16+
17+
#![feature(associated_types, lang_items, unboxed_closures)]
18+
#![no_implicit_prelude]
19+
20+
use std::option::Option::{None, Some, mod};
21+
22+
trait Iterator {
23+
type Item;
24+
25+
fn next(&mut self) -> Option<Self::Item>;
26+
}
27+
28+
trait IteratorExt: Iterator {
29+
fn by_ref(&mut self) -> ByRef<Self> {
30+
ByRef(self)
31+
}
32+
}
33+
34+
impl<I> IteratorExt for I where I: Iterator {}
35+
36+
struct ByRef<'a, I: 'a + Iterator>(&'a mut I);
37+
38+
impl<'a, A, I> Iterator for ByRef<'a, I> where I: Iterator<Item=A> {
39+
type Item = A;
40+
41+
fn next(&mut self) -> Option< <I as Iterator>::Item > {
42+
self.0.next()
43+
}
44+
}
45+
46+
fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
47+
48+
fn test<A, I: Iterator<Item=A>>(mut it: I) {
49+
is_iterator_of::<A, _>(&it.by_ref());
50+
}
51+
52+
fn main() { }

0 commit comments

Comments
 (0)