Skip to content

Commit 5c70619

Browse files
committed
Rewrite error reporting as requested
1 parent 19c4771 commit 5c70619

File tree

2 files changed

+82
-62
lines changed

2 files changed

+82
-62
lines changed

src/librustc_lint/types.rs

+69-45
Original file line numberDiff line numberDiff line change
@@ -152,29 +152,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
152152
// avoiding use of -min to prevent overflow/panic
153153
if (negative && v > max + 1) || (!negative && v > max) {
154154
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
155-
let bits = int_ty_bits(t, cx.sess().target.isize_ty);
156-
let actually =
157-
((v << (128 - bits)) as i128) >> (128 - bits);
158-
let mut err = cx.struct_span_lint(
159-
OVERFLOWING_LITERALS,
160-
e.span,
161-
&format!("literal out of range for {:?}", t),
162-
);
163-
err.note(&format!(
164-
"the literal `{}` (decimal `{}`) does not fit into \
165-
an `{:?}` and will become `{}{:?}`.",
166-
repr_str, v, t, actually, t
167-
));
168-
let sugg_ty = get_type_suggestion(
169-
&cx.tables.node_id_to_type(e.hir_id).sty,
155+
report_bin_hex_error(
156+
cx,
157+
e,
158+
ty::TyInt(t),
159+
repr_str,
170160
v,
171161
negative,
172162
);
173-
if !sugg_ty.is_empty() {
174-
err.help(&sugg_ty);
175-
}
176-
177-
err.emit();
178163
return;
179164
}
180165
cx.span_lint(
@@ -219,28 +204,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
219204
}
220205
}
221206
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
222-
let bits = uint_ty_bits(t, cx.sess().target.usize_ty);
223-
let actually = (lit_val << (128 - bits)) >> (128 - bits);
224-
let mut err = cx.struct_span_lint(
225-
OVERFLOWING_LITERALS,
226-
e.span,
227-
&format!("literal out of range for {:?}", t),
228-
);
229-
err.note(&format!(
230-
"the literal `{}` (decimal `{}`) does not fit into \
231-
an `{:?}` and will become `{}{:?}`.",
232-
repr_str, lit_val, t, actually, t
233-
));
234-
let sugg_ty = get_type_suggestion(
235-
&cx.tables.node_id_to_type(e.hir_id).sty,
207+
report_bin_hex_error(
208+
cx,
209+
e,
210+
ty::TyUint(t),
211+
repr_str,
236212
lit_val,
237213
false,
238214
);
239-
if !sugg_ty.is_empty() {
240-
err.help(&sugg_ty);
241-
}
242-
243-
err.emit();
244215
return;
245216
}
246217
cx.span_lint(
@@ -414,7 +385,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
414385
// - `uX` => `uY`
415386
//
416387
// No suggestion for: `isize`, `usize`.
417-
fn get_type_suggestion<'a>(t: &ty::TypeVariants, val: u128, negative: bool) -> String {
388+
fn get_type_suggestion<'a>(
389+
t: &ty::TypeVariants,
390+
val: u128,
391+
negative: bool,
392+
) -> Option<String> {
418393
use syntax::ast::IntTy::*;
419394
use syntax::ast::UintTy::*;
420395
macro_rules! find_fit {
@@ -425,14 +400,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
425400
match $ty {
426401
$($type => {
427402
$(if !negative && val <= uint_ty_range($utypes).1 {
428-
return format!("Consider using `{:?}`", $utypes)
403+
return Some(format!("{:?}", $utypes))
429404
})*
430405
$(if val <= int_ty_range($itypes).1 as u128 + _neg {
431-
return format!("Consider using `{:?}`", $itypes)
406+
return Some(format!("{:?}", $itypes))
432407
})*
433-
String::new()
408+
None
434409
},)*
435-
_ => String::new()
410+
_ => None
436411
}
437412
}
438413
}
@@ -450,8 +425,57 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
450425
U32 => [U32, U64, U128] => [],
451426
U64 => [U64, U128] => [],
452427
U128 => [U128] => []),
453-
_ => String::new(),
428+
_ => None,
429+
}
430+
}
431+
432+
fn report_bin_hex_error(
433+
cx: &LateContext,
434+
expr: &hir::Expr,
435+
ty: ty::TypeVariants,
436+
repr_str: String,
437+
val: u128,
438+
negative: bool,
439+
) {
440+
let (t, actually) = match ty {
441+
ty::TyInt(t) => {
442+
let bits = int_ty_bits(t, cx.sess().target.isize_ty);
443+
let actually = (val << (128 - bits)) as i128 >> (128 - bits);
444+
(format!("{:?}", t), actually.to_string())
445+
}
446+
ty::TyUint(t) => {
447+
let bits = uint_ty_bits(t, cx.sess().target.usize_ty);
448+
let actually = (val << (128 - bits)) >> (128 - bits);
449+
(format!("{:?}", t), actually.to_string())
450+
}
451+
_ => bug!(),
452+
};
453+
let mut err = cx.struct_span_lint(
454+
OVERFLOWING_LITERALS,
455+
expr.span,
456+
&format!("literal out of range for {}", t),
457+
);
458+
err.note(&format!(
459+
"the literal `{}` (decimal `{}`) does not fit into \
460+
an `{}` and will become `{}{}`",
461+
repr_str, val, t, actually, t
462+
));
463+
if let Some(sugg_ty) =
464+
get_type_suggestion(&cx.tables.node_id_to_type(expr.hir_id).sty, val, negative)
465+
{
466+
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
467+
let (sans_suffix, _) = repr_str.split_at(pos);
468+
err.span_suggestion(
469+
expr.span,
470+
&format!("consider using `{}` instead", sugg_ty),
471+
format!("{}{}", sans_suffix, sugg_ty),
472+
);
473+
} else {
474+
err.help(&format!("consider using `{}` instead", sugg_ty));
475+
}
454476
}
477+
478+
err.emit();
455479
}
456480
}
457481
}

src/test/ui/lint/type-overflow.stderr

+13-17
Original file line numberDiff line numberDiff line change
@@ -10,61 +10,57 @@ warning: literal out of range for i8
1010
--> $DIR/type-overflow.rs:21:16
1111
|
1212
21 | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8
13-
| ^^^^^^^^^^^^^
13+
| ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8`
1414
|
15-
= note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`.
16-
= help: Consider using `u8`
15+
= note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`
1716

1817
warning: literal out of range for i64
1918
--> $DIR/type-overflow.rs:23:16
2019
|
2120
23 | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64
22-
| ^^^^^^^^^^^^^^^^^^^^^^^^
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64`
2322
|
24-
= note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`.
25-
= help: Consider using `u64`
23+
= note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`
2624

2725
warning: literal out of range for u32
2826
--> $DIR/type-overflow.rs:25:16
2927
|
3028
25 | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32
31-
| ^^^^^^^^^^^^^^^^
29+
| ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64`
3230
|
33-
= note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`.
34-
= help: Consider using `u64`
31+
= note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`
3532

3633
warning: literal out of range for i128
3734
--> $DIR/type-overflow.rs:27:22
3835
|
3936
27 | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
4037
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4138
|
42-
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128`.
43-
= help: Consider using `u128`
39+
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128`
40+
= help: consider using `u128` instead
4441

4542
warning: literal out of range for i32
4643
--> $DIR/type-overflow.rs:30:16
4744
|
4845
30 | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32
4946
| ^^^^^^^^^^^^^^^^^^^^^
5047
|
51-
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32`.
52-
= help: Consider using `i128`
48+
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32`
49+
= help: consider using `i128` instead
5350

5451
warning: literal out of range for isize
5552
--> $DIR/type-overflow.rs:32:23
5653
|
5754
32 | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize
5855
| ^^^^^^^^^^^^^^^^^^^^^
5956
|
60-
= note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize`.
57+
= note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize`
6158

6259
warning: literal out of range for i8
6360
--> $DIR/type-overflow.rs:34:17
6461
|
6562
34 | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8
66-
| ^^^^^^^^^^^^^
63+
| ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16`
6764
|
68-
= note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`.
69-
= help: Consider using `i16`
65+
= note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`
7066

0 commit comments

Comments
 (0)