]> git.lizzy.rs Git - rust.git/commitdiff
Don't crash on non-existent path in constant.
authorEli Friedman <eli.friedman@gmail.com>
Wed, 30 Sep 2015 22:04:21 +0000 (15:04 -0700)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 30 Sep 2015 22:04:21 +0000 (15:04 -0700)
The behavior here isn't really ideal, but we can't really do much better
given the current state of constant evaluation.

Fixes #28670, and probably a bunch of duplicates.

src/librustc/middle/const_eval.rs
src/test/compile-fail/invalid-path-in-const.rs [new file with mode: 0644]

index 4894a78f1acb4b6fd9bd5a6884381b15f90aa65a..50e74d196e67469cb975e9339a992b8105b6a587 100644 (file)
@@ -388,6 +388,7 @@ pub enum ErrKind {
     ShiftRightWithOverflow,
     MissingStructField,
     NonConstPath,
+    UnresolvedPath,
     ExpectedConstTuple,
     ExpectedConstStruct,
     TupleIndexOutOfBounds,
@@ -424,7 +425,8 @@ pub fn description(&self) -> Cow<str> {
             ShiftLeftWithOverflow => "attempted left shift with overflow".into_cow(),
             ShiftRightWithOverflow => "attempted right shift with overflow".into_cow(),
             MissingStructField  => "nonexistent struct field".into_cow(),
-            NonConstPath        => "non-constant path in constant expr".into_cow(),
+            NonConstPath        => "non-constant path in constant expression".into_cow(),
+            UnresolvedPath => "unresolved path in constant expression".into_cow(),
             ExpectedConstTuple => "expected constant tuple".into_cow(),
             ExpectedConstStruct => "expected constant struct".into_cow(),
             TupleIndexOutOfBounds => "tuple index out of bounds".into_cow(),
@@ -916,7 +918,20 @@ fn fromb(b: bool) -> ConstVal { Int(b as i64) }
         }
       }
       hir::ExprPath(..) => {
-          let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
+          let opt_def = if let Some(def) = tcx.def_map.borrow().get(&e.id) {
+              // After type-checking, def_map contains definition of the
+              // item referred to by the path. During type-checking, it
+              // can contain the raw output of path resolution, which
+              // might be a partially resolved path.
+              // FIXME: There's probably a better way to make sure we don't
+              // panic here.
+              if def.depth != 0 {
+                  signal!(e, UnresolvedPath);
+              }
+              Some(def.full_def())
+          } else {
+              None
+          };
           let (const_expr, const_ty) = match opt_def {
               Some(def::DefConst(def_id)) => {
                   if def_id.is_local() {
diff --git a/src/test/compile-fail/invalid-path-in-const.rs b/src/test/compile-fail/invalid-path-in-const.rs
new file mode 100644 (file)
index 0000000..3c4ad5a
--- /dev/null
@@ -0,0 +1,14 @@
+// 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.
+
+fn main() {
+    fn f(a: [u8; u32::DOESNOTEXIST]) {}
+    //~^ ERROR unresolved path in constant expression
+}