about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-01-25 22:57:31 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-02-01 16:38:46 +0100
commitcf01b514c876656696e87672a1c118a3ce7817ed (patch)
tree76de0b5d6d16e9add8564e6e546d5d41126096d4
parent0d25ff8842ca35b7eabd2d8a22669c5b2216ad82 (diff)
downloadrust-cf01b514c876656696e87672a1c118a3ce7817ed.tar.gz
rust-cf01b514c876656696e87672a1c118a3ce7817ed.zip
Generic type parameters are flexible even for existential types
-rw-r--r--src/librustc_typeck/collect.rs11
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use.rs6
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use2.rs8
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use3.rs12
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use3.stderr19
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use4.rs10
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use4.stderr19
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use5.rs15
-rw-r--r--src/test/ui/existential_types/generic_duplicate_param_use5.stderr19
9 files changed, 32 insertions, 87 deletions
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index b0b266a61a5..e4fc1925eb3 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1346,7 +1346,16 @@ fn find_existential_constraints<'a, 'tcx>(
                 // FIXME(oli-obk): trace the actual span from inference to improve errors
                 let span = self.tcx.def_span(def_id);
                 if let Some((prev_span, prev_ty)) = self.found {
-                    if ty != prev_ty {
+                    let mut ty = ty.walk().fuse();
+                    let mut prev_ty = prev_ty.walk().fuse();
+                    let iter_eq = (&mut ty).zip(&mut prev_ty).all(|(t, p)| match (&t.sty, &p.sty) {
+                        // type parameters are equal to any other type parameter for the purpose of
+                        // concrete type equality, as it is possible to obtain the same type just
+                        // by passing matching parameters to a function.
+                        (ty::Param(_), ty::Param(_)) => true,
+                        _ => t == p,
+                    });
+                    if !iter_eq || ty.next().is_some() || prev_ty.next().is_some() {
                         // found different concrete types for the existential type
                         let mut err = self.tcx.sess.struct_span_err(
                             span,
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use.rs b/src/test/ui/existential_types/generic_duplicate_param_use.rs
index 14d63ecc6bb..d08cd88c600 100644
--- a/src/test/ui/existential_types/generic_duplicate_param_use.rs
+++ b/src/test/ui/existential_types/generic_duplicate_param_use.rs
@@ -1,11 +1,13 @@
 // compile-pass
 #![feature(existential_type)]
 
+use std::fmt::Debug;
+
 fn main() {}
 
 // test that unused generic parameters are ok
-existential type Two<T, U>: 'static;
+existential type Two<T, U>: Debug;
 
-fn one<T: 'static>(t: T) -> Two<T, T> {
+fn one<T: Debug>(t: T) -> Two<T, T> {
     t
 }
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use2.rs b/src/test/ui/existential_types/generic_duplicate_param_use2.rs
index b6cb22da41d..c27fbb74cf1 100644
--- a/src/test/ui/existential_types/generic_duplicate_param_use2.rs
+++ b/src/test/ui/existential_types/generic_duplicate_param_use2.rs
@@ -1,15 +1,17 @@
 // compile-pass
 #![feature(existential_type)]
 
+use std::fmt::Debug;
+
 fn main() {}
 
 // test that unused generic parameters are ok
-existential type Two<T, U>: 'static;
+existential type Two<T, U>: Debug;
 
-fn one<T: 'static>(t: T) -> Two<T, T> {
+fn one<T: Debug>(t: T) -> Two<T, T> {
     t
 }
 
-fn two<T: 'static, U: 'static>(t: T, _: U) -> Two<T, U> {
+fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
     t
 }
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.rs b/src/test/ui/existential_types/generic_duplicate_param_use3.rs
index 43650a6a352..b4d1b26dbab 100644
--- a/src/test/ui/existential_types/generic_duplicate_param_use3.rs
+++ b/src/test/ui/existential_types/generic_duplicate_param_use3.rs
@@ -1,19 +1,21 @@
+// compile-pass
 #![feature(existential_type)]
 
+use std::fmt::Debug;
+
 fn main() {}
 
 // test that unused generic parameters are ok
-existential type Two<T, U>: 'static;
+existential type Two<T, U>: Debug;
 
-fn one<T: 'static>(t: T) -> Two<T, T> {
+fn one<T: Debug>(t: T) -> Two<T, T> {
     t
 }
 
-fn two<T: 'static, U: 'static>(t: T, _: U) -> Two<T, U> {
+fn two<T: Debug, U>(t: T, _: U) -> Two<T, U> {
     t
 }
 
-fn three<T: 'static, U: 'static>(_: T, u: U) -> Two<T, U> {
-    //~^ ERROR defining existential type use differs from previous
+fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
     u
 }
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr b/src/test/ui/existential_types/generic_duplicate_param_use3.stderr
deleted file mode 100644
index 67c30ad648b..00000000000
--- a/src/test/ui/existential_types/generic_duplicate_param_use3.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error: defining existential type use differs from previous
-  --> $DIR/generic_duplicate_param_use3.rs:16:1
-   |
-LL | / fn three<T: 'static, U: 'static>(_: T, u: U) -> Two<T, U> {
-LL | |     //~^ ERROR defining existential type use differs from previous
-LL | |     u
-LL | | }
-   | |_^
-   |
-note: previous use here
-  --> $DIR/generic_duplicate_param_use3.rs:8:1
-   |
-LL | / fn one<T: 'static>(t: T) -> Two<T, T> {
-LL | |     t
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.rs b/src/test/ui/existential_types/generic_duplicate_param_use4.rs
index 79df528d209..afab86c3ff0 100644
--- a/src/test/ui/existential_types/generic_duplicate_param_use4.rs
+++ b/src/test/ui/existential_types/generic_duplicate_param_use4.rs
@@ -1,15 +1,17 @@
+// compile-pass
 #![feature(existential_type)]
 
+use std::fmt::Debug;
+
 fn main() {}
 
 // test that unused generic parameters are ok
-existential type Two<T, U>: 'static;
+existential type Two<T, U>: Debug;
 
-fn one<T: 'static>(t: T) -> Two<T, T> {
+fn one<T: Debug>(t: T) -> Two<T, T> {
     t
 }
 
-fn three<T: 'static, U: 'static>(_: T, u: U) -> Two<T, U> {
-//~^ ERROR defining existential type use differs from previous
+fn three<T, U: Debug>(_: T, u: U) -> Two<T, U> {
     u
 }
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr b/src/test/ui/existential_types/generic_duplicate_param_use4.stderr
deleted file mode 100644
index e7a372e0e0c..00000000000
--- a/src/test/ui/existential_types/generic_duplicate_param_use4.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error: defining existential type use differs from previous
-  --> $DIR/generic_duplicate_param_use4.rs:12:1
-   |
-LL | / fn three<T: 'static, U: 'static>(_: T, u: U) -> Two<T, U> {
-LL | | //~^ ERROR defining existential type use differs from previous
-LL | |     u
-LL | | }
-   | |_^
-   |
-note: previous use here
-  --> $DIR/generic_duplicate_param_use4.rs:8:1
-   |
-LL | / fn one<T: 'static>(t: T) -> Two<T, T> {
-LL | |     t
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.rs b/src/test/ui/existential_types/generic_duplicate_param_use5.rs
deleted file mode 100644
index f9d336d759b..00000000000
--- a/src/test/ui/existential_types/generic_duplicate_param_use5.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(existential_type)]
-
-fn main() {}
-
-// test that unused generic parameters are ok
-existential type Two<T, U>: 'static;
-
-fn one<T: 'static>(t: T) -> Two<T, T> {
-    t
-}
-
-fn two<T: 'static, U: 'static>(t: T, _: U) -> Two<U, T> {
-//~^ ERROR defining existential type use differs from previous
-    t
-}
diff --git a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr b/src/test/ui/existential_types/generic_duplicate_param_use5.stderr
deleted file mode 100644
index e2bf4a9e0df..00000000000
--- a/src/test/ui/existential_types/generic_duplicate_param_use5.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error: defining existential type use differs from previous
-  --> $DIR/generic_duplicate_param_use5.rs:12:1
-   |
-LL | / fn two<T: 'static, U: 'static>(t: T, _: U) -> Two<U, T> {
-LL | | //~^ ERROR defining existential type use differs from previous
-LL | |     t
-LL | | }
-   | |_^
-   |
-note: previous use here
-  --> $DIR/generic_duplicate_param_use5.rs:8:1
-   |
-LL | / fn one<T: 'static>(t: T) -> Two<T, T> {
-LL | |     t
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-