mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 19:17:43 +00:00
don't report errors in constants at every use site
This commit is contained in:
parent
23a7d30fc2
commit
d38a58d46d
@ -364,7 +364,7 @@ pub struct ConstEvalErr {
|
|||||||
pub kind: ErrKind,
|
pub kind: ErrKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone)]
|
||||||
pub enum ErrKind {
|
pub enum ErrKind {
|
||||||
CannotCast,
|
CannotCast,
|
||||||
CannotCastTo(&'static str),
|
CannotCastTo(&'static str),
|
||||||
@ -414,6 +414,7 @@ pub enum ErrKind {
|
|||||||
/// Expected, Got
|
/// Expected, Got
|
||||||
TypeMismatch(String, ConstInt),
|
TypeMismatch(String, ConstInt),
|
||||||
BadType(ConstVal),
|
BadType(ConstVal),
|
||||||
|
ErroneousReferencedConstant(Box<ConstEvalErr>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ConstMathErr> for ErrKind {
|
impl From<ConstMathErr> for ErrKind {
|
||||||
@ -480,6 +481,7 @@ impl ConstEvalErr {
|
|||||||
expected, got.description()).into_cow()
|
expected, got.description()).into_cow()
|
||||||
},
|
},
|
||||||
BadType(ref i) => format!("value of wrong type: {:?}", i).into_cow(),
|
BadType(ref i) => format!("value of wrong type: {:?}", i).into_cow(),
|
||||||
|
ErroneousReferencedConstant(_) => "could not evaluate referenced constant".into_cow(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,6 +698,8 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||||||
|
|
||||||
let val = match eval_const_expr_partial(tcx, &base, base_hint, fn_args) {
|
let val = match eval_const_expr_partial(tcx, &base, base_hint, fn_args) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
|
Err(ConstEvalErr { kind: ErroneousReferencedConstant(
|
||||||
|
box ConstEvalErr { kind: TypeMismatch(_, val), .. }), .. }) |
|
||||||
Err(ConstEvalErr { kind: TypeMismatch(_, val), .. }) => {
|
Err(ConstEvalErr { kind: TypeMismatch(_, val), .. }) => {
|
||||||
// Something like `5i8 as usize` doesn't need a type hint for the base
|
// Something like `5i8 as usize` doesn't need a type hint for the base
|
||||||
// instead take the type hint from the inner value
|
// instead take the type hint from the inner value
|
||||||
@ -737,19 +741,31 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
if let Some((e, ty)) = lookup_const_by_id(tcx, def_id, substs) {
|
if let Some((expr, ty)) = lookup_const_by_id(tcx, def_id, substs) {
|
||||||
let item_hint = match ty {
|
let item_hint = match ty {
|
||||||
Some(ty) => ty_hint.checked_or(ty),
|
Some(ty) => ty_hint.checked_or(ty),
|
||||||
None => ty_hint,
|
None => ty_hint,
|
||||||
};
|
};
|
||||||
eval_const_expr_partial(tcx, e, item_hint, None)?
|
match eval_const_expr_partial(tcx, expr, item_hint, None) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
debug!("bad reference: {:?}, {:?}", err.description(), err.span);
|
||||||
|
signal!(e, ErroneousReferencedConstant(box err))
|
||||||
|
},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
signal!(e, NonConstPath);
|
signal!(e, NonConstPath);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Def::Variant(enum_def, variant_def) => {
|
Def::Variant(enum_def, variant_def) => {
|
||||||
if let Some(const_expr) = lookup_variant_by_id(tcx, enum_def, variant_def) {
|
if let Some(const_expr) = lookup_variant_by_id(tcx, enum_def, variant_def) {
|
||||||
eval_const_expr_partial(tcx, const_expr, ty_hint, None)?
|
match eval_const_expr_partial(tcx, const_expr, ty_hint, None) {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
debug!("bad reference: {:?}, {:?}", err.description(), err.span);
|
||||||
|
signal!(e, ErroneousReferencedConstant(box err))
|
||||||
|
},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
signal!(e, UnimplementedConstVal("enum variants"));
|
signal!(e, UnimplementedConstVal("enum variants"));
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
#![feature(iter_arith)]
|
#![feature(iter_arith)]
|
||||||
#![feature(question_mark)]
|
#![feature(question_mark)]
|
||||||
|
#![feature(box_patterns)]
|
||||||
|
#![feature(box_syntax)]
|
||||||
|
|
||||||
#[macro_use] extern crate syntax;
|
#[macro_use] extern crate syntax;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
|
@ -29,6 +29,7 @@ use rustc::ty::cast::{CastKind};
|
|||||||
use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
|
use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
|
||||||
use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
|
use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
|
||||||
use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal};
|
use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal};
|
||||||
|
use rustc_const_eval::ErrKind::ErroneousReferencedConstant;
|
||||||
use rustc_const_eval::EvalHint::ExprTypeChecked;
|
use rustc_const_eval::EvalHint::ExprTypeChecked;
|
||||||
use rustc::hir::def::Def;
|
use rustc::hir::def::Def;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
@ -114,6 +115,7 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
|||||||
match err.kind {
|
match err.kind {
|
||||||
UnimplementedConstVal(_) => {},
|
UnimplementedConstVal(_) => {},
|
||||||
IndexOpFeatureGated => {},
|
IndexOpFeatureGated => {},
|
||||||
|
ErroneousReferencedConstant(_) => {},
|
||||||
_ => self.tcx.sess.add_lint(CONST_ERR, expr.id, expr.span,
|
_ => self.tcx.sess.add_lint(CONST_ERR, expr.id, expr.span,
|
||||||
format!("constant evaluation error: {}. This will \
|
format!("constant evaluation error: {}. This will \
|
||||||
become a HARD ERROR in the future",
|
become a HARD ERROR in the future",
|
||||||
|
@ -50,8 +50,9 @@
|
|||||||
|
|
||||||
use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
|
use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
|
||||||
use middle::const_val::ConstVal;
|
use middle::const_val::ConstVal;
|
||||||
use rustc_const_eval::eval_const_expr_partial;
|
use rustc_const_eval::{eval_const_expr_partial, ConstEvalErr};
|
||||||
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
||||||
|
use rustc_const_eval::ErrKind::ErroneousReferencedConstant;
|
||||||
use hir::def::{self, Def};
|
use hir::def::{self, Def};
|
||||||
use hir::def_id::DefId;
|
use hir::def_id::DefId;
|
||||||
use middle::resolve_lifetime as rl;
|
use middle::resolve_lifetime as rl;
|
||||||
@ -1693,7 +1694,10 @@ pub fn ast_ty_to_ty<'tcx>(this: &AstConv<'tcx>,
|
|||||||
"expected usize value for array length, got {}", val.description());
|
"expected usize value for array length, got {}", val.description());
|
||||||
this.tcx().types.err
|
this.tcx().types.err
|
||||||
},
|
},
|
||||||
Err(ref r) => {
|
// array length errors happen before the global constant check
|
||||||
|
// so we need to report the real error
|
||||||
|
Err(ConstEvalErr { kind: ErroneousReferencedConstant(box r), ..}) |
|
||||||
|
Err(r) => {
|
||||||
let mut err = struct_span_err!(tcx.sess, r.span, E0250,
|
let mut err = struct_span_err!(tcx.sess, r.span, E0250,
|
||||||
"array length constant evaluation error: {}",
|
"array length constant evaluation error: {}",
|
||||||
r.description());
|
r.description());
|
||||||
|
@ -68,7 +68,8 @@ use middle::lang_items::SizedTraitLangItem;
|
|||||||
use middle::resolve_lifetime;
|
use middle::resolve_lifetime;
|
||||||
use middle::const_val::ConstVal;
|
use middle::const_val::ConstVal;
|
||||||
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
use rustc_const_eval::EvalHint::UncheckedExprHint;
|
||||||
use rustc_const_eval::eval_const_expr_partial;
|
use rustc_const_eval::{eval_const_expr_partial, ConstEvalErr};
|
||||||
|
use rustc_const_eval::ErrKind::ErroneousReferencedConstant;
|
||||||
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
|
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
|
||||||
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
|
||||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
|
||||||
@ -1061,6 +1062,9 @@ fn convert_enum_def<'tcx>(tcx: &TyCtxt<'tcx>,
|
|||||||
print_err(tcx, e.span, ty_hint, cv);
|
print_err(tcx, e.span, ty_hint, cv);
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
// enum variant evaluation happens before the global constant check
|
||||||
|
// so we need to report the real error
|
||||||
|
Err(ConstEvalErr { kind: ErroneousReferencedConstant(box err), ..}) |
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
|
let mut diag = struct_span_err!(tcx.sess, err.span, E0080,
|
||||||
"constant evaluation error: {}",
|
"constant evaluation error: {}",
|
||||||
|
19
src/test/compile-fail/const-err-multi.rs
Normal file
19
src/test/compile-fail/const-err-multi.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
#![deny(const_err)]
|
||||||
|
|
||||||
|
pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
|
||||||
|
pub const B: i8 = A;
|
||||||
|
pub const C: u8 = A as u8;
|
||||||
|
pub const D: i8 = 50 - A;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user