]> git.lizzy.rs Git - rust.git/commitdiff
Remember to check the name of the associated type being projected when searching...
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 6 Jan 2015 18:41:14 +0000 (13:41 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 7 Jan 2015 16:24:50 +0000 (11:24 -0500)
src/librustc/middle/traits/project.rs
src/librustc/middle/ty.rs
src/test/compile-fail/associated-types-multiple-types-one-trait.rs [new file with mode: 0644]

index 65f7ad296db519855ac5cd625d79f7b11c972db7..a6be8d16a7803af1c0d080536b146966b875af90 100644 (file)
@@ -452,7 +452,9 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
     for predicate in elaborate_predicates(selcx.tcx(), env_predicates) {
         match predicate {
             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 obligation_poly_trait_ref =
                         obligation_trait_ref.to_poly_trait_ref();
@@ -465,6 +467,9 @@ fn assemble_candidates_from_predicates<'cx,'tcx>(
                 });
 
                 if is_match {
+                    debug!("assemble_candidates_from_predicates: candidate {}",
+                           data.repr(selcx.tcx()));
+
                     candidate_set.vec.push(
                         ProjectionTyCandidate::ParamEnv(data.clone()));
                 }
@@ -527,6 +532,9 @@ fn assemble_candidates_from_impls<'cx,'tcx>(
 
     match vtable {
         super::VtableImpl(data) => {
+            debug!("assemble_candidates_from_impls: impl candidate {}",
+                   data.repr(selcx.tcx()));
+
             candidate_set.vec.push(
                 ProjectionTyCandidate::Impl(data));
         }
index c359233eca173cd4ad7b9fe05d76b6838a4bc6d4..424e64d8e78800d1f23e48d3c666c81f5ed2dff4 100644 (file)
@@ -1866,6 +1866,10 @@ pub struct ProjectionPredicate<'tcx> {
 pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'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) {
         self.0.projection_ty.sort_key()
     }
diff --git a/src/test/compile-fail/associated-types-multiple-types-one-trait.rs b/src/test/compile-fail/associated-types-multiple-types-one-trait.rs
new file mode 100644 (file)
index 0000000..9436f82
--- /dev/null
@@ -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() { }