Skip to content

Commit 1861fb5

Browse files
committed
Auto merge of #50224 - pietroalbini:beta-backports, r=alexcrichton
[beta] Process backports * #49779: Don't report compile-time errors for promoteds * #50110: Warn on all erroneous constants
2 parents 5181002 + 656d825 commit 1861fb5

27 files changed

+357
-100
lines changed

src/librustc_lint/builtin.rs

+68
Original file line numberDiff line numberDiff line change
@@ -1430,3 +1430,71 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
14301430
}
14311431
}
14321432
}
1433+
1434+
/// Lint constants that are erroneous.
1435+
/// Without this lint, we might not get any diagnostic if the constant is
1436+
/// unused within this crate, even though downstream crates can't use it
1437+
/// without producing an error.
1438+
pub struct UnusedBrokenConst;
1439+
1440+
impl LintPass for UnusedBrokenConst {
1441+
fn get_lints(&self) -> LintArray {
1442+
lint_array!()
1443+
}
1444+
}
1445+
1446+
fn check_const(cx: &LateContext, body_id: hir::BodyId, what: &str) {
1447+
let def_id = cx.tcx.hir.body_owner_def_id(body_id);
1448+
let param_env = cx.tcx.param_env(def_id);
1449+
let cid = ::rustc::mir::interpret::GlobalId {
1450+
instance: ty::Instance::mono(cx.tcx, def_id),
1451+
promoted: None
1452+
};
1453+
if let Err(err) = cx.tcx.const_eval(param_env.and(cid)) {
1454+
let span = cx.tcx.def_span(def_id);
1455+
let mut diag = cx.struct_span_lint(
1456+
CONST_ERR,
1457+
span,
1458+
&format!("this {} cannot be used", what),
1459+
);
1460+
use rustc::middle::const_val::ConstEvalErrDescription;
1461+
match err.description() {
1462+
ConstEvalErrDescription::Simple(message) => {
1463+
diag.span_label(span, message);
1464+
}
1465+
ConstEvalErrDescription::Backtrace(miri, frames) => {
1466+
diag.span_label(span, format!("{}", miri));
1467+
for frame in frames {
1468+
diag.span_label(frame.span, format!("inside call to `{}`", frame.location));
1469+
}
1470+
}
1471+
}
1472+
diag.emit()
1473+
}
1474+
}
1475+
1476+
struct UnusedBrokenConstVisitor<'a, 'tcx: 'a>(&'a LateContext<'a, 'tcx>);
1477+
1478+
impl<'a, 'tcx, 'v> hir::intravisit::Visitor<'v> for UnusedBrokenConstVisitor<'a, 'tcx> {
1479+
fn visit_nested_body(&mut self, id: hir::BodyId) {
1480+
check_const(self.0, id, "array length");
1481+
}
1482+
fn nested_visit_map<'this>(&'this mut self) -> hir::intravisit::NestedVisitorMap<'this, 'v> {
1483+
hir::intravisit::NestedVisitorMap::None
1484+
}
1485+
}
1486+
1487+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
1488+
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
1489+
match it.node {
1490+
hir::ItemConst(_, body_id) => {
1491+
check_const(cx, body_id, "constant");
1492+
},
1493+
hir::ItemTy(ref ty, _) => hir::intravisit::walk_ty(
1494+
&mut UnusedBrokenConstVisitor(cx),
1495+
ty
1496+
),
1497+
_ => {},
1498+
}
1499+
}
1500+
}

src/librustc_lint/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
139139
UnionsWithDropFields,
140140
UnreachablePub,
141141
TypeAliasBounds,
142+
UnusedBrokenConst,
142143
);
143144

144145
add_builtin_with_new!(sess,

src/librustc_mir/interpret/const_eval.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub fn mk_eval_cx<'a, 'tcx>(
5656
Ok(ecx)
5757
}
5858

59-
pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
59+
pub fn eval_promoted<'a, 'mir, 'tcx>(
6060
tcx: TyCtxt<'a, 'tcx, 'tcx>,
6161
cid: GlobalId<'tcx>,
6262
mir: &'mir mir::Mir<'tcx>,
@@ -66,7 +66,7 @@ pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
6666
match res {
6767
Ok(val) => Some(val),
6868
Err(mut err) => {
69-
ecx.report(&mut err, true, None);
69+
ecx.report(&mut err, false, None);
7070
None
7171
}
7272
}

src/librustc_mir/interpret/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub use self::place::{Place, PlaceExtra};
1919
pub use self::memory::{Memory, MemoryKind, HasMemory};
2020

2121
pub use self::const_eval::{
22-
eval_body_with_mir,
22+
eval_promoted,
2323
mk_borrowck_eval_cx,
2424
eval_body,
2525
CompileTimeEvaluator,

src/librustc_mir/monomorphize/collector.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1146,17 +1146,15 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11461146
param_substs: instance.substs,
11471147
}.visit_mir(&mir);
11481148
let param_env = ty::ParamEnv::reveal_all();
1149-
for (i, promoted) in mir.promoted.iter().enumerate() {
1149+
for i in 0..mir.promoted.len() {
11501150
use rustc_data_structures::indexed_vec::Idx;
11511151
let cid = GlobalId {
11521152
instance,
11531153
promoted: Some(Promoted::new(i)),
11541154
};
11551155
match tcx.const_eval(param_env.and(cid)) {
11561156
Ok(val) => collect_const(tcx, val, instance.substs, output),
1157-
Err(err) => {
1158-
err.report(tcx, promoted.span, "promoted");
1159-
}
1157+
Err(_) => {},
11601158
}
11611159
}
11621160
}

src/librustc_mir/transform/const_prop.rs

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

src/librustc_trans/mir/operand.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,14 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
399399
self.mir_constant_to_miri_value(bx, constant)
400400
.and_then(|c| OperandRef::from_const(bx, c, ty))
401401
.unwrap_or_else(|err| {
402-
err.report(bx.tcx(), constant.span, "const operand");
402+
match constant.literal {
403+
mir::Literal::Promoted { .. } => {
404+
// don't report errors inside promoteds, just warnings.
405+
},
406+
mir::Literal::Value { .. } => {
407+
err.report(bx.tcx(), constant.span, "const operand")
408+
},
409+
}
403410
// We've errored, so we don't have to produce working code.
404411
let layout = bx.cx.layout_of(ty);
405412
PlaceRef::new_sized(

src/test/compile-fail/array_const_index-0.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const A: &'static [i32] = &[];
1212
const B: i32 = (&A)[1];
1313
//~^ ERROR constant evaluation error
1414
//~| index out of bounds: the len is 0 but the index is 1
15+
//~| WARN this constant cannot be used
1516

1617
fn main() {
1718
let _ = B;

src/test/compile-fail/array_const_index-1.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const A: [i32; 0] = [];
1212
const B: i32 = A[1];
1313
//~^ ERROR constant evaluation error
1414
//~| index out of bounds: the len is 0 but the index is 1
15+
//~| WARN this constant cannot be used
1516

1617
fn main() {
1718
let _ = B;

src/test/compile-fail/const-err-early.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010

1111
#![deny(const_err)]
1212

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

2525
fn main() {
2626
let _a = A;

src/test/compile-fail/const-err-multi.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ pub const A: i8 = -std::i8::MIN;
1414
//~^ ERROR E0080
1515
//~| ERROR attempt to negate with overflow
1616
//~| ERROR constant evaluation error
17+
//~| ERROR this constant cannot be used
1718
pub const B: i8 = A;
18-
//~^ ERROR E0080
19+
//~^ ERROR const_err
1920
pub const C: u8 = A as u8;
20-
//~^ ERROR E0080
21+
//~^ ERROR const_err
2122
pub const D: i8 = 50 - A;
22-
//~^ ERROR E0080
23+
//~^ ERROR const_err
2324

2425
fn main() {
2526
let _ = (A, B, C, D);

src/test/compile-fail/const-eval-overflow2.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize};
2222
use std::{u8, u16, u32, u64, usize};
2323

2424
const VALS_I8: (i8,) =
25+
//~^ ERROR this constant cannot be used
2526
(
2627
i8::MIN - 1,
27-
//~^ ERROR constant evaluation error
28-
//~| ERROR attempt to subtract with overflow
28+
//~^ ERROR attempt to subtract with overflow
2929
);
3030

3131
const VALS_I16: (i16,) =
32+
//~^ ERROR this constant cannot be used
3233
(
3334
i16::MIN - 1,
34-
//~^ ERROR constant evaluation error
35-
//~| ERROR attempt to subtract with overflow
35+
//~^ ERROR attempt to subtract with overflow
3636
);
3737

3838
const VALS_I32: (i32,) =
39+
//~^ ERROR this constant cannot be used
3940
(
4041
i32::MIN - 1,
41-
//~^ ERROR constant evaluation error
42-
//~| ERROR attempt to subtract with overflow
42+
//~^ ERROR attempt to subtract with overflow
4343
);
4444

4545
const VALS_I64: (i64,) =
46+
//~^ ERROR this constant cannot be used
4647
(
4748
i64::MIN - 1,
48-
//~^ ERROR constant evaluation error
49-
//~| ERROR attempt to subtract with overflow
49+
//~^ ERROR attempt to subtract with overflow
5050
);
5151

5252
const VALS_U8: (u8,) =
53+
//~^ ERROR this constant cannot be used
5354
(
5455
u8::MIN - 1,
55-
//~^ ERROR constant evaluation error
56-
//~| ERROR attempt to subtract with overflow
56+
//~^ ERROR attempt to subtract with overflow
5757
);
5858

5959
const VALS_U16: (u16,) = (
60+
//~^ ERROR this constant cannot be used
6061
u16::MIN - 1,
61-
//~^ ERROR constant evaluation error
62-
//~| ERROR attempt to subtract with overflow
62+
//~^ ERROR attempt to subtract with overflow
6363
);
6464

6565
const VALS_U32: (u32,) = (
66+
//~^ ERROR this constant cannot be used
6667
u32::MIN - 1,
67-
//~^ ERROR constant evaluation error
68-
//~| ERROR attempt to subtract with overflow
68+
//~^ ERROR attempt to subtract with overflow
6969
);
7070

7171
const VALS_U64: (u64,) =
72+
//~^ ERROR this constant cannot be used
7273
(
7374
u64::MIN - 1,
74-
//~^ ERROR constant evaluation error
75-
//~| ERROR attempt to subtract with overflow
75+
//~^ ERROR attempt to subtract with overflow
7676
);
7777

7878
fn main() {

src/test/compile-fail/const-eval-overflow2b.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -22,57 +22,57 @@ use std::{i8, i16, i32, i64, isize};
2222
use std::{u8, u16, u32, u64, usize};
2323

2424
const VALS_I8: (i8,) =
25+
//~^ ERROR this constant cannot be used
2526
(
2627
i8::MAX + 1,
27-
//~^ ERROR constant evaluation error
28-
//~| ERROR attempt to add with overflow
28+
//~^ ERROR attempt to add with overflow
2929
);
3030

3131
const VALS_I16: (i16,) =
32+
//~^ ERROR this constant cannot be used
3233
(
3334
i16::MAX + 1,
34-
//~^ ERROR constant evaluation error
35-
//~| ERROR attempt to add with overflow
35+
//~^ ERROR attempt to add with overflow
3636
);
3737

3838
const VALS_I32: (i32,) =
39+
//~^ ERROR this constant cannot be used
3940
(
4041
i32::MAX + 1,
41-
//~^ ERROR constant evaluation error
42-
//~| ERROR attempt to add with overflow
42+
//~^ ERROR attempt to add with overflow
4343
);
4444

4545
const VALS_I64: (i64,) =
46+
//~^ ERROR this constant cannot be used
4647
(
4748
i64::MAX + 1,
48-
//~^ ERROR constant evaluation error
49-
//~| ERROR attempt to add with overflow
49+
//~^ ERROR attempt to add with overflow
5050
);
5151

5252
const VALS_U8: (u8,) =
53+
//~^ ERROR this constant cannot be used
5354
(
5455
u8::MAX + 1,
55-
//~^ ERROR constant evaluation error
56-
//~| ERROR attempt to add with overflow
56+
//~^ ERROR attempt to add with overflow
5757
);
5858

5959
const VALS_U16: (u16,) = (
60+
//~^ ERROR this constant cannot be used
6061
u16::MAX + 1,
61-
//~^ ERROR constant evaluation error
62-
//~| ERROR attempt to add with overflow
62+
//~^ ERROR attempt to add with overflow
6363
);
6464

6565
const VALS_U32: (u32,) = (
66+
//~^ ERROR this constant cannot be used
6667
u32::MAX + 1,
67-
//~^ ERROR constant evaluation error
68-
//~| ERROR attempt to add with overflow
68+
//~^ ERROR attempt to add with overflow
6969
);
7070

7171
const VALS_U64: (u64,) =
72+
//~^ ERROR this constant cannot be used
7273
(
7374
u64::MAX + 1,
74-
//~^ ERROR constant evaluation error
75-
//~| ERROR attempt to add with overflow
75+
//~^ ERROR attempt to add with overflow
7676
);
7777

7878
fn main() {

0 commit comments

Comments
 (0)