Only warn on erroneous promoted constants

This commit is contained in:
Oliver Schneider 2018-04-08 22:26:28 +02:00
parent 602b3957f1
commit a406af885d
No known key found for this signature in database
GPG Key ID: 1D5CB4FC597C3004
13 changed files with 129 additions and 30 deletions

View File

@ -57,7 +57,7 @@ pub fn mk_eval_cx<'a, 'tcx>(
Ok(ecx)
}
pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
pub fn eval_promoted<'a, 'mir, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
cid: GlobalId<'tcx>,
mir: &'mir mir::Mir<'tcx>,
@ -67,7 +67,7 @@ pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
match res {
Ok(val) => Some(val),
Err(mut err) => {
ecx.report(&mut err, true, None);
ecx.report(&mut err, false, None);
None
}
}

View File

@ -19,7 +19,7 @@ pub use self::place::{Place, PlaceExtra};
pub use self::memory::{Memory, MemoryKind, HasMemory};
pub use self::const_eval::{
eval_body_with_mir,
eval_promoted,
mk_borrowck_eval_cx,
eval_body,
CompileTimeEvaluator,

View File

@ -1177,7 +1177,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_substs: instance.substs,
}.visit_mir(&mir);
let param_env = ty::ParamEnv::reveal_all();
for (i, promoted) in mir.promoted.iter().enumerate() {
for i in 0..mir.promoted.len() {
use rustc_data_structures::indexed_vec::Idx;
let cid = GlobalId {
instance,
@ -1185,9 +1185,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
};
match tcx.const_eval(param_env.and(cid)) {
Ok(val) => collect_const(tcx, val, instance.substs, output),
Err(err) => {
err.report(tcx, promoted.span, "promoted");
}
Err(_) => {},
}
}
}

View File

@ -20,7 +20,7 @@ use rustc::mir::visit::{Visitor, PlaceContext};
use rustc::middle::const_val::ConstVal;
use rustc::ty::{TyCtxt, self, Instance};
use rustc::mir::interpret::{Value, PrimVal, GlobalId};
use interpret::{eval_body_with_mir, mk_borrowck_eval_cx, ValTy};
use interpret::{eval_promoted, mk_borrowck_eval_cx, ValTy};
use transform::{MirPass, MirSource};
use syntax::codemap::Span;
use rustc::ty::subst::Substs;
@ -161,7 +161,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
};
// cannot use `const_eval` here, because that would require having the MIR
// for the current function available, but we're producing said MIR right now
let (value, _, ty) = eval_body_with_mir(self.tcx, cid, self.mir, self.param_env)?;
let (value, _, ty) = eval_promoted(self.tcx, cid, self.mir, self.param_env)?;
let val = (value, ty, c.span);
trace!("evaluated {:?} to {:?}", c, val);
Some(val)

View File

@ -399,7 +399,14 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
self.mir_constant_to_miri_value(bx, constant)
.and_then(|c| OperandRef::from_const(bx, c, ty))
.unwrap_or_else(|err| {
err.report(bx.tcx(), constant.span, "const operand");
match constant.literal {
mir::Literal::Promoted { .. } => {
// don't report errors inside promoteds, just warnings.
},
mir::Literal::Value { .. } => {
err.report(bx.tcx(), constant.span, "const operand")
},
}
// We've errored, so we don't have to produce working code.
let layout = bx.cx.layout_of(ty);
PlaceRef::new_sized(

View File

@ -8,11 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-pass
const X: u32 = 5;
const Y: u32 = 6;
const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
//~^ WARN attempt to subtract with overflow
fn main() {
println!("{}", FOO); //~ E0080
println!("{}", FOO);
//~^ WARN constant evaluation error
}

View File

@ -1,17 +1,14 @@
warning: attempt to subtract with overflow
--> $DIR/conditional_array_execution.rs:13:19
--> $DIR/conditional_array_execution.rs:15:19
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ^^^^^
|
= note: #[warn(const_err)] on by default
error[E0080]: constant evaluation error
--> $DIR/conditional_array_execution.rs:17:20
warning: constant evaluation error
--> $DIR/conditional_array_execution.rs:19:20
|
LL | println!("{}", FOO); //~ E0080
LL | println!("{}", FOO);
| ^^^ referenced constant has errors
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-pass
#![feature(const_fn)]
const fn foo(x: u32) -> u32 {
@ -20,6 +22,6 @@ fn main() {
const Y: u32 = foo(0-1);
//~^ WARN attempt to subtract with overflow
println!("{} {}", X, Y);
//~^ ERROR constant evaluation error
//~| ERROR constant evaluation error
//~^ WARN constant evaluation error
//~| WARN constant evaluation error
}

View File

@ -1,29 +1,26 @@
warning: attempt to subtract with overflow
--> $DIR/issue-43197.rs:18:20
--> $DIR/issue-43197.rs:20:20
|
LL | const X: u32 = 0-1;
| ^^^
|
= note: #[warn(const_err)] on by default
error[E0080]: constant evaluation error
--> $DIR/issue-43197.rs:22:23
warning: constant evaluation error
--> $DIR/issue-43197.rs:24:23
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
warning: attempt to subtract with overflow
--> $DIR/issue-43197.rs:20:24
--> $DIR/issue-43197.rs:22:24
|
LL | const Y: u32 = foo(0-1);
| ^^^
error[E0080]: constant evaluation error
--> $DIR/issue-43197.rs:22:26
warning: constant evaluation error
--> $DIR/issue-43197.rs:24:26
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.

View File

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-pass
trait Foo {
const AMT: usize;
}
@ -30,5 +32,6 @@ impl Foo for u16 {
}
fn main() {
println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ E0080
println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
//~^ WARN const_err
}

View File

@ -0,0 +1,14 @@
warning: constant evaluation error
--> $DIR/issue-44578.rs:35:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
|
= note: #[warn(const_err)] on by default
warning: constant evaluation error
--> $DIR/issue-44578.rs:35:20
|
LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); //~ WARN const_err
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors

View File

@ -0,0 +1,28 @@
// 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.
// compile-pass
fn main() {
println!("{}", 0u32 - 1);
//~^ WARN const_err
//~| WARN const_err
let _x = 0u32 - 1;
//~^ WARN const_err
println!("{}", 1/(1-1));
//~^ WARN const_err
//~| WARN const_err
let _x = 1/(1-1);
//~^ WARN const_err
//~| WARN const_err
println!("{}", 1/(false as u32));
//~^ WARN const_err
let _x = 1/(false as u32);
}

View File

@ -0,0 +1,50 @@
warning: constant evaluation error
--> $DIR/promoted_errors.rs:14:20
|
LL | println!("{}", 0u32 - 1);
| ^^^^^^^^ attempted to do overflowing math
|
= note: #[warn(const_err)] on by default
warning: constant evaluation error
--> $DIR/promoted_errors.rs:14:20
|
LL | println!("{}", 0u32 - 1);
| ^^^^^^^^ attempted to do overflowing math
warning: constant evaluation error
--> $DIR/promoted_errors.rs:17:14
|
LL | let _x = 0u32 - 1;
| ^^^^^^^^ attempted to do overflowing math
warning: attempt to divide by zero
--> $DIR/promoted_errors.rs:19:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^
warning: constant evaluation error
--> $DIR/promoted_errors.rs:19:20
|
LL | println!("{}", 1/(1-1));
| ^^^^^^^ attempted to do overflowing math
warning: attempt to divide by zero
--> $DIR/promoted_errors.rs:22:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^
warning: constant evaluation error
--> $DIR/promoted_errors.rs:22:14
|
LL | let _x = 1/(1-1);
| ^^^^^^^ attempted to do overflowing math
warning: constant evaluation error
--> $DIR/promoted_errors.rs:25:20
|
LL | println!("{}", 1/(false as u32));
| ^^^^^^^^^^^^^^^^ attempted to do overflowing math