}
}
}
+
+/// 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
+ ),
+ _ => {},
+ }
+ }
+}
UnionsWithDropFields,
UnreachablePub,
TypeAliasBounds,
+ UnusedBrokenConst,
);
add_builtin_with_new!(sess,
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;
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;
#![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;
//~^ 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);
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() {
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() {
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() {
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;
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);
|
= 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
fn main() {
const X: u32 = 0-1;
//~^ WARN attempt to subtract with overflow
+ //~| WARN this constant cannot be used
const Y: u32 = foo(0-1);
//~^ WARN attempt to subtract with overflow
+ //~| WARN this constant cannot be used
println!("{} {}", X, Y);
//~^ WARN constant evaluation error
//~| WARN constant evaluation error
|
= note: #[warn(const_err)] on by default
-warning: constant evaluation error
- --> $DIR/issue-43197.rs:24:23
+warning: this constant cannot be used
+ --> $DIR/issue-43197.rs:20:5
|
-LL | println!("{} {}", X, Y);
- | ^ referenced constant has errors
+LL | const X: u32 = 0-1;
+ | ^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
warning: attempt to subtract with overflow
- --> $DIR/issue-43197.rs:22:24
+ --> $DIR/issue-43197.rs:23:24
|
LL | const Y: u32 = foo(0-1);
| ^^^
+warning: this constant cannot be used
+ --> $DIR/issue-43197.rs:23:5
+ |
+LL | const Y: u32 = foo(0-1);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+warning: constant evaluation error
+ --> $DIR/issue-43197.rs:26:23
+ |
+LL | println!("{} {}", X, Y);
+ | ^ referenced constant has errors
+
warning: constant evaluation error
- --> $DIR/issue-43197.rs:24:26
+ --> $DIR/issue-43197.rs:26:26
|
LL | println!("{} {}", X, Y);
| ^ referenced constant has errors
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![deny(const_err)]
+// compile-pass
#![crate_type = "lib"]
pub const Z: u32 = 0 - 1;
-//~^ ERROR attempt to subtract with overflow
+//~^ WARN attempt to subtract with overflow
+//~| WARN this constant cannot be used
+
+pub type Foo = [i32; 0 - 1];
+//~^ WARN attempt to subtract with overflow
+//~| WARN this array length cannot be used
-error: attempt to subtract with overflow
+warning: attempt to subtract with overflow
--> $DIR/pub_const_err.rs:15:20
|
LL | pub const Z: u32 = 0 - 1;
| ^^^^^
|
-note: lint level defined here
- --> $DIR/pub_const_err.rs:11:9
+ = note: #[warn(const_err)] on by default
+
+warning: this constant cannot be used
+ --> $DIR/pub_const_err.rs:15:1
|
-LL | #![deny(const_err)]
- | ^^^^^^^^^
+LL | pub const Z: u32 = 0 - 1;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
-error: aborting due to previous error
+warning: attempt to subtract with overflow
+ --> $DIR/pub_const_err.rs:19:22
+ |
+LL | pub type Foo = [i32; 0 - 1];
+ | ^^^^^
+
+warning: this array length cannot be used
+ --> $DIR/pub_const_err.rs:19:22
+ |
+LL | pub type Foo = [i32; 0 - 1];
+ | ^^^^^ attempt to subtract with overflow
--- /dev/null
+// Copyright 2017 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
+
+pub const Z: u32 = 0 - 1;
+//~^ WARN attempt to subtract with overflow
+//~| WARN this constant cannot be used
+
+pub type Foo = [i32; 0 - 1];
+//~^ WARN attempt to subtract with overflow
+//~| WARN this array length cannot be used
+
+fn main() {}
--- /dev/null
+warning: attempt to subtract with overflow
+ --> $DIR/pub_const_err_bin.rs:13:20
+ |
+LL | pub const Z: u32 = 0 - 1;
+ | ^^^^^
+ |
+ = note: #[warn(const_err)] on by default
+
+warning: this constant cannot be used
+ --> $DIR/pub_const_err_bin.rs:13:1
+ |
+LL | pub const Z: u32 = 0 - 1;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+warning: attempt to subtract with overflow
+ --> $DIR/pub_const_err_bin.rs:17:22
+ |
+LL | pub type Foo = [i32; 0 - 1];
+ | ^^^^^
+
+warning: this array length cannot be used
+ --> $DIR/pub_const_err_bin.rs:17:22
+ |
+LL | pub type Foo = [i32; 0 - 1];
+ | ^^^^^ attempt to subtract with overflow
+