From d00ca112020680928aadb221aad13bd52634823b Mon Sep 17 00:00:00 2001 From: Camelid Date: Sat, 12 Dec 2020 13:46:25 -0800 Subject: [PATCH 01/17] Add 'consider using' message to overflowing_literals Ironically, the overflowing_literals handler for binary or hex already had this message! You would think it would be the other way around :) --- compiler/rustc_lint/src/types.rs | 29 +++++++++++-------- .../ui/enum/enum-discrim-too-small2.stderr | 4 +++ src/test/ui/issues/issue-79744.rs | 13 +++++++++ src/test/ui/issues/issue-79744.stderr | 12 ++++++++ src/test/ui/lint/lint-type-limits2.stderr | 1 + src/test/ui/lint/lint-type-limits3.stderr | 1 + src/test/ui/lint/lint-type-overflow.stderr | 16 ++++++++++ src/test/ui/lint/lint-type-overflow2.stderr | 1 + src/test/ui/lint/type-overflow.stderr | 1 + 9 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/issues/issue-79744.rs create mode 100644 src/test/ui/issues/issue-79744.stderr diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 9ad9d53cd0db3..d9f4da23d2f86 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -331,18 +331,23 @@ fn lint_int_literal<'tcx>( } cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - lint.build(&format!("literal out of range for `{}`", t.name_str())) - .note(&format!( - "the literal `{}` does not fit into the type `{}` whose range is `{}..={}`", - cx.sess() - .source_map() - .span_to_snippet(lit.span) - .expect("must get snippet from literal"), - t.name_str(), - min, - max, - )) - .emit(); + let mut err = lint.build(&format!("literal out of range for `{}`", t.name_str())); + err.note(&format!( + "the literal `{}` does not fit into the type `{}` whose range is `{}..={}`", + cx.sess() + .source_map() + .span_to_snippet(lit.span) + .expect("must get snippet from literal"), + t.name_str(), + min, + max, + )); + if let Some(sugg_ty) = + get_type_suggestion(&cx.typeck_results().node_type(e.hir_id), v, negative) + { + err.help(&format!("consider using `{}` instead", sugg_ty)); + } + err.emit(); }); } } diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr index fadf6ab86b43e..f0deb26e96db4 100644 --- a/src/test/ui/enum/enum-discrim-too-small2.stderr +++ b/src/test/ui/enum/enum-discrim-too-small2.stderr @@ -10,6 +10,7 @@ note: the lint level is defined here LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: literal out of range for `i16` --> $DIR/enum-discrim-too-small2.rs:15:12 @@ -18,6 +19,7 @@ LL | Ci16 = 55555, | ^^^^^ | = note: the literal `55555` does not fit into the type `i16` whose range is `-32768..=32767` + = help: consider using `u16` instead error: literal out of range for `i32` --> $DIR/enum-discrim-too-small2.rs:22:12 @@ -26,6 +28,7 @@ LL | Ci32 = 3_000_000_000, | ^^^^^^^^^^^^^ | = note: the literal `3_000_000_000` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using `u32` instead error: literal out of range for `i64` --> $DIR/enum-discrim-too-small2.rs:29:12 @@ -34,6 +37,7 @@ LL | Ci64 = 9223372036854775809, | ^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775809` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` + = help: consider using `u64` instead error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-79744.rs b/src/test/ui/issues/issue-79744.rs new file mode 100644 index 0000000000000..49051f2cee655 --- /dev/null +++ b/src/test/ui/issues/issue-79744.rs @@ -0,0 +1,13 @@ +fn main() { + let elem = 6i8; + let e2 = 230; + //~^ ERROR literal out of range for `i8` + //~| HELP consider using `u8` instead + + let mut vec = Vec::new(); + + vec.push(e2); + vec.push(elem); + + println!("{:?}", vec); +} diff --git a/src/test/ui/issues/issue-79744.stderr b/src/test/ui/issues/issue-79744.stderr new file mode 100644 index 0000000000000..b35700cd47268 --- /dev/null +++ b/src/test/ui/issues/issue-79744.stderr @@ -0,0 +1,12 @@ +error: literal out of range for `i8` + --> $DIR/issue-79744.rs:3:14 + | +LL | let e2 = 230; + | ^^^ + | + = note: `#[deny(overflowing_literals)]` on by default + = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead + +error: aborting due to previous error + diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr index e8746ce980a96..357fde7151ca2 100644 --- a/src/test/ui/lint/lint-type-limits2.stderr +++ b/src/test/ui/lint/lint-type-limits2.stderr @@ -18,6 +18,7 @@ note: the lint level is defined here LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr index 0e8a64510695a..c8558cfc2143c 100644 --- a/src/test/ui/lint/lint-type-limits3.stderr +++ b/src/test/ui/lint/lint-type-limits3.stderr @@ -18,6 +18,7 @@ note: the lint level is defined here LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/lint/lint-type-overflow.stderr b/src/test/ui/lint/lint-type-overflow.stderr index 7715c0d3a4db9..f0a8f507d5723 100644 --- a/src/test/ui/lint/lint-type-overflow.stderr +++ b/src/test/ui/lint/lint-type-overflow.stderr @@ -26,6 +26,7 @@ LL | let x1: i8 = 128; | ^^^ | = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:18:19 @@ -34,6 +35,7 @@ LL | let x3: i8 = -129; | ^^^ | = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `i16` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:19:19 @@ -42,6 +44,7 @@ LL | let x3: i8 = -(129); | ^^^^^ | = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `i16` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:20:20 @@ -50,6 +53,7 @@ LL | let x3: i8 = -{129}; | ^^^ | = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:22:10 @@ -58,6 +62,7 @@ LL | test(1000); | ^^^^ | = note: the literal `1000` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `i16` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:24:13 @@ -66,6 +71,7 @@ LL | let x = 128_i8; | ^^^^^^ | = note: the literal `128_i8` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:28:14 @@ -74,6 +80,7 @@ LL | let x = -129_i8; | ^^^^^^ | = note: the literal `129_i8` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `i16` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:32:18 @@ -82,6 +89,7 @@ LL | let x: i32 = 2147483648; | ^^^^^^^^^^ | = note: the literal `2147483648` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using `u32` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:33:13 @@ -90,6 +98,7 @@ LL | let x = 2147483648_i32; | ^^^^^^^^^^^^^^ | = note: the literal `2147483648_i32` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using `u32` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:36:19 @@ -98,6 +107,7 @@ LL | let x: i32 = -2147483649; | ^^^^^^^^^^ | = note: the literal `2147483649` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using `i64` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:37:14 @@ -106,6 +116,7 @@ LL | let x = -2147483649_i32; | ^^^^^^^^^^^^^^ | = note: the literal `2147483649_i32` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using `i64` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:38:13 @@ -114,6 +125,7 @@ LL | let x = 2147483648; | ^^^^^^^^^^ | = note: the literal `2147483648` does not fit into the type `i32` whose range is `-2147483648..=2147483647` + = help: consider using `u32` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:40:13 @@ -122,6 +134,7 @@ LL | let x = 9223372036854775808_i64; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775808_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` + = help: consider using `u64` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:42:13 @@ -130,6 +143,7 @@ LL | let x = 18446744073709551615_i64; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `18446744073709551615_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` + = help: consider using `u64` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:43:19 @@ -138,6 +152,7 @@ LL | let x: i64 = -9223372036854775809; | ^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775809` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` + = help: consider using `i128` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:44:14 @@ -146,6 +161,7 @@ LL | let x = -9223372036854775809_i64; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775809_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` + = help: consider using `i128` instead error: aborting due to 18 previous errors diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr index 0f16229a29178..ab28c4aaf477b 100644 --- a/src/test/ui/lint/lint-type-overflow2.stderr +++ b/src/test/ui/lint/lint-type-overflow2.stderr @@ -10,6 +10,7 @@ note: the lint level is defined here LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead error: literal out of range for `f32` --> $DIR/lint-type-overflow2.rs:9:14 diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 6ba8b43954d3e..dafce414d2fdf 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -10,6 +10,7 @@ note: the lint level is defined here LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using `u8` instead warning: literal out of range for i8 --> $DIR/type-overflow.rs:10:16 From a9b16c6d714dcec62b9e92f1ad7963b999c163c9 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sat, 13 Feb 2021 21:42:32 -0800 Subject: [PATCH 02/17] Improve error and help messages --- compiler/rustc_lint/src/types.rs | 8 ++--- .../ui/enum/enum-discrim-too-small2.stderr | 8 ++--- src/test/ui/issues/issue-79744.rs | 2 +- src/test/ui/issues/issue-79744.stderr | 2 +- src/test/ui/lint/lint-type-limits2.stderr | 2 +- src/test/ui/lint/lint-type-limits3.stderr | 2 +- src/test/ui/lint/lint-type-overflow.stderr | 32 +++++++++---------- src/test/ui/lint/lint-type-overflow2.stderr | 2 +- src/test/ui/lint/type-overflow.rs | 12 +++---- src/test/ui/lint/type-overflow.stderr | 26 +++++++-------- 10 files changed, 48 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index d9f4da23d2f86..b64f18d24832f 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -225,7 +225,7 @@ fn report_bin_hex_error( (t.name_str(), actually.to_string()) } }; - let mut err = lint.build(&format!("literal out of range for {}", t)); + let mut err = lint.build(&format!("literal out of range for `{}`", t)); err.note(&format!( "the literal `{}` (decimal `{}`) does not fit into \ the type `{}` and will become `{}{}`", @@ -238,12 +238,12 @@ fn report_bin_hex_error( let (sans_suffix, _) = repr_str.split_at(pos); err.span_suggestion( expr.span, - &format!("consider using `{}` instead", sugg_ty), + &format!("consider using the type `{}` instead", sugg_ty), format!("{}{}", sans_suffix, sugg_ty), Applicability::MachineApplicable, ); } else { - err.help(&format!("consider using `{}` instead", sugg_ty)); + err.help(&format!("consider using the type `{}` instead", sugg_ty)); } } err.emit(); @@ -345,7 +345,7 @@ fn lint_int_literal<'tcx>( if let Some(sugg_ty) = get_type_suggestion(&cx.typeck_results().node_type(e.hir_id), v, negative) { - err.help(&format!("consider using `{}` instead", sugg_ty)); + err.help(&format!("consider using the type `{}` instead", sugg_ty)); } err.emit(); }); diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr index f0deb26e96db4..43830679535de 100644 --- a/src/test/ui/enum/enum-discrim-too-small2.stderr +++ b/src/test/ui/enum/enum-discrim-too-small2.stderr @@ -10,7 +10,7 @@ note: the lint level is defined here LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: literal out of range for `i16` --> $DIR/enum-discrim-too-small2.rs:15:12 @@ -19,7 +19,7 @@ LL | Ci16 = 55555, | ^^^^^ | = note: the literal `55555` does not fit into the type `i16` whose range is `-32768..=32767` - = help: consider using `u16` instead + = help: consider using the type `u16` instead error: literal out of range for `i32` --> $DIR/enum-discrim-too-small2.rs:22:12 @@ -28,7 +28,7 @@ LL | Ci32 = 3_000_000_000, | ^^^^^^^^^^^^^ | = note: the literal `3_000_000_000` does not fit into the type `i32` whose range is `-2147483648..=2147483647` - = help: consider using `u32` instead + = help: consider using the type `u32` instead error: literal out of range for `i64` --> $DIR/enum-discrim-too-small2.rs:29:12 @@ -37,7 +37,7 @@ LL | Ci64 = 9223372036854775809, | ^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775809` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` - = help: consider using `u64` instead + = help: consider using the type `u64` instead error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-79744.rs b/src/test/ui/issues/issue-79744.rs index 49051f2cee655..e9725a027d379 100644 --- a/src/test/ui/issues/issue-79744.rs +++ b/src/test/ui/issues/issue-79744.rs @@ -2,7 +2,7 @@ fn main() { let elem = 6i8; let e2 = 230; //~^ ERROR literal out of range for `i8` - //~| HELP consider using `u8` instead + //~| HELP consider using the type `u8` instead let mut vec = Vec::new(); diff --git a/src/test/ui/issues/issue-79744.stderr b/src/test/ui/issues/issue-79744.stderr index b35700cd47268..6f6dd44d2369e 100644 --- a/src/test/ui/issues/issue-79744.stderr +++ b/src/test/ui/issues/issue-79744.stderr @@ -6,7 +6,7 @@ LL | let e2 = 230; | = note: `#[deny(overflowing_literals)]` on by default = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: aborting due to previous error diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr index 357fde7151ca2..3562cb440a661 100644 --- a/src/test/ui/lint/lint-type-limits2.stderr +++ b/src/test/ui/lint/lint-type-limits2.stderr @@ -18,7 +18,7 @@ note: the lint level is defined here LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr index c8558cfc2143c..823d1a4c76fd6 100644 --- a/src/test/ui/lint/lint-type-limits3.stderr +++ b/src/test/ui/lint/lint-type-limits3.stderr @@ -18,7 +18,7 @@ note: the lint level is defined here LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/lint/lint-type-overflow.stderr b/src/test/ui/lint/lint-type-overflow.stderr index f0a8f507d5723..1bb1ec5477609 100644 --- a/src/test/ui/lint/lint-type-overflow.stderr +++ b/src/test/ui/lint/lint-type-overflow.stderr @@ -26,7 +26,7 @@ LL | let x1: i8 = 128; | ^^^ | = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:18:19 @@ -35,7 +35,7 @@ LL | let x3: i8 = -129; | ^^^ | = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `i16` instead + = help: consider using the type `i16` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:19:19 @@ -44,7 +44,7 @@ LL | let x3: i8 = -(129); | ^^^^^ | = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `i16` instead + = help: consider using the type `i16` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:20:20 @@ -53,7 +53,7 @@ LL | let x3: i8 = -{129}; | ^^^ | = note: the literal `129` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:22:10 @@ -62,7 +62,7 @@ LL | test(1000); | ^^^^ | = note: the literal `1000` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `i16` instead + = help: consider using the type `i16` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:24:13 @@ -71,7 +71,7 @@ LL | let x = 128_i8; | ^^^^^^ | = note: the literal `128_i8` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: literal out of range for `i8` --> $DIR/lint-type-overflow.rs:28:14 @@ -80,7 +80,7 @@ LL | let x = -129_i8; | ^^^^^^ | = note: the literal `129_i8` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `i16` instead + = help: consider using the type `i16` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:32:18 @@ -89,7 +89,7 @@ LL | let x: i32 = 2147483648; | ^^^^^^^^^^ | = note: the literal `2147483648` does not fit into the type `i32` whose range is `-2147483648..=2147483647` - = help: consider using `u32` instead + = help: consider using the type `u32` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:33:13 @@ -98,7 +98,7 @@ LL | let x = 2147483648_i32; | ^^^^^^^^^^^^^^ | = note: the literal `2147483648_i32` does not fit into the type `i32` whose range is `-2147483648..=2147483647` - = help: consider using `u32` instead + = help: consider using the type `u32` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:36:19 @@ -107,7 +107,7 @@ LL | let x: i32 = -2147483649; | ^^^^^^^^^^ | = note: the literal `2147483649` does not fit into the type `i32` whose range is `-2147483648..=2147483647` - = help: consider using `i64` instead + = help: consider using the type `i64` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:37:14 @@ -116,7 +116,7 @@ LL | let x = -2147483649_i32; | ^^^^^^^^^^^^^^ | = note: the literal `2147483649_i32` does not fit into the type `i32` whose range is `-2147483648..=2147483647` - = help: consider using `i64` instead + = help: consider using the type `i64` instead error: literal out of range for `i32` --> $DIR/lint-type-overflow.rs:38:13 @@ -125,7 +125,7 @@ LL | let x = 2147483648; | ^^^^^^^^^^ | = note: the literal `2147483648` does not fit into the type `i32` whose range is `-2147483648..=2147483647` - = help: consider using `u32` instead + = help: consider using the type `u32` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:40:13 @@ -134,7 +134,7 @@ LL | let x = 9223372036854775808_i64; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775808_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` - = help: consider using `u64` instead + = help: consider using the type `u64` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:42:13 @@ -143,7 +143,7 @@ LL | let x = 18446744073709551615_i64; | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `18446744073709551615_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` - = help: consider using `u64` instead + = help: consider using the type `u64` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:43:19 @@ -152,7 +152,7 @@ LL | let x: i64 = -9223372036854775809; | ^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775809` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` - = help: consider using `i128` instead + = help: consider using the type `i128` instead error: literal out of range for `i64` --> $DIR/lint-type-overflow.rs:44:14 @@ -161,7 +161,7 @@ LL | let x = -9223372036854775809_i64; | ^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `9223372036854775809_i64` does not fit into the type `i64` whose range is `-9223372036854775808..=9223372036854775807` - = help: consider using `i128` instead + = help: consider using the type `i128` instead error: aborting due to 18 previous errors diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr index ab28c4aaf477b..3d40cdf96efdb 100644 --- a/src/test/ui/lint/lint-type-overflow2.stderr +++ b/src/test/ui/lint/lint-type-overflow2.stderr @@ -10,7 +10,7 @@ note: the lint level is defined here LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead error: literal out of range for `f32` --> $DIR/lint-type-overflow2.rs:9:14 diff --git a/src/test/ui/lint/type-overflow.rs b/src/test/ui/lint/type-overflow.rs index e40321e56bf15..6234b794c1f48 100644 --- a/src/test/ui/lint/type-overflow.rs +++ b/src/test/ui/lint/type-overflow.rs @@ -7,16 +7,16 @@ fn main() { let ok = 0b1000_0001; // should be ok -> i32 let ok = 0b0111_1111i8; // should be ok -> 127i8 - let fail = 0b1000_0001i8; //~WARNING literal out of range for i8 + let fail = 0b1000_0001i8; //~WARNING literal out of range for `i8` - let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64 + let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for `i64` - let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32 + let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for `u32` let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; - //~^ WARNING literal out of range for i128 + //~^ WARNING literal out of range for `i128` - let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32 + let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for `i32` - let fail = -0b1111_1111i8; //~WARNING literal out of range for i8 + let fail = -0b1111_1111i8; //~WARNING literal out of range for `i8` } diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index dafce414d2fdf..521223e325650 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -10,55 +10,55 @@ note: the lint level is defined here LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using `u8` instead + = help: consider using the type `u8` instead -warning: literal out of range for i8 +warning: literal out of range for `i8` --> $DIR/type-overflow.rs:10:16 | LL | let fail = 0b1000_0001i8; - | ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8` + | ^^^^^^^^^^^^^ help: consider using the type `u8` instead: `0b1000_0001u8` | = note: the literal `0b1000_0001i8` (decimal `129`) does not fit into the type `i8` and will become `-127i8` -warning: literal out of range for i64 +warning: literal out of range for `i64` --> $DIR/type-overflow.rs:12:16 | LL | let fail = 0x8000_0000_0000_0000i64; - | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64` + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x8000_0000_0000_0000u64` | = note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into the type `i64` and will become `-9223372036854775808i64` -warning: literal out of range for u32 +warning: literal out of range for `u32` --> $DIR/type-overflow.rs:14:16 | LL | let fail = 0x1_FFFF_FFFFu32; - | ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64` + | ^^^^^^^^^^^^^^^^ help: consider using the type `u64` instead: `0x1_FFFF_FFFFu64` | = note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into the type `u32` and will become `4294967295u32` -warning: literal out of range for i128 +warning: literal out of range for `i128` --> $DIR/type-overflow.rs:16:22 | LL | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into the type `i128` and will become `-170141183460469231731687303715884105728i128` - = help: consider using `u128` instead + = help: consider using the type `u128` instead -warning: literal out of range for i32 +warning: literal out of range for `i32` --> $DIR/type-overflow.rs:19:16 | LL | let fail = 0x8FFF_FFFF_FFFF_FFFE; | ^^^^^^^^^^^^^^^^^^^^^ | = note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into the type `i32` and will become `-2i32` - = help: consider using `i128` instead + = help: consider using the type `i128` instead -warning: literal out of range for i8 +warning: literal out of range for `i8` --> $DIR/type-overflow.rs:21:17 | LL | let fail = -0b1111_1111i8; - | ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16` + | ^^^^^^^^^^^^^ help: consider using the type `i16` instead: `0b1111_1111i16` | = note: the literal `0b1111_1111i8` (decimal `255`) does not fit into the type `i8` and will become `-1i8` From fa3621b468263828b5e1a1b1563e0b9cb7209e96 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sun, 14 Feb 2021 18:27:08 +0200 Subject: [PATCH 03/17] Don't fail to remove files if they are missing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the backend we may want to remove certain temporary files, but in certain other situations these files might not be produced in the first place. We don't exactly care about that, and the intent is really that these files are gone after a certain point in the backend. Here we unify the backend file removing calls to use `ensure_removed` which will attempt to delete a file, but will not fail if it does not exist (anymore). The tradeoff to this approach is, of course, that we may miss instances were we are attempting to remove files at wrong paths due to some bug – compilation would silently succeed but the temporary files would remain there somewhere. --- compiler/rustc_codegen_llvm/src/back/write.rs | 5 ++--- compiler/rustc_codegen_ssa/src/back/link.rs | 11 +++++++---- compiler/rustc_codegen_ssa/src/back/write.rs | 14 +++++++------- .../debuginfo-emit-llvm-ir-and-split-debuginfo.rs | 7 +++++++ 4 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 8b737c9a2e557..5f8a11ab94e66 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -11,6 +11,7 @@ use crate::llvm_util; use crate::type_::Type; use crate::LlvmCodegenBackend; use crate::ModuleLlvm; +use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{ BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig, TargetMachineFactoryFn, @@ -879,9 +880,7 @@ pub(crate) unsafe fn codegen( if !config.emit_bc { debug!("removing_bitcode {:?}", bc_out); - if let Err(e) = fs::remove_file(&bc_out) { - diag_handler.err(&format!("failed to remove bitcode: {}", e)); - } + ensure_removed(diag_handler, &bc_out); } } diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 6c58417590e69..972b9bbfe1caf 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1,5 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::temp_dir::MaybeTempDir; +use rustc_errors::Handler; use rustc_fs_util::fix_windows_verbatim_for_gcc; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::cstore::{EncodedMetadata, LibSource}; @@ -34,9 +35,11 @@ use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; use std::{ascii, char, env, fmt, fs, io, mem, str}; -pub fn remove(sess: &Session, path: &Path) { +pub fn ensure_removed(diag_handler: &Handler, path: &Path) { if let Err(e) = fs::remove_file(path) { - sess.err(&format!("failed to remove {}: {}", path.display(), e)); + if e.kind() != io::ErrorKind::NotFound { + diag_handler.err(&format!("failed to remove {}: {}", path.display(), e)); + } } } @@ -112,11 +115,11 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>( if !sess.opts.cg.save_temps { let remove_temps_from_module = |module: &CompiledModule| { if let Some(ref obj) = module.object { - remove(sess, obj); + ensure_removed(sess.diagnostic(), obj); } if let Some(ref obj) = module.dwarf_object { - remove(sess, obj); + ensure_removed(sess.diagnostic(), obj); } }; diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 6aef5cb535a1f..b0aed81246007 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1,4 +1,4 @@ -use super::link::{self, remove}; +use super::link::{self, ensure_removed}; use super::linker::LinkerInfo; use super::lto::{self, SerializedModule}; use super::symbol_export::symbol_name_for_instance_in_crate; @@ -543,7 +543,7 @@ fn produce_final_output_artifacts( copy_gracefully(&path, &crate_output.path(output_type)); if !sess.opts.cg.save_temps && !keep_numbered { // The user just wants `foo.x`, not `foo.#module-name#.x`. - remove(sess, &path); + ensure_removed(sess.diagnostic(), &path); } } else { let ext = crate_output @@ -642,19 +642,19 @@ fn produce_final_output_artifacts( for module in compiled_modules.modules.iter() { if let Some(ref path) = module.object { if !keep_numbered_objects { - remove(sess, path); + ensure_removed(sess.diagnostic(), path); } } if let Some(ref path) = module.dwarf_object { if !keep_numbered_objects { - remove(sess, path); + ensure_removed(sess.diagnostic(), path); } } if let Some(ref path) = module.bytecode { if !keep_numbered_bitcode { - remove(sess, path); + ensure_removed(sess.diagnostic(), path); } } } @@ -662,13 +662,13 @@ fn produce_final_output_artifacts( if !user_wants_bitcode { if let Some(ref metadata_module) = compiled_modules.metadata_module { if let Some(ref path) = metadata_module.bytecode { - remove(sess, &path); + ensure_removed(sess.diagnostic(), &path); } } if let Some(ref allocator_module) = compiled_modules.allocator_module { if let Some(ref path) = allocator_module.bytecode { - remove(sess, path); + ensure_removed(sess.diagnostic(), path); } } } diff --git a/src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs b/src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs new file mode 100644 index 0000000000000..043011b3316a7 --- /dev/null +++ b/src/test/ui/debuginfo-emit-llvm-ir-and-split-debuginfo.rs @@ -0,0 +1,7 @@ +// build-pass +// +// compile-flags: -g --emit=llvm-ir -Zunstable-options -Csplit-debuginfo=unpacked +// +// Make sure that we don't explode with an error if we don't actually end up emitting any `dwo`s, +// as would be the case if we don't actually codegen anything. +#![crate_type="rlib"] From 845c14db05bb19bb7c8a0df835a9951073d313bb Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Sun, 14 Feb 2021 11:34:22 +0000 Subject: [PATCH 04/17] Simpler way to convert to digit --- library/core/src/char/methods.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index e450240527aa5..d92df5532e589 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1,5 +1,6 @@ //! impl char {} +use crate::intrinsics::likely; use crate::slice; use crate::str::from_utf8_unchecked_mut; use crate::unicode::printable::is_printable; @@ -330,16 +331,14 @@ impl char { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn to_digit(self, radix: u32) -> Option { + assert!(radix <= 36, "to_digit: radix is too high (maximum 36)"); + const ASCII_DIGIT_MASK: u32 = 0b11_0000; // the code is split up here to improve execution speed for cases where // the `radix` is constant and 10 or smaller - let val = if radix <= 10 { - match self { - '0'..='9' => self as u32 - '0' as u32, - _ => return None, - } + let val = if likely(radix <= 10) { + // If not a digit, a number greater than radix will be created. + self as u32 ^ ASCII_DIGIT_MASK } else { - assert!(radix <= 36, "to_digit: radix is too high (maximum 36)"); - match self { '0'..='9' => self as u32 - '0' as u32, 'a'..='z' => self as u32 - 'a' as u32 + 10, From a491f51218f93cc6373b28b2f0f753c5c1a5b295 Mon Sep 17 00:00:00 2001 From: Edward Shen Date: Sun, 14 Feb 2021 23:59:45 -0500 Subject: [PATCH 05/17] Use delay_span_bug for mismatched subst/hir arg --- .../borrow_check/diagnostics/region_name.rs | 11 ++--- .../issue-82126-mismatched-subst-and-hir.rs | 25 +++++++++++ ...ssue-82126-mismatched-subst-and-hir.stderr | 43 +++++++++++++++++++ 3 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs create mode 100644 src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index cbca012824f82..77297ded40d75 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs @@ -634,14 +634,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { | GenericArgKind::Const(_), _, ) => { - // I *think* that HIR lowering should ensure this - // doesn't happen, even in erroneous - // programs. Else we should use delay-span-bug. - span_bug!( + // HIR lowering is insufficient in erroneous programs, so + // we need to use delay_span_bug here. See #82126. + self.infcx.tcx.sess.delay_span_bug( hir_arg.span(), - "unmatched subst and hir arg: found {:?} vs {:?}", - kind, - hir_arg, + &format!("unmatched subst and hir arg: found {:?} vs {:?}", kind, hir_arg), ); } } diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs new file mode 100644 index 0000000000000..b6cb617e2f0e7 --- /dev/null +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs @@ -0,0 +1,25 @@ +// Regression test for #82087. Checks that mismatched lifetimes and types are +// properly handled. + +// edition:2018 + +use std::sync::Mutex; + +struct MarketMultiplier {} + +impl MarketMultiplier { + fn buy(&mut self) -> &mut usize { + todo!() + } +} + +async fn buy_lock(generator: &Mutex) -> LockedMarket<'_> { + //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied + //~^^ ERROR this struct takes 1 type argument but 0 type arguments were supplied + LockedMarket(generator.lock().unwrap().buy()) + //~^ ERROR cannot return value referencing temporary value +} + +struct LockedMarket(T); + +fn main() {} diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr new file mode 100644 index 0000000000000..b6844f50488e1 --- /dev/null +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr @@ -0,0 +1,43 @@ +error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59 + | +LL | async fn buy_lock(generator: &Mutex) -> LockedMarket<'_> { + | ^^^^^^^^^^^^---- help: remove these generics + | | + | expected 0 lifetime arguments + | +note: struct defined here, with 0 lifetime parameters + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + | +LL | struct LockedMarket(T); + | ^^^^^^^^^^^^ + +error[E0107]: this struct takes 1 type argument but 0 type arguments were supplied + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59 + | +LL | async fn buy_lock(generator: &Mutex) -> LockedMarket<'_> { + | ^^^^^^^^^^^^ expected 1 type argument + | +note: struct defined here, with 1 type parameter: `T` + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:23:8 + | +LL | struct LockedMarket(T); + | ^^^^^^^^^^^^ - +help: add missing type argument + | +LL | async fn buy_lock(generator: &Mutex) -> LockedMarket<'_, T> { + | ^^^ + +error[E0515]: cannot return value referencing temporary value + --> $DIR/issue-82126-mismatched-subst-and-hir.rs:19:5 + | +LL | LockedMarket(generator.lock().unwrap().buy()) + | ^^^^^^^^^^^^^-------------------------^^^^^^^ + | | | + | | temporary value created here + | returns a value referencing data owned by the current function + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0107, E0515. +For more information about an error, try `rustc --explain E0107`. From f856224e16ef378968114c3811d99bf5cd0e64cb Mon Sep 17 00:00:00 2001 From: Edward Shen Date: Mon, 15 Feb 2021 00:03:57 -0500 Subject: [PATCH 06/17] Fix test issue reference --- src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs index b6cb617e2f0e7..2e6b88a4beba8 100644 --- a/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs +++ b/src/test/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs @@ -1,4 +1,4 @@ -// Regression test for #82087. Checks that mismatched lifetimes and types are +// Regression test for #82126. Checks that mismatched lifetimes and types are // properly handled. // edition:2018 From a4b2fafcc19801e858afc59ed3b319c39adefc20 Mon Sep 17 00:00:00 2001 From: Edward Shen Date: Mon, 15 Feb 2021 00:28:58 -0500 Subject: [PATCH 07/17] Revise HIR lowering comment --- .../rustc_mir/src/borrow_check/diagnostics/region_name.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs index 77297ded40d75..c8b45f87639a2 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_name.rs @@ -634,8 +634,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { | GenericArgKind::Const(_), _, ) => { - // HIR lowering is insufficient in erroneous programs, so - // we need to use delay_span_bug here. See #82126. + // HIR lowering sometimes doesn't catch this in erroneous + // programs, so we need to use delay_span_bug here. See #82126. self.infcx.tcx.sess.delay_span_bug( hir_arg.span(), &format!("unmatched subst and hir arg: found {:?} vs {:?}", kind, hir_arg), From 17e238d78ee0baa33e560ec51ab636a2da7a2493 Mon Sep 17 00:00:00 2001 From: Squirrel Date: Mon, 15 Feb 2021 07:35:28 +0000 Subject: [PATCH 08/17] Use wrapping sub Co-authored-by: Mara --- library/core/src/char/methods.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index d92df5532e589..4e9dad9fd2c1a 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -337,7 +337,7 @@ impl char { // the `radix` is constant and 10 or smaller let val = if likely(radix <= 10) { // If not a digit, a number greater than radix will be created. - self as u32 ^ ASCII_DIGIT_MASK + (self as u32).wrapping_sub('0' as u32) } else { match self { '0'..='9' => self as u32 - '0' as u32, From d2ba68b24eba7e763b5e0937ab1ef6dcb5a09ca3 Mon Sep 17 00:00:00 2001 From: Squirrel Date: Mon, 15 Feb 2021 07:39:15 +0000 Subject: [PATCH 09/17] Update methods.rs Remove unused const --- library/core/src/char/methods.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index 4e9dad9fd2c1a..64ae7db0d9b53 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -332,7 +332,6 @@ impl char { #[inline] pub fn to_digit(self, radix: u32) -> Option { assert!(radix <= 36, "to_digit: radix is too high (maximum 36)"); - const ASCII_DIGIT_MASK: u32 = 0b11_0000; // the code is split up here to improve execution speed for cases where // the `radix` is constant and 10 or smaller let val = if likely(radix <= 10) { From cb653b100c43118beed5bbd84cd8b832362a355f Mon Sep 17 00:00:00 2001 From: Teddy Katz Date: Mon, 15 Feb 2021 21:06:00 -0500 Subject: [PATCH 10/17] Document that `assert!` format arguments are evaluated lazily It can be useful to do some computation in `assert!` format arguments, in order to get better error messages. For example: ```rust assert!( some_condition, "The state is invalid. Details: {}", expensive_call_to_get_debugging_info(), ); ``` It seems like `assert!` only evaluates the format arguments if the assertion fails, which is useful but doesn't appear to be documented anywhere. This PR documents the behavior and adds some tests. --- library/core/src/macros/mod.rs | 3 ++- src/test/ui/macros/assert-format-lazy.rs | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/macros/assert-format-lazy.rs diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 7aaf5a5fd4614..3b085b0459a4f 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1208,7 +1208,8 @@ pub(crate) mod builtin { /// /// This macro has a second form, where a custom panic message can /// be provided with or without arguments for formatting. See [`std::fmt`] - /// for syntax for this form. + /// for syntax for this form. Expressions used as format arguments will only + /// be evaluated if the assertion fails. /// /// [`std::fmt`]: ../std/fmt/index.html /// diff --git a/src/test/ui/macros/assert-format-lazy.rs b/src/test/ui/macros/assert-format-lazy.rs new file mode 100644 index 0000000000000..e0e2bd5a970e5 --- /dev/null +++ b/src/test/ui/macros/assert-format-lazy.rs @@ -0,0 +1,11 @@ +// run-pass + +#[allow(unreachable_code)] +fn main() { + assert!(true, "Failed: {:?}", panic!("assert! evaluated format expressions")); + debug_assert!(true, "Failed: {:?}", panic!("debug_assert! evaluated format expressions")); + assert_eq!(1, 1, "Failed: {:?}", panic!("assert_eq! evaluated format expressions")); + debug_assert_eq!(1, 1, "Failed: {:?}", panic!("debug_assert_eq! evaluated format expressions")); + assert_ne!(1, 2, "Failed: {:?}", panic!("assert_ne! evaluated format expressions")); + debug_assert_ne!(1, 2, "Failed: {:?}", panic!("debug_assert_ne! evaluated format expressions")); +} From e527def9c7a090fabf9ca41d09b629e5268d41f8 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 16 Feb 2021 08:09:07 +0100 Subject: [PATCH 11/17] Replace File::create and write_all with fs::write Also don't convert to u8 buffers and back when we are only creating strings. --- compiler/rustc_driver/src/pretty.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index b7edc24bc4a1a..1729cf99862a8 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -15,8 +15,6 @@ use rustc_span::symbol::Ident; use rustc_span::FileName; use std::cell::Cell; -use std::fs::File; -use std::io::Write; use std::path::Path; pub use self::PpMode::*; @@ -375,13 +373,14 @@ fn get_source(input: &Input, sess: &Session) -> (String, FileName) { (src, src_name) } -fn write_output(out: Vec, ofile: Option<&Path>) { +fn write_or_print(out: &str, ofile: Option<&Path>) { match ofile { - None => print!("{}", String::from_utf8(out).unwrap()), - Some(p) => match File::create(p) { - Ok(mut w) => w.write_all(&out).unwrap(), - Err(e) => panic!("print-print failed to open {} due to {}", p.display(), e), - }, + None => print!("{}", out), + Some(p) => { + if let Err(e) = std::fs::write(p, out) { + panic!("print-print failed to write {} due to {}", p.display(), e); + } + } } } @@ -417,7 +416,7 @@ pub fn print_after_parsing( unreachable!(); }; - write_output(out.into_bytes(), ofile); + write_or_print(&out, ofile); } pub fn print_after_hir_lowering<'tcx>( @@ -477,7 +476,7 @@ pub fn print_after_hir_lowering<'tcx>( _ => unreachable!(), } - write_output(out.into_bytes(), ofile); + write_or_print(&out, ofile); } // In an ideal world, this would be a public function called by the driver after @@ -503,7 +502,8 @@ fn print_with_analysis( } .unwrap(); - write_output(out, ofile); + let out = std::str::from_utf8(&out).unwrap(); + write_or_print(out, ofile); Ok(()) } From a98b22c837edd73b11c8fca02a8bcedc9c94eb95 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 16 Feb 2021 11:45:46 -0800 Subject: [PATCH 12/17] Add caveat to Path::display() about lossiness --- library/std/src/path.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 1889e54933867..581c09e23dfa6 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2321,7 +2321,9 @@ impl Path { } /// Returns an object that implements [`Display`] for safely printing paths - /// that may contain non-Unicode data. + /// that may contain non-Unicode data. This may perform lossy conversion, + /// depending on the platform. If you would like an implementation which + /// escapes the path please use [`Debug`] instead. /// /// [`Display`]: fmt::Display /// @@ -2555,7 +2557,9 @@ impl fmt::Debug for Path { /// /// A [`Path`] might contain non-Unicode data. This `struct` implements the /// [`Display`] trait in a way that mitigates that. It is created by the -/// [`display`](Path::display) method on [`Path`]. +/// [`display`](Path::display) method on [`Path`]. This may perform lossy +/// conversion, depending on the platform. If you would like an implementation +/// which escapes the path please use [`Debug`] instead. /// /// # Examples /// From 61bb1836f8f2e72e9e92187cc763d0873d603b91 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Tue, 16 Feb 2021 21:49:56 +0100 Subject: [PATCH 13/17] Optimize Iterator::is_sorted_by by using Iterator::all for internal iteration --- library/core/src/iter/traits/iterator.rs | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 9f7ced829b0ac..b9ec2becbd2f8 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -3317,24 +3317,31 @@ pub trait Iterator { /// /// [`is_sorted`]: Iterator::is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] - fn is_sorted_by(mut self, mut compare: F) -> bool + fn is_sorted_by(mut self, compare: F) -> bool where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Option, { + #[inline] + fn check<'a, T>( + last: &'a mut T, + mut compare: impl FnMut(&T, &T) -> Option + 'a, + ) -> impl FnMut(T) -> bool + 'a { + move |curr| { + if let Some(Ordering::Greater) | None = compare(&last, &curr) { + return false; + } + *last = curr; + true + } + } + let mut last = match self.next() { Some(e) => e, None => return true, }; - while let Some(curr) = self.next() { - if let Some(Ordering::Greater) | None = compare(&last, &curr) { - return false; - } - last = curr; - } - - true + self.all(check(&mut last, compare)) } /// Checks if the elements of this iterator are sorted using the given key extraction From 15197cbc61450bd19328387ad9a04500e35d7086 Mon Sep 17 00:00:00 2001 From: Teddy Katz Date: Tue, 16 Feb 2021 19:05:30 -0500 Subject: [PATCH 14/17] Ensure debug_assert! tests get run --- src/test/ui/macros/assert-format-lazy.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/macros/assert-format-lazy.rs b/src/test/ui/macros/assert-format-lazy.rs index e0e2bd5a970e5..c7f05d763b7a4 100644 --- a/src/test/ui/macros/assert-format-lazy.rs +++ b/src/test/ui/macros/assert-format-lazy.rs @@ -1,4 +1,5 @@ // run-pass +// compile-flags: -C debug_assertions=yes #[allow(unreachable_code)] fn main() { From 5715f79b3739a9df2e8dbf9488f3d76f8b024f5b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 16 Feb 2021 17:19:28 -0800 Subject: [PATCH 15/17] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/embedded-book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/book b/src/doc/book index e724bd826580f..db5e8a5105aa2 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit e724bd826580ff95df48a8533af7dec1080693d4 +Subproject commit db5e8a5105aa22979490dce30e33b68d8645761d diff --git a/src/doc/edition-guide b/src/doc/edition-guide index b91a9a881ee00..1da3c411f17ad 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit b91a9a881ee007c12e74e844460ec407cf07a50f +Subproject commit 1da3c411f17adb1ba5de1683bb6acee83362b54a diff --git a/src/doc/embedded-book b/src/doc/embedded-book index ceec19e873be8..4cf7981696a85 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit ceec19e873be87c6ee5666b030c6bb612f889a96 +Subproject commit 4cf7981696a85c3e633076c6401611bd3f6346c4 diff --git a/src/doc/nomicon b/src/doc/nomicon index bbf06ad39d1f4..adca786547d08 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit bbf06ad39d1f45654047e9596b750cc6e6d1b693 +Subproject commit adca786547d08fe676b2fc7a6f08c2ed5280ca38 diff --git a/src/doc/reference b/src/doc/reference index f02b09eb6e8af..361367c126290 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit f02b09eb6e8af340ad1256a54adb7aae2ff3163e +Subproject commit 361367c126290ac17cb4089f8d38fd8b2ac43f98 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index f633769acef68..551cc4bc8394f 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit f633769acef68574427a6fae6c06f13bc2199573 +Subproject commit 551cc4bc8394feccea6acd21f86d9a4e1d2271a0 From ee0e841a2e949cba1dcf3a2fb04e9a673681e4fd Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 16 Feb 2021 19:17:01 -0800 Subject: [PATCH 16/17] rustdoc: treat edition 2021 as unstable --- compiler/rustc_session/src/config.rs | 2 +- src/librustdoc/config.rs | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 210dbb0ee9939..4533b37f10b42 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1350,7 +1350,7 @@ pub fn parse_error_format( error_format } -fn parse_crate_edition(matches: &getopts::Matches) -> Edition { +pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition { let edition = match matches.opt_str("edition") { Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| { early_error( diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 63a25e5dbfbbb..1478437cefaa3 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -16,7 +16,7 @@ use rustc_session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, E use rustc_session::getopts; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; -use rustc_span::edition::{Edition, DEFAULT_EDITION}; +use rustc_span::edition::Edition; use rustc_target::spec::TargetTriple; use crate::core::new_handler; @@ -469,17 +469,7 @@ impl Options { } } - let edition = if let Some(e) = matches.opt_str("edition") { - match e.parse() { - Ok(e) => e, - Err(_) => { - diag.struct_err("could not parse edition").emit(); - return Err(1); - } - } - } else { - DEFAULT_EDITION - }; + let edition = config::parse_crate_edition(&matches); let mut id_map = html::markdown::IdMap::new(); id_map.populate(&html::render::INITIAL_IDS); From c80b737394e1616993a23d5deb2b8f4c888f32dc Mon Sep 17 00:00:00 2001 From: Jesus Rubio Date: Wed, 17 Feb 2021 18:08:30 +0100 Subject: [PATCH 17/17] Add long explanation for E0543 --- compiler/rustc_error_codes/src/error_codes.rs | 2 +- .../src/error_codes/E0543.md | 35 +++++++++++++++++++ .../stability-attribute-sanity.stderr | 2 +- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0543.md diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index cccc0e0560012..8944711f38f4f 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -286,6 +286,7 @@ E0538: include_str!("./error_codes/E0538.md"), E0539: include_str!("./error_codes/E0539.md"), E0541: include_str!("./error_codes/E0541.md"), E0542: include_str!("./error_codes/E0542.md"), +E0543: include_str!("./error_codes/E0543.md"), E0545: include_str!("./error_codes/E0545.md"), E0546: include_str!("./error_codes/E0546.md"), E0547: include_str!("./error_codes/E0547.md"), @@ -605,7 +606,6 @@ E0781: include_str!("./error_codes/E0781.md"), E0523, // E0526, // shuffle indices are not constant // E0540, // multiple rustc_deprecated attributes - E0543, // missing 'reason' E0544, // multiple stability levels // E0548, // replaced with a generic attribute input check // rustc_deprecated attribute must be paired with either stable or unstable diff --git a/compiler/rustc_error_codes/src/error_codes/E0543.md b/compiler/rustc_error_codes/src/error_codes/E0543.md new file mode 100644 index 0000000000000..ba26f92e89f5e --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0543.md @@ -0,0 +1,35 @@ +The `reason` value is missing in a stability attribute. + +Erroneous code example: + +```compile_fail,E0543 +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "test")] + +#[stable(since = "0.1.0", feature = "_deprecated_fn")] +#[rustc_deprecated( + since = "1.0.0" +)] // invalid +fn _deprecated_fn() {} +``` + +To fix this issue, you need to provide the `reason` field. Example: + +``` +#![feature(staged_api)] +#![stable(since = "1.0.0", feature = "test")] + +#[stable(since = "0.1.0", feature = "_deprecated_fn")] +#[rustc_deprecated( + since = "1.0.0", + reason = "explanation for deprecation" +)] // ok! +fn _deprecated_fn() {} +``` + +See the [How Rust is Made and “Nightly Rust”][how-rust-made-nightly] appendix +of the Book and the [Stability attributes][stability-attributes] section of the +Rustc Dev Guide for more details. + +[how-rust-made-nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html +[stability-attributes]: https://rustc-dev-guide.rust-lang.org/stability.html diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr index 674139f4afcce..715eb00974ee2 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr @@ -116,5 +116,5 @@ LL | #[rustc_deprecated(since = "a", reason = "text")] error: aborting due to 19 previous errors -Some errors have detailed explanations: E0539, E0541, E0542, E0546, E0547, E0550. +Some errors have detailed explanations: E0539, E0541, E0542, E0543, E0546, E0547, E0550. For more information about an error, try `rustc --explain E0539`.