Skip to content

Commit 1763fcb

Browse files
committed
Don't crash on non-existent path in constant.
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.
1 parent dcb167e commit 1763fcb

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/librustc/middle/const_eval.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ pub enum ErrKind {
388388
ShiftRightWithOverflow,
389389
MissingStructField,
390390
NonConstPath,
391+
UnresolvedPath,
391392
ExpectedConstTuple,
392393
ExpectedConstStruct,
393394
TupleIndexOutOfBounds,
@@ -424,7 +425,8 @@ impl ConstEvalErr {
424425
ShiftLeftWithOverflow => "attempted left shift with overflow".into_cow(),
425426
ShiftRightWithOverflow => "attempted right shift with overflow".into_cow(),
426427
MissingStructField => "nonexistent struct field".into_cow(),
427-
NonConstPath => "non-constant path in constant expr".into_cow(),
428+
NonConstPath => "non-constant path in constant expression".into_cow(),
429+
UnresolvedPath => "unresolved path in constant expression".into_cow(),
428430
ExpectedConstTuple => "expected constant tuple".into_cow(),
429431
ExpectedConstStruct => "expected constant struct".into_cow(),
430432
TupleIndexOutOfBounds => "tuple index out of bounds".into_cow(),
@@ -916,7 +918,20 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
916918
}
917919
}
918920
hir::ExprPath(..) => {
919-
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
921+
let opt_def = if let Some(def) = tcx.def_map.borrow().get(&e.id) {
922+
// After type-checking, def_map contains definition of the
923+
// item referred to by the path. During type-checking, it
924+
// can contain the raw output of path resolution, which
925+
// might be a partially resolved path.
926+
// FIXME: There's probably a better way to make sure we don't
927+
// panic here.
928+
if def.depth != 0 {
929+
signal!(e, UnresolvedPath);
930+
}
931+
Some(def.full_def())
932+
} else {
933+
None
934+
};
920935
let (const_expr, const_ty) = match opt_def {
921936
Some(def::DefConst(def_id)) => {
922937
if def_id.is_local() {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
fn f(a: [u8; u32::DOESNOTEXIST]) {}
13+
//~^ ERROR unresolved path in constant expression
14+
}

0 commit comments

Comments
 (0)