Skip to content

[beta] Process backports #50224

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

Merged
merged 4 commits 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 @@ -1430,3 +1430,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 @@ -139,6 +139,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
UnionsWithDropFields,
UnreachablePub,
TypeAliasBounds,
UnusedBrokenConst,
);

add_builtin_with_new!(sess,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,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>,
Expand All @@ -66,7 +66,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
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/interpret/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 2 additions & 4 deletions src/librustc_mir/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,17 +1146,15 @@ 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,
promoted: Some(Promoted::new(i)),
};
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(_) => {},
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_trans/mir/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
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
Loading