Skip to content

Commit 3acee3b

Browse files
committed
const_err lint all constant expressions
1 parent ee98323 commit 3acee3b

File tree

5 files changed

+44
-27
lines changed

5 files changed

+44
-27
lines changed

src/librustc_passes/consts.rs

+20-25
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use rustc::dep_graph::DepNode;
2828
use rustc::ty::cast::{CastKind};
2929
use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs};
3030
use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id};
31-
use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal};
32-
use rustc_const_eval::ErrKind::ErroneousReferencedConstant;
31+
use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal, MiscCatchAll};
32+
use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp};
3333
use rustc_const_eval::EvalHint::ExprTypeChecked;
3434
use rustc::hir::def::Def;
3535
use rustc::hir::def_id::DefId;
@@ -437,29 +437,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
437437
}
438438
intravisit::walk_expr(self, ex);
439439
}
440-
// Division by zero and overflow checking.
441-
hir::ExprBinary(op, _, _) => {
442-
intravisit::walk_expr(self, ex);
443-
let div_or_rem = op.node == hir::BiDiv || op.node == hir::BiRem;
444-
match node_ty.sty {
445-
ty::TyUint(_) | ty::TyInt(_) if div_or_rem => {
446-
if !self.qualif.intersects(ConstQualif::NOT_CONST) {
447-
match eval_const_expr_partial(
448-
self.tcx, ex, ExprTypeChecked, None) {
449-
Ok(_) => {}
450-
Err(ConstEvalErr { kind: UnimplementedConstVal(_), ..}) |
451-
Err(ConstEvalErr { kind: IndexOpFeatureGated, ..}) => {},
452-
Err(msg) => {
453-
self.tcx.sess.add_lint(CONST_ERR, ex.id,
454-
msg.span,
455-
msg.description().into_owned())
456-
}
457-
}
458-
}
459-
}
460-
_ => {}
461-
}
462-
}
463440
_ => intravisit::walk_expr(self, ex)
464441
}
465442

@@ -505,6 +482,24 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckCrateVisitor<'a, 'tcx> {
505482
}
506483
None => {}
507484
}
485+
486+
if self.mode == Mode::Var && !self.qualif.intersects(ConstQualif::NOT_CONST) {
487+
match eval_const_expr_partial(self.tcx, ex, ExprTypeChecked, None) {
488+
Ok(_) => {}
489+
Err(ConstEvalErr { kind: UnimplementedConstVal(_), ..}) |
490+
Err(ConstEvalErr { kind: MiscCatchAll, ..}) |
491+
Err(ConstEvalErr { kind: MiscBinaryOp, ..}) |
492+
Err(ConstEvalErr { kind: ErroneousReferencedConstant(_), ..}) |
493+
Err(ConstEvalErr { kind: IndexOpFeatureGated, ..}) => {},
494+
Err(msg) => {
495+
self.qualif = self.qualif | ConstQualif::NOT_CONST;
496+
self.tcx.sess.add_lint(CONST_ERR, ex.id,
497+
msg.span,
498+
msg.description().into_owned())
499+
}
500+
}
501+
}
502+
508503
self.tcx.const_qualif_map.borrow_mut().insert(ex.id, self.qualif);
509504
// Don't propagate certain flags.
510505
self.qualif = outer | (self.qualif - ConstQualif::HAS_STATIC_BORROWS);

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempted to subtract with overfl
1818
pub const E: u8 = [5u8][1]; //~ ERROR index out of bounds
1919

2020
fn main() {
21-
let _e = [6u8][1];
21+
let _e = [6u8][1]; //~ ERROR: array index out of bounds
2222
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ fn main() {
2121
//~^ WARN attempted to negate with overflow
2222
let b = 200u8 + 200u8 + 200u8;
2323
//~^ WARN attempted to add with overflow
24-
//~^^ WARN attempted to add with overflow
2524
let c = 200u8 * 4;
2625
//~^ WARN attempted to multiply with overflow
2726
let d = 42u8 - (42u8 + 1);

src/test/compile-fail/lint-exceeding-bitshifts.rs

+21
Original file line numberDiff line numberDiff line change
@@ -16,58 +16,79 @@
1616
fn main() {
1717
let n = 1u8 << 7;
1818
let n = 1u8 << 8; //~ ERROR: bitshift exceeds the type's number of bits
19+
//~^ WARN: attempted to shift left with overflow
1920
let n = 1u16 << 15;
2021
let n = 1u16 << 16; //~ ERROR: bitshift exceeds the type's number of bits
22+
//~^ WARN: attempted to shift left with overflow
2123
let n = 1u32 << 31;
2224
let n = 1u32 << 32; //~ ERROR: bitshift exceeds the type's number of bits
25+
//~^ WARN: attempted to shift left with overflow
2326
let n = 1u64 << 63;
2427
let n = 1u64 << 64; //~ ERROR: bitshift exceeds the type's number of bits
28+
//~^ WARN: attempted to shift left with overflow
2529
let n = 1i8 << 7;
2630
let n = 1i8 << 8; //~ ERROR: bitshift exceeds the type's number of bits
31+
//~^ WARN: attempted to shift left with overflow
2732
let n = 1i16 << 15;
2833
let n = 1i16 << 16; //~ ERROR: bitshift exceeds the type's number of bits
34+
//~^ WARN: attempted to shift left with overflow
2935
let n = 1i32 << 31;
3036
let n = 1i32 << 32; //~ ERROR: bitshift exceeds the type's number of bits
37+
//~^ WARN: attempted to shift left with overflow
3138
let n = 1i64 << 63;
3239
let n = 1i64 << 64; //~ ERROR: bitshift exceeds the type's number of bits
40+
//~^ WARN: attempted to shift left with overflow
3341

3442
let n = 1u8 >> 7;
3543
let n = 1u8 >> 8; //~ ERROR: bitshift exceeds the type's number of bits
44+
//~^ WARN: attempted to shift right with overflow
3645
let n = 1u16 >> 15;
3746
let n = 1u16 >> 16; //~ ERROR: bitshift exceeds the type's number of bits
47+
//~^ WARN: attempted to shift right with overflow
3848
let n = 1u32 >> 31;
3949
let n = 1u32 >> 32; //~ ERROR: bitshift exceeds the type's number of bits
50+
//~^ WARN: attempted to shift right with overflow
4051
let n = 1u64 >> 63;
4152
let n = 1u64 >> 64; //~ ERROR: bitshift exceeds the type's number of bits
53+
//~^ WARN: attempted to shift right with overflow
4254
let n = 1i8 >> 7;
4355
let n = 1i8 >> 8; //~ ERROR: bitshift exceeds the type's number of bits
56+
//~^ WARN: attempted to shift right with overflow
4457
let n = 1i16 >> 15;
4558
let n = 1i16 >> 16; //~ ERROR: bitshift exceeds the type's number of bits
59+
//~^ WARN: attempted to shift right with overflow
4660
let n = 1i32 >> 31;
4761
let n = 1i32 >> 32; //~ ERROR: bitshift exceeds the type's number of bits
62+
//~^ WARN: attempted to shift right with overflow
4863
let n = 1i64 >> 63;
4964
let n = 1i64 >> 64; //~ ERROR: bitshift exceeds the type's number of bits
65+
//~^ WARN: attempted to shift right with overflow
5066

5167
let n = 1u8;
5268
let n = n << 7;
5369
let n = n << 8; //~ ERROR: bitshift exceeds the type's number of bits
5470

5571
let n = 1u8 << -8; //~ ERROR: bitshift exceeds the type's number of bits
72+
//~^ WARN: attempted to shift by a negative amount
5673

5774
let n = 1u8 << (4+3);
5875
let n = 1u8 << (4+4); //~ ERROR: bitshift exceeds the type's number of bits
76+
//~^ WARN: attempted to shift left with overflow
5977

6078
#[cfg(target_pointer_width = "32")]
6179
const BITS: usize = 32;
6280
#[cfg(target_pointer_width = "64")]
6381
const BITS: usize = 64;
6482

6583
let n = 1_isize << BITS; //~ ERROR: bitshift exceeds the type's number of bits
84+
//~^ WARN: attempted to shift left with overflow
6685
let n = 1_usize << BITS; //~ ERROR: bitshift exceeds the type's number of bits
86+
//~^ WARN: attempted to shift left with overflow
6787

6888

6989
let n = 1i8<<(1isize+-1);
7090

7191
let n = 1i64 >> [63][0];
7292
let n = 1i64 >> [64][0]; //~ ERROR: bitshift exceeds the type's number of bits
93+
//~^ WARN: attempted to shift right with overflow
7394
}

src/test/compile-fail/lint-type-overflow2.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
//
1111

1212
#![deny(overflowing_literals)]
13+
#![deny(const_err)]
1314

1415
#[allow(unused_variables)]
1516
fn main() {
1617
let x2: i8 = --128; //~ error: literal out of range for i8
18+
//~^ error: attempted to negate with overflow
1719

1820
let x = -3.40282348e+38_f32; //~ error: literal out of range for f32
1921
let x = 3.40282348e+38_f32; //~ error: literal out of range for f32

0 commit comments

Comments
 (0)