auto merge of #20655 : nikomatsakis/rust/carl-ice, r=aturon

Remember to check the name of the associated type being projected when searching the environment. Fixes #20651.
This commit is contained in:
bors 2015-01-07 17:45:11 +00:00
commit 9f1ead8fad
3 changed files with 69 additions and 1 deletions

View File

@ -452,7 +452,9 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
for predicate in elaborate_predicates(selcx.tcx(), env_predicates) { for predicate in elaborate_predicates(selcx.tcx(), env_predicates) {
match predicate { match predicate {
ty::Predicate::Projection(ref data) => { ty::Predicate::Projection(ref data) => {
let is_match = infcx.probe(|_| { let same_name = data.item_name() == obligation.predicate.item_name;
let is_match = same_name && infcx.probe(|_| {
let origin = infer::Misc(obligation.cause.span); let origin = infer::Misc(obligation.cause.span);
let obligation_poly_trait_ref = let obligation_poly_trait_ref =
obligation_trait_ref.to_poly_trait_ref(); obligation_trait_ref.to_poly_trait_ref();
@ -465,6 +467,9 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
}); });
if is_match { if is_match {
debug!("assemble_candidates_from_predicates: candidate {}",
data.repr(selcx.tcx()));
candidate_set.vec.push( candidate_set.vec.push(
ProjectionTyCandidate::ParamEnv(data.clone())); ProjectionTyCandidate::ParamEnv(data.clone()));
} }
@ -527,6 +532,9 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
match vtable { match vtable {
super::VtableImpl(data) => { super::VtableImpl(data) => {
debug!("assemble_candidates_from_impls: impl candidate {}",
data.repr(selcx.tcx()));
candidate_set.vec.push( candidate_set.vec.push(
ProjectionTyCandidate::Impl(data)); ProjectionTyCandidate::Impl(data));
} }

View File

@ -1892,6 +1892,10 @@ pub struct ProjectionPredicate<'tcx> {
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>; pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
impl<'tcx> PolyProjectionPredicate<'tcx> { impl<'tcx> PolyProjectionPredicate<'tcx> {
pub fn item_name(&self) -> ast::Name {
self.0.projection_ty.item_name // safe to skip the binder to access a name
}
pub fn sort_key(&self) -> (ast::DefId, ast::Name) { pub fn sort_key(&self) -> (ast::DefId, ast::Name) {
self.0.projection_ty.sort_key() self.0.projection_ty.sort_key()
} }

View File

@ -0,0 +1,56 @@
// 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 X;
type Y;
}
fn have_x_want_x<T:Foo<X=u32>>(t: &T)
{
want_x(t);
}
fn have_x_want_y<T:Foo<X=u32>>(t: &T)
{
want_y(t); //~ ERROR type mismatch
}
fn have_y_want_x<T:Foo<Y=i32>>(t: &T)
{
want_x(t); //~ ERROR type mismatch
}
fn have_y_want_y<T:Foo<Y=i32>>(t: &T)
{
want_y(t);
}
fn have_xy_want_x<T:Foo<X=u32,Y=i32>>(t: &T)
{
want_x(t);
}
fn have_xy_want_y<T:Foo<X=u32,Y=i32>>(t: &T)
{
want_y(t);
}
fn have_xy_want_xy<T:Foo<X=u32,Y=i32>>(t: &T)
{
want_x(t);
want_y(t);
}
fn want_x<T:Foo<X=u32>>(t: &T) { }
fn want_y<T:Foo<Y=i32>>(t: &T) { }
fn main() { }