Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn on all erroneous constants #50110

Merged
merged 1 commit into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,3 +1441,71 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
}
}
}

/// Lint constants that are erroneous.
/// Without this lint, we might not get any diagnostic if the constant is
/// unused within this crate, even though downstream crates can't use it
/// without producing an error.
pub struct UnusedBrokenConst;

impl LintPass for UnusedBrokenConst {
fn get_lints(&self) -> LintArray {
lint_array!()
}
}

fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) {
let def_id = cx.tcx.hir.body_owner_def_id(body_id);
let param_env = cx.tcx.param_env(def_id);
let cid = ::rustc::mir::interpret::GlobalId {
instance: ty::Instance::mono(cx.tcx, def_id),
promoted: None
};
if let Err(err) = cx.tcx.const_eval(param_env.and(cid)) {
let span = cx.tcx.def_span(def_id);
let mut diag = cx.struct_span_lint(
CONST_ERR,
span,
&format!("this {} cannot be used", what),
);
use rustc::middle::const_val::ConstEvalErrDescription;
match err.description() {
ConstEvalErrDescription::Simple(message) => {
diag.span_label(span, message);
}
ConstEvalErrDescription::Backtrace(miri, frames) => {
diag.span_label(span, format!("{}", miri));
for frame in frames {
diag.span_label(frame.span, format!("inside call to `{}`", frame.location));
}
}
}
diag.emit()
}
}

struct UnusedBrokenConstVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);

impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for UnusedBrokenConstVisitor<'a, 'tcx> {
fn visit_nested_body(&mut self, id: hir::BodyId) {
check_const(self.0, id, "array length");
}
fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
hir::intravisit::NestedVisitorMap::None
}
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
match it.node {
hir::ItemConst(_, body_id) => {
check_const(cx, body_id, "constant");
},
hir::ItemTy(ref ty, _) => hir::intravisit::walk_ty(
&mut UnusedBrokenConstVisitor(cx),
ty
),
_ => {},
}
}
}
1 change: 1 addition & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
UnionsWithDropFields,
UnreachablePub,
TypeAliasBounds,
UnusedBrokenConst,
);

add_builtin_with_new!(sess,
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/array_const_index-0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const A: &'static [i32] = &[];
const B: i32 = (&A)[1];
//~^ ERROR constant evaluation error
//~| index out of bounds: the len is 0 but the index is 1
//~| WARN this constant cannot be used

fn main() {
let _ = B;
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/array_const_index-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const A: [i32; 0] = [];
const B: i32 = A[1];
//~^ ERROR constant evaluation error
//~| index out of bounds: the len is 0 but the index is 1
//~| WARN this constant cannot be used

fn main() {
let _ = B;
Expand Down
18 changes: 9 additions & 9 deletions src/test/compile-fail/const-err-early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@

#![deny(const_err)]

pub const A: i8 = -std::i8::MIN; //~ ERROR E0080
//~^ ERROR attempt to negate with overflow
pub const A: i8 = -std::i8::MIN; //~ ERROR const_err
//~^ ERROR this constant cannot be used
//~| ERROR constant evaluation error
pub const B: u8 = 200u8 + 200u8; //~ ERROR E0080
//~^ ERROR attempt to add with overflow
pub const C: u8 = 200u8 * 4; //~ ERROR E0080
//~^ ERROR attempt to multiply with overflow
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR E0080
//~^ ERROR attempt to subtract with overflow
pub const B: u8 = 200u8 + 200u8; //~ ERROR const_err
//~^ ERROR this constant cannot be used
pub const C: u8 = 200u8 * 4; //~ ERROR const_err
//~^ ERROR this constant cannot be used
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR const_err
//~^ ERROR this constant cannot be used
pub const E: u8 = [5u8][1];
//~^ ERROR E0080
//~^ ERROR const_err

fn main() {
let _a = A;
Expand Down
7 changes: 4 additions & 3 deletions src/test/compile-fail/const-err-multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ pub const A: i8 = -std::i8::MIN;
//~^ ERROR E0080
//~| ERROR attempt to negate with overflow
//~| ERROR constant evaluation error
//~| ERROR this constant cannot be used
pub const B: i8 = A;
//~^ ERROR E0080
//~^ ERROR const_err
pub const C: u8 = A as u8;
//~^ ERROR E0080
//~^ ERROR const_err
pub const D: i8 = 50 - A;
//~^ ERROR E0080
//~^ ERROR const_err

fn main() {
let _ = (A, B, C, D);
Expand Down
32 changes: 16 additions & 16 deletions src/test/compile-fail/const-eval-overflow2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};

const VALS_I8: (i8,) =
//~^ ERROR this constant cannot be used
(
i8::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_I16: (i16,) =
//~^ ERROR this constant cannot be used
(
i16::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_I32: (i32,) =
//~^ ERROR this constant cannot be used
(
i32::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_I64: (i64,) =
//~^ ERROR this constant cannot be used
(
i64::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_U8: (u8,) =
//~^ ERROR this constant cannot be used
(
u8::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_U16: (u16,) = (
//~^ ERROR this constant cannot be used
u16::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_U32: (u32,) = (
//~^ ERROR this constant cannot be used
u32::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

const VALS_U64: (u64,) =
//~^ ERROR this constant cannot be used
(
u64::MIN - 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to subtract with overflow
//~^ ERROR attempt to subtract with overflow
);

fn main() {
Expand Down
32 changes: 16 additions & 16 deletions src/test/compile-fail/const-eval-overflow2b.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};

const VALS_I8: (i8,) =
//~^ ERROR this constant cannot be used
(
i8::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_I16: (i16,) =
//~^ ERROR this constant cannot be used
(
i16::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_I32: (i32,) =
//~^ ERROR this constant cannot be used
(
i32::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_I64: (i64,) =
//~^ ERROR this constant cannot be used
(
i64::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_U8: (u8,) =
//~^ ERROR this constant cannot be used
(
u8::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_U16: (u16,) = (
//~^ ERROR this constant cannot be used
u16::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_U32: (u32,) = (
//~^ ERROR this constant cannot be used
u32::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

const VALS_U64: (u64,) =
//~^ ERROR this constant cannot be used
(
u64::MAX + 1,
//~^ ERROR constant evaluation error
//~| ERROR attempt to add with overflow
//~^ ERROR attempt to add with overflow
);

fn main() {
Expand Down
32 changes: 16 additions & 16 deletions src/test/compile-fail/const-eval-overflow2c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};

const VALS_I8: (i8,) =
//~^ ERROR this constant cannot be used
(
i8::MIN * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_I16: (i16,) =
//~^ ERROR this constant cannot be used
(
i16::MIN * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_I32: (i32,) =
//~^ ERROR this constant cannot be used
(
i32::MIN * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_I64: (i64,) =
//~^ ERROR this constant cannot be used
(
i64::MIN * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_U8: (u8,) =
//~^ ERROR this constant cannot be used
(
u8::MAX * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_U16: (u16,) = (
//~^ ERROR this constant cannot be used
u16::MAX * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_U32: (u32,) = (
//~^ ERROR this constant cannot be used
u32::MAX * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

const VALS_U64: (u64,) =
//~^ ERROR this constant cannot be used
(
u64::MAX * 2,
//~^ ERROR constant evaluation error
//~| ERROR attempt to multiply with overflow
//~^ ERROR attempt to multiply with overflow
);

fn main() {
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/const-slice-oob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const FOO: &'static[u32] = &[1, 2, 3];
const BAR: u32 = FOO[5];
//~^ ERROR constant evaluation error [E0080]
//~| index out of bounds: the len is 3 but the index is 5
//~| WARN this constant cannot be used

fn main() {
let _ = BAR;
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/const-eval/conditional_array_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ 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
//~| WARN this constant cannot be used

fn main() {
println!("{}", FOO);
Expand Down
8 changes: 7 additions & 1 deletion src/test/ui/const-eval/conditional_array_execution.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
|
= note: #[warn(const_err)] on by default

warning: this constant cannot be used
--> $DIR/conditional_array_execution.rs:15:1
|
LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow

warning: constant evaluation error
--> $DIR/conditional_array_execution.rs:19:20
--> $DIR/conditional_array_execution.rs:20:20
|
LL | println!("{}", FOO);
| ^^^ referenced constant has errors
Expand Down
Loading