about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-05-11 12:25:11 +0000
committerbors <bors@rust-lang.org>2019-05-11 12:25:11 +0000
commit5f1924c9922c640108d2225d6b68e69e589b94ae (patch)
tree9c82d71d54414451e9b7b18ee3089fd569556a47
parentaf39a1fd73de7f4b9c895d3377e03f8fa3221449 (diff)
parentaa9369c7a4f463ea9e2d1f5ceecccbeb026baa41 (diff)
Auto merge of #60714 - varkor:existential-global-lift-ice, r=oli-obk
Fix ICE with un-feature-gated existential type

Fixes https://github.com/rust-lang/rust/issues/60371.

r? @oli-obk
-rw-r--r--src/librustc_typeck/check/writeback.rs45
-rw-r--r--src/test/ui/existential-type/issue-60371.rs15
-rw-r--r--src/test/ui/existential-type/issue-60371.stderr29
3 files changed, 70 insertions, 19 deletions
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index f9d83146e30..bf978352fae 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -611,26 +611,33 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
                 }
             }
 
-            let new = ty::ResolvedOpaqueTy {
-                concrete_type: definition_ty,
-                substs: self.tcx().lift_to_global(&opaque_defn.substs).unwrap(),
-            };
-
-            let old = self.tables
-                .concrete_existential_types
-                .insert(def_id, new);
-            if let Some(old) = old {
-                if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
-                    span_bug!(
-                        span,
-                        "visit_opaque_types tried to write \
-                        different types for the same existential type: {:?}, {:?}, {:?}, {:?}",
-                        def_id,
-                        definition_ty,
-                        opaque_defn,
-                        old,
-                    );
+            if let Some(substs) = self.tcx().lift_to_global(&opaque_defn.substs) {
+                let new = ty::ResolvedOpaqueTy {
+                    concrete_type: definition_ty,
+                    substs,
+                };
+
+                let old = self.tables
+                    .concrete_existential_types
+                    .insert(def_id, new);
+                if let Some(old) = old {
+                    if old.concrete_type != definition_ty || old.substs != opaque_defn.substs {
+                        span_bug!(
+                            span,
+                            "visit_opaque_types tried to write \
+                            different types for the same existential type: {:?}, {:?}, {:?}, {:?}",
+                            def_id,
+                            definition_ty,
+                            opaque_defn,
+                            old,
+                        );
+                    }
                 }
+            } else {
+                self.tcx().sess.delay_span_bug(
+                    span,
+                    "cannot lift `opaque_defn` substs to global type context",
+                );
             }
         }
     }
diff --git a/src/test/ui/existential-type/issue-60371.rs b/src/test/ui/existential-type/issue-60371.rs
new file mode 100644
index 00000000000..f9def11d193
--- /dev/null
+++ b/src/test/ui/existential-type/issue-60371.rs
@@ -0,0 +1,15 @@
+trait Bug {
+    type Item: Bug;
+
+    const FUN: fn() -> Self::Item;
+}
+
+impl Bug for &() {
+    existential type Item: Bug; //~ ERROR existential types are unstable
+    //~^ ERROR the trait bound `(): Bug` is not satisfied
+    //~^^ ERROR could not find defining uses
+
+    const FUN: fn() -> Self::Item = || ();
+}
+
+fn main() {}
diff --git a/src/test/ui/existential-type/issue-60371.stderr b/src/test/ui/existential-type/issue-60371.stderr
new file mode 100644
index 00000000000..2560e01047a
--- /dev/null
+++ b/src/test/ui/existential-type/issue-60371.stderr
@@ -0,0 +1,29 @@
+error[E0658]: existential types are unstable
+  --> $DIR/issue-60371.rs:8:5
+   |
+LL |     existential type Item: Bug;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/34511
+   = help: add #![feature(existential_type)] to the crate attributes to enable
+
+error[E0277]: the trait bound `(): Bug` is not satisfied
+  --> $DIR/issue-60371.rs:8:5
+   |
+LL |     existential type Item: Bug;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bug` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <&() as Bug>
+   = note: the return type of a function must have a statically known size
+
+error: could not find defining uses
+  --> $DIR/issue-60371.rs:8:5
+   |
+LL |     existential type Item: Bug;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.