From b99f9f775c59de7223e810b303e56b39f7bbaf03 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Nov 2018 21:48:13 +0000 Subject: [PATCH 01/13] Enclose type in backticks for "non-exhaustive patterns" error This makes the error style consistent with the convention in error messages. --- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/test/ui/error-codes/E0004-2.stderr | 2 +- src/test/ui/issues/issue-3096-1.stderr | 2 +- src/test/ui/issues/issue-3096-2.stderr | 2 +- .../ui/uninhabited/uninhabited-matches-feature-gated.stderr | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index bafabe4e9972c..a6bd36e582fcd 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -234,7 +234,7 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { if !scrutinee_is_uninhabited { // We know the type is inhabited, so this must be wrong let mut err = create_e0004(self.tcx.sess, scrut.span, - format!("non-exhaustive patterns: type {} \ + format!("non-exhaustive patterns: type `{}` \ is non-empty", pat_ty)); span_help!(&mut err, scrut.span, diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr index 900812787bcf7..2d46196ddda55 100644 --- a/src/test/ui/error-codes/E0004-2.stderr +++ b/src/test/ui/error-codes/E0004-2.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type std::option::Option is non-empty +error[E0004]: non-exhaustive patterns: type `std::option::Option` is non-empty --> $DIR/E0004-2.rs:14:11 | LL | match x { } //~ ERROR E0004 diff --git a/src/test/ui/issues/issue-3096-1.stderr b/src/test/ui/issues/issue-3096-1.stderr index b2bfe6b5e8c07..f0782bd973805 100644 --- a/src/test/ui/issues/issue-3096-1.stderr +++ b/src/test/ui/issues/issue-3096-1.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type () is non-empty +error[E0004]: non-exhaustive patterns: type `()` is non-empty --> $DIR/issue-3096-1.rs:12:11 | LL | match () { } //~ ERROR non-exhaustive diff --git a/src/test/ui/issues/issue-3096-2.stderr b/src/test/ui/issues/issue-3096-2.stderr index bb9dfabe7be03..e0fa641ff39e7 100644 --- a/src/test/ui/issues/issue-3096-2.stderr +++ b/src/test/ui/issues/issue-3096-2.stderr @@ -1,4 +1,4 @@ -error[E0004]: non-exhaustive patterns: type *const bottom is non-empty +error[E0004]: non-exhaustive patterns: type `*const bottom` is non-empty --> $DIR/issue-3096-2.rs:15:11 | LL | match x { } //~ ERROR non-exhaustive patterns diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index 83fd736a997a9..f4974b8fa3854 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -4,7 +4,7 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered LL | let _ = match x { //~ ERROR non-exhaustive | ^ pattern `Err(_)` not covered -error[E0004]: non-exhaustive patterns: type &Void is non-empty +error[E0004]: non-exhaustive patterns: type `&Void` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:20:19 | LL | let _ = match x {}; //~ ERROR non-exhaustive @@ -16,7 +16,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ -error[E0004]: non-exhaustive patterns: type (Void,) is non-empty +error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:23:19 | LL | let _ = match x {}; //~ ERROR non-exhaustive @@ -28,7 +28,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc LL | let _ = match x {}; //~ ERROR non-exhaustive | ^ -error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty +error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:26:19 | LL | let _ = match x {}; //~ ERROR non-exhaustive From 83388e84c25f86563d82514d7bf71cfd474e008a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20S=CC=B6c=CC=B6h=CC=B6n=CC=B6e=CC=B6i=CC=B6d=CC=B6?= =?UTF-8?q?e=CC=B6r=20Scherer?= Date: Wed, 21 Nov 2018 12:26:40 +0100 Subject: [PATCH 02/13] Update an outdated comment in mir building --- src/librustc_mir/build/expr/as_temp.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 8f50a1e9a21b9..19bfb35ed620d 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -85,9 +85,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); - // In constants, temp_lifetime is None. We should not need to drop - // anything because no values with a destructor can be created in - // a constant at this time, even if the type may need dropping. + // In constants, temp_lifetime is None. We do not drop anything because + // values with a destructor will simply be leaked in constants. if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop_storage_and_value( expr_span, From 5a2a251b9cb0358851bb9d8d8870163f43c081dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20S=CC=B6c=CC=B6h=CC=B6n=CC=B6e=CC=B6i=CC=B6d=CC=B6?= =?UTF-8?q?e=CC=B6r=20Scherer?= Date: Wed, 21 Nov 2018 12:40:53 +0100 Subject: [PATCH 03/13] Update as_temp.rs --- src/librustc_mir/build/expr/as_temp.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index 19bfb35ed620d..f060eefe520a6 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -85,8 +85,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); - // In constants, temp_lifetime is None. We do not drop anything because - // values with a destructor will simply be leaked in constants. + // In constants, temp_lifetime is None for temporaries that live for the + // entire constant. Thus we do not drop these temporaries and simply leak them. + // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything + // within a block will keep the regular drops just like runtime code. if let Some(temp_lifetime) = temp_lifetime { this.schedule_drop_storage_and_value( expr_span, From 925274ab70c15ac5dcb3537e3473c29771ab7df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20S=CC=B6c=CC=B6h=CC=B6n=CC=B6e=CC=B6i=CC=B6d=CC=B6?= =?UTF-8?q?e=CC=B6r=20Scherer?= Date: Wed, 21 Nov 2018 13:10:10 +0100 Subject: [PATCH 04/13] Update as_temp.rs --- src/librustc_mir/build/expr/as_temp.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index f060eefe520a6..2db9fb9cb99f4 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -86,7 +86,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { unpack!(block = this.into(&Place::Local(temp), block, expr)); // In constants, temp_lifetime is None for temporaries that live for the - // entire constant. Thus we do not drop these temporaries and simply leak them. + // 'static lifetime. Thus we do not drop these temporaries and simply leak them. + // This is equivalent to what `let x = &foo();` does in functions. The temporary + // is lifted to their surrounding scope. In a function that means the temporary lives + // until just before the function returns. In constants that means it outlives the + // constant's initialization value computation. Anything outliving a constant + // must have the `'static` lifetime and live forever. // Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything // within a block will keep the regular drops just like runtime code. if let Some(temp_lifetime) = temp_lifetime { From f03987276656134f25f92f7434d7d1c63c9e981c Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 21 Nov 2018 16:06:24 +0000 Subject: [PATCH 05/13] Enclose type in backticks for "reached the recursion limit while auto-dereferencing" error --- src/librustc_typeck/check/autoderef.rs | 4 ++-- src/librustc_typeck/diagnostics.rs | 2 +- src/test/ui/did_you_mean/recursion_limit_deref.stderr | 2 +- src/test/ui/error-codes/E0055.stderr | 2 +- src/test/ui/infinite/infinite-autoderef.stderr | 6 +++--- src/test/ui/issues/issue-38940.rs | 2 +- src/test/ui/issues/issue-38940.stderr | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index 73489309d0742..2cd2bb5064877 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -59,7 +59,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> { if self.steps.len() >= *tcx.sess.recursion_limit.get() { // We've reached the recursion limit, error gracefully. let suggested_limit = *tcx.sess.recursion_limit.get() * 2; - let msg = format!("reached the recursion limit while auto-dereferencing {:?}", + let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`", self.cur_ty); let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg); let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); @@ -67,7 +67,7 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> { struct_span_err!(tcx.sess, self.span, E0055, - "reached the recursion limit while auto-dereferencing {:?}", + "reached the recursion limit while auto-dereferencing `{:?}`", self.cur_ty) .span_label(self.span, "deref recursion limit reached") .help(&format!( diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index a985c3e9fdf44..084951f4a2c16 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -538,7 +538,7 @@ fn main() { let foo = Foo; let ref_foo = &&Foo; - // error, reached the recursion limit while auto-dereferencing &&Foo + // error, reached the recursion limit while auto-dereferencing `&&Foo` ref_foo.foo(); } ``` diff --git a/src/test/ui/did_you_mean/recursion_limit_deref.stderr b/src/test/ui/did_you_mean/recursion_limit_deref.stderr index 20a94f7aac196..7e7f21dd69c92 100644 --- a/src/test/ui/did_you_mean/recursion_limit_deref.stderr +++ b/src/test/ui/did_you_mean/recursion_limit_deref.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing I +error[E0055]: reached the recursion limit while auto-dereferencing `I` --> $DIR/recursion_limit_deref.rs:60:22 | LL | let x: &Bottom = &t; //~ ERROR mismatched types diff --git a/src/test/ui/error-codes/E0055.stderr b/src/test/ui/error-codes/E0055.stderr index 9653f4eaeefd0..dddbd92765a5d 100644 --- a/src/test/ui/error-codes/E0055.stderr +++ b/src/test/ui/error-codes/E0055.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/E0055.rs:21:13 | LL | ref_foo.foo(); diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr index b5e20ea5cbf99..ef68adecd1a5f 100644 --- a/src/test/ui/infinite/infinite-autoderef.stderr +++ b/src/test/ui/infinite/infinite-autoderef.stderr @@ -7,7 +7,7 @@ LL | x = box x; | cyclic type of infinite size | help: try using a conversion method: `box x.to_string()` -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:35:5 | LL | Foo.foo; @@ -15,7 +15,7 @@ LL | Foo.foo; | = help: consider adding a `#![recursion_limit="128"]` attribute to your crate -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:35:9 | LL | Foo.foo; @@ -29,7 +29,7 @@ error[E0609]: no field `foo` on type `Foo` LL | Foo.foo; | ^^^ unknown field -error[E0055]: reached the recursion limit while auto-dereferencing Foo +error[E0055]: reached the recursion limit while auto-dereferencing `Foo` --> $DIR/infinite-autoderef.rs:36:9 | LL | Foo.bar(); diff --git a/src/test/ui/issues/issue-38940.rs b/src/test/ui/issues/issue-38940.rs index 7f9b141e02e3c..1c785949547e5 100644 --- a/src/test/ui/issues/issue-38940.rs +++ b/src/test/ui/issues/issue-38940.rs @@ -42,5 +42,5 @@ fn main() { let t = Top::new(); let x: &Bottom = &t; //~^ ERROR mismatched types - //~| ERROR reached the recursion limit while auto-dereferencing I + //~| ERROR reached the recursion limit while auto-dereferencing `I` } diff --git a/src/test/ui/issues/issue-38940.stderr b/src/test/ui/issues/issue-38940.stderr index 2d3cfda9a5f72..d94a7101c0a38 100644 --- a/src/test/ui/issues/issue-38940.stderr +++ b/src/test/ui/issues/issue-38940.stderr @@ -1,4 +1,4 @@ -error[E0055]: reached the recursion limit while auto-dereferencing I +error[E0055]: reached the recursion limit while auto-dereferencing `I` --> $DIR/issue-38940.rs:43:22 | LL | let x: &Bottom = &t; From 5c99ae6661311e42abaa590dcf592106155b3c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 24 Nov 2018 17:12:28 -0800 Subject: [PATCH 06/13] Fix ICE with feature self_struct_ctor --- src/librustc/middle/reachable.rs | 1 + src/test/ui/issues/issue-56202.rs | 15 +++++++++++++++ src/test/ui/issues/issue-56202.stderr | 7 +++++++ 3 files changed, 23 insertions(+) create mode 100644 src/test/ui/issues/issue-56202.rs create mode 100644 src/test/ui/issues/issue-56202.stderr diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 0009a517dd1db..cf81729bdaba8 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -116,6 +116,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => { self.reachable_symbols.insert(node_id); } + Some(Def::Err) => {} // #56202: calling `def.def_id()` would be an error Some(def) => { let def_id = def.def_id(); if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { diff --git a/src/test/ui/issues/issue-56202.rs b/src/test/ui/issues/issue-56202.rs new file mode 100644 index 0000000000000..c80c372c9e2ea --- /dev/null +++ b/src/test/ui/issues/issue-56202.rs @@ -0,0 +1,15 @@ +#![feature(self_struct_ctor)] + +trait FooTrait {} + +trait BarTrait { + fn foo(_: T) -> Self; +} + +struct FooStruct(u32); + +impl BarTrait for FooStruct { + fn foo(_: T) -> Self { + Self(u32::default()) + } +} diff --git a/src/test/ui/issues/issue-56202.stderr b/src/test/ui/issues/issue-56202.stderr new file mode 100644 index 0000000000000..3007b08450298 --- /dev/null +++ b/src/test/ui/issues/issue-56202.stderr @@ -0,0 +1,7 @@ +error[E0601]: `main` function not found in crate `issue_56202` + | + = note: consider adding a `main` function to `$DIR/issue-56202.rs` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0601`. From 8d76f54fd8f866c2ccefb736cb084dddedd9230d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 25 Nov 2018 07:40:26 -0800 Subject: [PATCH 07/13] Use opt_def_id instead of having special branch --- src/librustc/middle/reachable.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index cf81729bdaba8..ab0094df0e219 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -116,10 +116,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> { Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => { self.reachable_symbols.insert(node_id); } - Some(Def::Err) => {} // #56202: calling `def.def_id()` would be an error Some(def) => { - let def_id = def.def_id(); - if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { + if let Some((node_id, def_id)) = def.opt_def_id().and_then(|def_id| { + self.tcx.hir.as_local_node_id(def_id).map(|node_id| (node_id, def_id)) + }) { if self.def_id_represents_local_inlined_item(def_id) { self.worklist.push(node_id); } else { From 057e6d3a35a54e8b88c2cef1e6a1b9e590066276 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 25 Nov 2018 17:33:16 +0100 Subject: [PATCH 08/13] Add TryFrom<&[T]> for [T; $N] where T: Copy `TryFrom<&[T]> for &[T; $N]` (note *reference* to an array) already exists, but not needing to dereference makes type inference easier for example when using `u32::from_be_bytes`. Also add doc examples doing just that. --- src/libcore/array.rs | 9 +++++ src/libcore/num/mod.rs | 78 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/src/libcore/array.rs b/src/libcore/array.rs index 3d24f8902bd83..26e7a79d35df6 100644 --- a/src/libcore/array.rs +++ b/src/libcore/array.rs @@ -148,6 +148,15 @@ macro_rules! array_impls { } } + #[unstable(feature = "try_from", issue = "33417")] + impl<'a, T> TryFrom<&'a [T]> for [T; $N] where T: Copy { + type Error = TryFromSliceError; + + fn try_from(slice: &[T]) -> Result<[T; $N], TryFromSliceError> { + <&Self>::try_from(slice).map(|r| *r) + } + } + #[unstable(feature = "try_from", issue = "33417")] impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] { type Error = TryFromSliceError; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 9deae12482976..f6f649bc06d01 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1989,6 +1989,19 @@ big endian. ``` let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -2008,6 +2021,19 @@ little endian. ``` let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -2037,6 +2063,19 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi ", $le_bytes, " }); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -3719,6 +3758,19 @@ big endian. ``` let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -3738,6 +3790,19 @@ little endian. ``` let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, "); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] @@ -3767,6 +3832,19 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi ", $le_bytes, " }); assert_eq!(value, ", $swap_op, "); +``` + +When starting from a slice rather than an array, fallible conversion APIs can be used: + +``` +#![feature(try_from)] +use std::convert::TryInto; + +fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " { + let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">()); + *input = rest; + ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap()) +} ```"), #[stable(feature = "int_to_from_bytes", since = "1.32.0")] #[rustc_const_unstable(feature = "const_int_conversion")] From 2d2b7c01ebee3f2926af58b9461284e271955855 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 25 Nov 2018 15:43:00 -0700 Subject: [PATCH 09/13] Make JSON output from -Zprofile-json valid --- src/librustc/util/profiling.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index 6540a09d87763..bea3453b31adf 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -102,7 +102,7 @@ macro_rules! define_categories { }; json.push_str(&format!( - "{{ \"category\": {}, \"time_ms\": {}, + "{{ \"category\": \"{}\", \"time_ms\": {},\ \"query_count\": {}, \"query_hits\": {} }},", stringify!($name), self.times.$name / 1_000_000, From ae0d0339e801bc10c46adbeb021b537b8313b760 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 25 Nov 2018 15:36:17 -0800 Subject: [PATCH 10/13] Update cargo --- Cargo.lock | 17 +++++++++++++++++ src/tools/cargo | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index a7b83f87b191b..604839d3a8a0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,6 +201,7 @@ dependencies = [ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "home 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ignore 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "im-rc 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -978,6 +979,15 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "im-rc" +version = "12.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "installer" version = "0.0.0" @@ -3038,6 +3048,11 @@ dependencies = [ "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "typenum" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ucd-util" version = "0.1.1" @@ -3331,6 +3346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum if_chain 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4bac95d9aa0624e7b78187d6fb8ab012b41d9f6f54b1bcb61e61c4845f8357ec" "checksum ignore 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3e9faa7c84064f07b40da27044af629f578bc7994b650d3e458d0c29183c1d91" +"checksum im-rc 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4591152fd573cf453a890b5f9fdc5c328a751a0785539316739d5f85e5c468c" "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053" "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450" "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" @@ -3482,6 +3498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" "checksum toml-query 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6854664bfc6df0360c695480836ee90e2d0c965f06db291d10be9344792d43e8" +"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25" diff --git a/src/tools/cargo b/src/tools/cargo index b3d0b2e545b61..1ff5975b96b3d 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit b3d0b2e545b61d4cd08096911724b7d49d213f73 +Subproject commit 1ff5975b96b3d395bb962394596998dfb485f793 From cc466851bc458219121142ae75f5cc47bb3a927f Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 26 Nov 2018 08:40:34 -0500 Subject: [PATCH 11/13] Remove unsafe `unsafe` inner function. Within this `Iterator` implementation, a function `unsafe_get` is defined which unsafely allows _unchecked_ indexing of any element in a slice. This should be marked as _unsafe_, but it is not. To address this issue, I removed that inner function. --- src/libcore/str/lossy.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 186d6adbc91cf..52abd8f99529b 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -62,18 +62,15 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } const TAG_CONT_U8: u8 = 128; - fn unsafe_get(xs: &[u8], i: usize) -> u8 { - unsafe { *xs.get_unchecked(i) } - } fn safe_get(xs: &[u8], i: usize) -> u8 { - if i >= xs.len() { 0 } else { unsafe_get(xs, i) } + *xs.get(i).unwrap_or(&0) } let mut i = 0; while i < self.source.len() { let i_ = i; - let byte = unsafe_get(self.source, i); + let byte = unsafe { *self.source.get_unchecked(i) }; i += 1; if byte < 128 { From cd20be50912170842689e4f936c31c5a28184432 Mon Sep 17 00:00:00 2001 From: Jason Langenauer Date: Mon, 26 Nov 2018 21:21:17 +0100 Subject: [PATCH 12/13] Update outdated code comments in StringReader --- src/libsyntax/parse/lexer/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index 0584cd5a3df47..c90c62c13f969 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -60,11 +60,11 @@ pub struct StringReader<'a> { // cache a direct reference to the source text, so that we don't have to // retrieve it via `self.source_file.src.as_ref().unwrap()` all the time. src: Lrc, - /// Stack of open delimiters and their spans. Used for error message. token: token::Token, span: Span, /// The raw source span which *does not* take `override_span` into account span_src_raw: Span, + /// Stack of open delimiters and their spans. Used for error message. open_braces: Vec<(token::DelimToken, Span)>, /// The type and spans for all braces /// @@ -506,8 +506,7 @@ impl<'a> StringReader<'a> { } } - /// Advance the StringReader by one character. If a newline is - /// discovered, add it to the SourceFile's list of line start offsets. + /// Advance the StringReader by one character. crate fn bump(&mut self) { let next_src_index = self.src_index(self.next_pos); if next_src_index < self.end_src_index { From d4a6e739f3322c56e66fa8fef31569b7f16bc325 Mon Sep 17 00:00:00 2001 From: ljedrz Date: Fri, 9 Nov 2018 15:12:09 +0100 Subject: [PATCH 13/13] Use sort_by_cached_key when key the function is not trivial/free --- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/traits/object_safety.rs | 2 +- src/librustc_mir/monomorphize/partitioning.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 6ff450508d136..07054ee99af76 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1573,7 +1573,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .collect(); // ensure that we issue lints in a repeatable order - def_ids.sort_by_key(|&def_id| self.tcx.def_path_hash(def_id)); + def_ids.sort_by_cached_key(|&def_id| self.tcx.def_path_hash(def_id)); for def_id in def_ids { debug!( diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index c79fa3861234f..2909daf22b3ba 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -409,7 +409,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { .collect::>(); // existential predicates need to be in a specific order - associated_types.sort_by_key(|item| self.def_path_hash(item.def_id)); + associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id)); let projection_predicates = associated_types.into_iter().map(|item| { ty::ExistentialPredicate::Projection(ty::ExistentialProjection { diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 6dba020120f84..3a6ee6da42215 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -985,7 +985,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); - cgus.as_mut_slice().sort_by_key(|&(ref name, _)| name.clone()); + cgus.as_mut_slice().sort_by_cached_key(|&(ref name, _)| name.clone()); cgus.dedup(); for &(ref cgu_name, (linkage, _)) in cgus.iter() { output.push_str(" ");