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:
commit
9f1ead8fad
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() { }
|
Loading…
Reference in New Issue