about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-03-10 16:24:34 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-04-15 10:22:51 -0700
commitf47c4ffdfacc783b3fe4bad395a6e16ae296b3d1 (patch)
tree4056b185d3e91b7c3b5724c7404419c9bde998b4
parentdf768c5c8fcb361c4dc94b4c776d6a78c12862e1 (diff)
downloadrust-f47c4ffdfacc783b3fe4bad395a6e16ae296b3d1.tar.gz
rust-f47c4ffdfacc783b3fe4bad395a6e16ae296b3d1.zip
Do not ICE in the face of invalid enum discriminant
-rw-r--r--src/librustc_middle/ty/mod.rs6
-rw-r--r--src/librustc_mir_build/hair/cx/expr.rs14
-rw-r--r--src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs35
-rw-r--r--src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr123
4 files changed, 173 insertions, 5 deletions
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 8d50f560a83..430ff67d56b 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -2399,7 +2399,11 @@ impl<'tcx> AdtDef {
                 None
             }
             Err(ErrorHandled::TooGeneric) => {
-                span_bug!(tcx.def_span(expr_did), "enum discriminant depends on generic arguments",)
+                tcx.sess.delay_span_bug(
+                    tcx.def_span(expr_did),
+                    "enum discriminant depends on generic arguments",
+                );
+                None
             }
         }
     }
diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs
index 21d632b9f6b..d2d99cf030d 100644
--- a/src/librustc_mir_build/hair/cx/expr.rs
+++ b/src/librustc_mir_build/hair/cx/expr.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast,
 };
 use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
-use rustc_middle::ty::{self, AdtKind, Ty};
+use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
 use rustc_span::Span;
 
 impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr<'tcx> {
@@ -718,8 +718,7 @@ fn convert_path_expr<'a, 'tcx>(
 
         Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id) => {
             let user_provided_types = cx.tables.user_provided_types();
-            let user_provided_type = user_provided_types.get(expr.hir_id).copied();
-            debug!("convert_path_expr: user_provided_type={:?}", user_provided_type);
+            let user_ty = user_provided_types.get(expr.hir_id).copied();
             let ty = cx.tables().node_type(expr.hir_id);
             match ty.kind {
                 // A unit struct/variant which is used as a value.
@@ -728,10 +727,17 @@ fn convert_path_expr<'a, 'tcx>(
                     adt_def,
                     variant_index: adt_def.variant_index_with_ctor_id(def_id),
                     substs,
-                    user_ty: user_provided_type,
+                    user_ty,
                     fields: vec![],
                     base: None,
                 },
+                _ if ty.references_error() => {
+                    // Handle degenerate input without ICE (#67377).
+                    ExprKind::Literal {
+                        literal: ty::Const::zero_sized(cx.tcx, cx.tcx.types.err),
+                        user_ty: None,
+                    }
+                }
                 _ => bug!("unexpected ty: {:?}", ty),
             }
         }
diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs
new file mode 100644
index 00000000000..87222ef4b59
--- /dev/null
+++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.rs
@@ -0,0 +1,35 @@
+mod a {
+    use std::marker::PhantomData;
+
+    enum Bug {
+        V = [PhantomData; { [ () ].len() ].len() as isize,
+        //~^ ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+    }
+}
+
+mod b {
+    enum Bug {
+        V = [Vec::new; { [].len()  ].len() as isize,
+        //~^ ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR type annotations needed
+    }
+}
+
+mod c {
+    enum Bug {
+        V = [Vec::new; { [0].len() ].len() as isize,
+        //~^ ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR mismatched closing delimiter: `]`
+        //~| ERROR type annotations needed
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr
new file mode 100644
index 00000000000..f20ec755353
--- /dev/null
+++ b/src/test/ui/parser/issue-67377-invalid-syntax-in-enum-discriminant.stderr
@@ -0,0 +1,123 @@
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:5:42
+   |
+LL |         V = [PhantomData; { [ () ].len() ].len() as isize,
+   |             -             -              ^ mismatched closing delimiter
+   |             |             |
+   |             |             unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:36
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error: mismatched closing delimiter: `]`
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:36
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |             -          -           ^ mismatched closing delimiter
+   |             |          |
+   |             |          unclosed delimiter
+   |             closing delimiter possibly meant for this
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:15:29
+   |
+LL |         V = [Vec::new; { [].len()  ].len() as isize,
+   |                             ^^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-67377-invalid-syntax-in-enum-discriminant.rs:26:14
+   |
+LL |         V = [Vec::new; { [0].len() ].len() as isize,
+   |              ^^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0282`.