]> git.lizzy.rs Git - rust.git/commitdiff
Fix ICEs with match/return expressions inside array lengths
authorvarkor <github@varkor.com>
Sun, 1 Jul 2018 19:57:23 +0000 (20:57 +0100)
committervarkor <github@varkor.com>
Mon, 2 Jul 2018 18:44:27 +0000 (19:44 +0100)
src/librustc/ty/layout.rs
src/librustc_mir/hair/pattern/mod.rs
src/test/ui/return-match-array-const.rs [new file with mode: 0644]
src/test/ui/return-match-array-const.stderr [new file with mode: 0644]

index f5c2a0c3f9f05f504c09026d9ec714749b7e8fff..0763c8af5d037a02d69e2ed51b5af57ef475915e 100644 (file)
@@ -1118,9 +1118,12 @@ enum StructKind {
             ty::TyParam(_) => {
                 return Err(LayoutError::Unknown(ty));
             }
-            ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => {
+            ty::TyGeneratorWitness(..) | ty::TyInfer(_) => {
                 bug!("LayoutDetails::compute: unexpected type `{}`", ty)
             }
+            ty::TyError => {
+                return Err(LayoutError::Unknown(ty));
+            }
         })
     }
 
index 4d0e3e826e8789f01efa54b5c2328aea90093929..2291387792b0e2c689066cf4b946e2d7deaab749 100644 (file)
@@ -743,8 +743,10 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
                         );
                         *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
                     },
-                    Err(()) => {
-                        self.errors.push(PatternError::FloatBug);
+                    Err(float_bug) => {
+                        if float_bug {
+                            self.errors.push(PatternError::FloatBug);
+                        }
                         PatternKind::Wild
                     },
                 }
@@ -764,8 +766,10 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
                         );
                         *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
                     },
-                    Err(()) => {
-                        self.errors.push(PatternError::FloatBug);
+                    Err(float_bug) => {
+                        if float_bug {
+                            self.errors.push(PatternError::FloatBug);
+                        }
                         PatternKind::Wild
                     },
                 }
@@ -1123,7 +1127,7 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           ty: Ty<'tcx>,
                           neg: bool)
-                          -> Result<&'tcx ty::Const<'tcx>, ()> {
+                          -> Result<&'tcx ty::Const<'tcx>, bool> {
     use syntax::ast::*;
 
     use rustc::mir::interpret::*;
@@ -1152,7 +1156,11 @@ enum Int {
                 ty::TyInt(other) => Int::Signed(other),
                 ty::TyUint(UintTy::Usize) => Int::Unsigned(tcx.sess.target.usize_ty),
                 ty::TyUint(other) => Int::Unsigned(other),
-                _ => bug!(),
+                ty::TyError => {
+                    // Avoid ICE
+                    return Err(false);
+                }
+                _ => bug!("{:?}", ty.sty),
             };
             // This converts from LitKind::Int (which is sign extended) to
             // Scalar::Bytes (which is zero extended)
@@ -1182,14 +1190,14 @@ enum Int {
             })
         },
         LitKind::Float(n, fty) => {
-            parse_float(n, fty, neg)?
+            parse_float(n, fty, neg).map_err(|_| true)?
         }
         LitKind::FloatUnsuffixed(n) => {
             let fty = match ty.sty {
                 ty::TyFloat(fty) => fty,
                 _ => bug!()
             };
-            parse_float(n, fty, neg)?
+            parse_float(n, fty, neg).map_err(|_| true)?
         }
         LitKind::Bool(b) => ConstValue::Scalar(Scalar::Bits {
             bits: b as u128,
diff --git a/src/test/ui/return-match-array-const.rs b/src/test/ui/return-match-array-const.rs
new file mode 100644 (file)
index 0000000..45fc571
--- /dev/null
@@ -0,0 +1,17 @@
+// Copyright 2018 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.
+
+fn main() {
+    [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body
+
+    [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body
+
+    [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body
+}
diff --git a/src/test/ui/return-match-array-const.stderr b/src/test/ui/return-match-array-const.stderr
new file mode 100644 (file)
index 0000000..044dc8f
--- /dev/null
@@ -0,0 +1,21 @@
+error[E0572]: return statement outside of function body
+  --> $DIR/return-match-array-const.rs:12:10
+   |
+LL |     [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/return-match-array-const.rs:14:10
+   |
+LL |     [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0572]: return statement outside of function body
+  --> $DIR/return-match-array-const.rs:16:10
+   |
+LL |     [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0572`.