From 6fb5b73cf4dcf69e72ae414e83c53fe5eb8f0ffe Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Tue, 22 Jan 2019 17:51:33 -0500 Subject: [PATCH 01/15] dbg!() without parameters. --- src/libstd/macros.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index b87257188df..cfb8336e540 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -305,10 +305,16 @@ macro_rules! eprintln { /// let _ = dbg!(a); // <-- `a` is moved again; error! /// ``` /// +/// You can also use `dbg!()` without a value to just print the +/// file and line whenever it's reached. +/// /// [stderr]: https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr) #[macro_export] #[stable(feature = "dbg_macro", since = "1.32.0")] macro_rules! dbg { + () => { + eprintln!("[{}:{}]", file!(), line!()); + }; ($val:expr) => { // Use of `match` here is intentional because it affects the lifetimes // of temporaries - https://stackoverflow.com/a/48732525/1063961 From ea9e2c4ef5cf2d1867b284bd4f84b5417d8df45b Mon Sep 17 00:00:00 2001 From: Clar Fon Date: Thu, 31 Jan 2019 00:43:49 -0500 Subject: [PATCH 02/15] Test behaviour --- .../dbg-macro-expected-behavior.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs index 3d24f49ad75..67f7f80a9e2 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs @@ -33,6 +33,9 @@ fn test() { // We can move `b` because it's Copy. drop(b); + // Without parameters works as expected. + let _: () = dbg!(); + // Test that we can borrow and that successive applications is still identity. let a = NoCopy(1337); let b: &NoCopy = dbg!(dbg!(&a)); @@ -69,17 +72,19 @@ fn validate_stderr(stderr: Vec) { " y: 24", "}", - ":38] &a = NoCopy(", + ":37]", + + ":41] &a = NoCopy(", " 1337", ")", - ":38] dbg!(& a) = NoCopy(", + ":41] dbg!(& a) = NoCopy(", " 1337", ")", - ":43] f(&42) = 42", + ":46] f(&42) = 42", "before", - ":48] { foo += 1; eprintln!(\"before\"); 7331 } = 7331", + ":51] { foo += 1; eprintln!(\"before\"); 7331 } = 7331", ]); } From 988b3d5f9e43a9d63a8bff86756c27b9cb69615c Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 27 Feb 2019 18:11:35 +0100 Subject: [PATCH 03/15] Implement ExactSizeIterator for ToLowercase and ToUppercase --- src/libcore/char/mod.rs | 22 ++++++++++++++++++++++ src/libcore/tests/char.rs | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index 15e153bdfad..95b7c066793 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -389,11 +389,17 @@ impl Iterator for ToLowercase { fn next(&mut self) -> Option { self.0.next() } + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } } #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToLowercase {} +#[stable(feature = "exact_size_case_mapping_iter", since = "1.34.0")] +impl ExactSizeIterator for ToLowercase {} + /// Returns an iterator that yields the uppercase equivalent of a `char`. /// /// This `struct` is created by the [`to_uppercase`] method on [`char`]. See @@ -411,11 +417,17 @@ impl Iterator for ToUppercase { fn next(&mut self) -> Option { self.0.next() } + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } } #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToUppercase {} +#[stable(feature = "exact_size_case_mapping_iter", since = "1.34.0")] +impl ExactSizeIterator for ToUppercase {} + #[derive(Debug, Clone)] enum CaseMappingIter { Three(char, char, char), @@ -457,6 +469,16 @@ impl Iterator for CaseMappingIter { CaseMappingIter::Zero => None, } } + + fn size_hint(&self) -> (usize, Option) { + let size = match self { + CaseMappingIter::Three(..) => 3, + CaseMappingIter::Two(..) => 2, + CaseMappingIter::One(_) => 1, + CaseMappingIter::Zero => 0, + }; + (size, Some(size)) + } } impl fmt::Display for CaseMappingIter { diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs index 61856242c57..579feed288a 100644 --- a/src/libcore/tests/char.rs +++ b/src/libcore/tests/char.rs @@ -76,6 +76,8 @@ fn test_to_digit() { #[test] fn test_to_lowercase() { fn lower(c: char) -> String { + let to_lowercase = c.to_uppercase(); + assert_eq!(to_lowercase.len(), to_lowercase.count()); let iter: String = c.to_lowercase().collect(); let disp: String = c.to_lowercase().to_string(); assert_eq!(iter, disp); @@ -101,6 +103,8 @@ fn test_to_lowercase() { #[test] fn test_to_uppercase() { fn upper(c: char) -> String { + let to_uppercase = c.to_uppercase(); + assert_eq!(to_uppercase.len(), to_uppercase.count()); let iter: String = c.to_uppercase().collect(); let disp: String = c.to_uppercase().to_string(); assert_eq!(iter, disp); From 911a633bb1ce0f20fec1c8c45fe4cbf025f19e07 Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 27 Feb 2019 14:44:20 +0100 Subject: [PATCH 04/15] Remove copy paste error in char tests Co-Authored-By: xfix --- src/libcore/tests/char.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs index 579feed288a..57e9f4e384e 100644 --- a/src/libcore/tests/char.rs +++ b/src/libcore/tests/char.rs @@ -76,7 +76,7 @@ fn test_to_digit() { #[test] fn test_to_lowercase() { fn lower(c: char) -> String { - let to_lowercase = c.to_uppercase(); + let to_lowercase = c.to_lowercase(); assert_eq!(to_lowercase.len(), to_lowercase.count()); let iter: String = c.to_lowercase().collect(); let disp: String = c.to_lowercase().to_string(); From c5fe4055a90d0dac5dc80178d58148c042c5de2b Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Thu, 28 Feb 2019 10:23:13 -0500 Subject: [PATCH 05/15] Clarify distinction between floor() and trunc() --- src/libstd/f32.rs | 12 ++++++++---- src/libstd/f64.rs | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index f6cd9e82abd..1636208f46f 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -32,11 +32,13 @@ impl f32 { /// # Examples /// /// ``` - /// let f = 3.99_f32; + /// let f = 3.7_f32; /// let g = 3.0_f32; + /// let h = -3.7_f32; /// /// assert_eq!(f.floor(), 3.0); /// assert_eq!(g.floor(), 3.0); + /// assert_eq!(h.floor(), -4.0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -104,11 +106,13 @@ impl f32 { /// # Examples /// /// ``` - /// let f = 3.3_f32; - /// let g = -3.7_f32; + /// let f = 3.7_f32; + /// let g = 3.0_f32; + /// let h = -3.7_f32; /// /// assert_eq!(f.trunc(), 3.0); - /// assert_eq!(g.trunc(), -3.0); + /// assert_eq!(g.trunc(), 3.0); + /// assert_eq!(h.trunc(), -3.0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 8ff97ab828a..71605618cf6 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -32,11 +32,13 @@ impl f64 { /// # Examples /// /// ``` - /// let f = 3.99_f64; + /// let f = 3.7_f64; /// let g = 3.0_f64; + /// let h = -3.7_f64; /// /// assert_eq!(f.floor(), 3.0); /// assert_eq!(g.floor(), 3.0); + /// assert_eq!(h.floor(), -4.0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -84,11 +86,13 @@ impl f64 { /// # Examples /// /// ``` - /// let f = 3.3_f64; - /// let g = -3.7_f64; + /// let f = 3.7_f64; + /// let g = 3.0_f64; + /// let h = -3.7_f64; /// /// assert_eq!(f.trunc(), 3.0); - /// assert_eq!(g.trunc(), -3.0); + /// assert_eq!(g.trunc(), 3.0); + /// assert_eq!(h.trunc(), -3.0); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] From b91ab6287952e8ff4f6d6765ed5196825027c903 Mon Sep 17 00:00:00 2001 From: Taeguk Kwon Date: Tue, 5 Mar 2019 23:08:01 +0900 Subject: [PATCH 06/15] Fix a tiny error in documentation of std::pin. --- src/libcore/pin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index fb78f5e5a23..8da24c04510 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -109,7 +109,7 @@ //! assert_eq!(still_unmoved.slice, NonNull::from(&still_unmoved.data)); //! //! // Since our type doesn't implement Unpin, this will fail to compile: -//! // let new_unmoved = Unmovable::new("world".to_string()); +//! // let mut new_unmoved = Unmovable::new("world".to_string()); //! // std::mem::swap(&mut *still_unmoved, &mut *new_unmoved); //! ``` //! From b9d12edd6ce7b364fb1a4de53f7541d536df0940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 11 Mar 2019 15:07:07 -0700 Subject: [PATCH 07/15] Be more discerning on when to attempt suggesting a comma in a macro invocation --- src/libsyntax/tokenstream.rs | 8 +++++--- src/test/ui/macros/missing-comma.rs | 7 +++++++ src/test/ui/macros/missing-comma.stderr | 21 +++++++++++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 4ce308d015c..5caa59a53f9 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -178,9 +178,11 @@ impl TokenStream { while let Some((pos, ts)) = iter.next() { if let Some((_, next)) = iter.peek() { let sp = match (&ts, &next) { - ((TokenTree::Token(_, token::Token::Comma), NonJoint), _) | - (_, (TokenTree::Token(_, token::Token::Comma), NonJoint)) => continue, - ((TokenTree::Token(sp, _), NonJoint), _) => *sp, + (_, (TokenTree::Token(_, token::Token::Comma), _)) => continue, + ((TokenTree::Token(sp, token_left), NonJoint), + (TokenTree::Token(_, token_right), _)) + if token_left.is_ident() || token_left.is_lit() && + token_right.is_ident() || token_right.is_lit() => *sp, ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), _ => continue, }; diff --git a/src/test/ui/macros/missing-comma.rs b/src/test/ui/macros/missing-comma.rs index 1e146875bcc..2b411aba8a2 100644 --- a/src/test/ui/macros/missing-comma.rs +++ b/src/test/ui/macros/missing-comma.rs @@ -6,6 +6,11 @@ macro_rules! foo { ($a:ident, $b:ident, $c:ident, $d:ident, $e:ident) => (); } +macro_rules! bar { + ($lvl:expr, $($arg:tt)+) => {} +} + + fn main() { println!("{}" a); //~^ ERROR expected token: `,` @@ -17,4 +22,6 @@ fn main() { //~^ ERROR no rules expected the token `d` foo!(a, b, c d e); //~^ ERROR no rules expected the token `d` + bar!(Level::Error, ); + //~^ ERROR unexpected end of macro invocation } diff --git a/src/test/ui/macros/missing-comma.stderr b/src/test/ui/macros/missing-comma.stderr index 5881e0b7b68..424fefd00f8 100644 --- a/src/test/ui/macros/missing-comma.stderr +++ b/src/test/ui/macros/missing-comma.stderr @@ -1,11 +1,11 @@ error: expected token: `,` - --> $DIR/missing-comma.rs:10:19 + --> $DIR/missing-comma.rs:15:19 | LL | println!("{}" a); | ^ error: no rules expected the token `b` - --> $DIR/missing-comma.rs:12:12 + --> $DIR/missing-comma.rs:17:12 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -16,7 +16,7 @@ LL | foo!(a b); | help: missing comma here error: no rules expected the token `e` - --> $DIR/missing-comma.rs:14:21 + --> $DIR/missing-comma.rs:19:21 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -27,7 +27,7 @@ LL | foo!(a, b, c, d e); | help: missing comma here error: no rules expected the token `d` - --> $DIR/missing-comma.rs:16:18 + --> $DIR/missing-comma.rs:21:18 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -38,7 +38,7 @@ LL | foo!(a, b, c d, e); | help: missing comma here error: no rules expected the token `d` - --> $DIR/missing-comma.rs:18:18 + --> $DIR/missing-comma.rs:23:18 | LL | macro_rules! foo { | ---------------- when calling this macro @@ -46,5 +46,14 @@ LL | macro_rules! foo { LL | foo!(a, b, c d e); | ^ no rules expected this token in macro call -error: aborting due to 5 previous errors +error: unexpected end of macro invocation + --> $DIR/missing-comma.rs:25:23 + | +LL | macro_rules! bar { + | ---------------- when calling this macro +... +LL | bar!(Level::Error, ); + | ^ missing tokens in macro arguments + +error: aborting due to 6 previous errors From 27abd52170b2d2769f5fbed665795bdb9a3facef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 13 Mar 2019 00:10:16 -0700 Subject: [PATCH 08/15] Fix operator precedence --- src/libsyntax/tokenstream.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 5caa59a53f9..80a7bde606a 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -181,8 +181,8 @@ impl TokenStream { (_, (TokenTree::Token(_, token::Token::Comma), _)) => continue, ((TokenTree::Token(sp, token_left), NonJoint), (TokenTree::Token(_, token_right), _)) - if token_left.is_ident() || token_left.is_lit() && - token_right.is_ident() || token_right.is_lit() => *sp, + if (token_left.is_ident() || token_left.is_lit()) && + (token_right.is_ident() || token_right.is_lit()) => *sp, ((TokenTree::Delimited(sp, ..), NonJoint), _) => sp.entire(), _ => continue, }; From 4e5692d9858d298f27757579688c71ba494cb5c3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 18 Jan 2019 12:18:57 +0100 Subject: [PATCH 09/15] test that wildcard type `_` is not duplicated by `type Foo = (X, X);` and potentially instantiated at different types. (Updated to reflect changes in diagnostic output and compiletest infrastructure.) --- ...ssue-55748-pat-types-constrain-bindings.rs | 70 +++++++++++++++++++ ...-55748-pat-types-constrain-bindings.stderr | 29 ++++++++ 2 files changed, 99 insertions(+) create mode 100644 src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs create mode 100644 src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr diff --git a/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs new file mode 100644 index 00000000000..3d042d442d5 --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.rs @@ -0,0 +1,70 @@ +// This test is ensuring that type ascriptions on let bindings +// constrain both: +// +// 1. the input expression on the right-hand side (after any potential +// coercion, and allowing for covariance), *and* +// +// 2. the bindings (if any) nested within the pattern on the left-hand +// side (and here, the type-constraint is *invariant*). + +#![feature(nll)] + +#![allow(dead_code, unused_mut)] +type PairUncoupled<'a, 'b, T> = (&'a T, &'b T); +type PairCoupledRegions<'a, T> = (&'a T, &'a T); +type PairCoupledTypes = (T, T); + +fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((mut y, mut _z),): (PairUncoupled,) = ((s, &_x),); // ok + // Above compiling does *not* imply below would compile. + // ::std::mem::swap(&mut y, &mut _z); + y +} + +fn swap_regions((mut y, mut _z): PairCoupledRegions) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledRegions,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_regions((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn swap_types((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<&u32>,) = ((s, &_x),); + // If above line compiled, so should line below ... + + // swap_types((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn swap_wilds((mut y, mut _z): PairCoupledTypes<&u32>) { + ::std::mem::swap(&mut y, &mut _z); +} + +fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + let ((y, _z),): (PairCoupledTypes<_>,) = ((s, &_x),); + // If above line compiled, so should line below + // swap_wilds((y, _z)); + + // ... but the ascribed type also invalidates this use of `y` + y //~ ERROR lifetime may not live long enough +} + +fn main() { + uncoupled_lhs(&3, &4); + coupled_regions_lhs(&3, &4); + coupled_types_lhs(&3, &4); + coupled_wilds_lhs(&3, &4); +} diff --git a/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr new file mode 100644 index 00000000000..5929707e41e --- /dev/null +++ b/src/test/ui/nll/user-annotations/issue-55748-pat-types-constrain-bindings.stderr @@ -0,0 +1,29 @@ +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:35:5 + | +LL | fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:49:5 + | +LL | fn coupled_types_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: lifetime may not live long enough + --> $DIR/issue-55748-pat-types-constrain-bindings.rs:62:5 + | +LL | fn coupled_wilds_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 { + | -- lifetime `'a` defined here +... +LL | y + | ^ returning this value requires that `'a` must outlive `'static` + +error: aborting due to 3 previous errors + From 98b26728e0627ef417599497e2355e784a1e9f9c Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 17 Mar 2019 11:55:56 +0100 Subject: [PATCH 10/15] update mailmap for Bastian Kauschke --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index a928606b693..5f2f9c89955 100644 --- a/.mailmap +++ b/.mailmap @@ -29,6 +29,7 @@ Ariel Ben-Yehuda Ariel Ben-Yehuda Ariel Ben-Yehuda arielb1 Austin Seipp Aydin Kim aydin.kim +Bastian Kauschke Barosl Lee Barosl LEE Ben Alpert Ben Sago Ben S From 698bbe52533e8ef07793b6a696cc89015a9dc7f6 Mon Sep 17 00:00:00 2001 From: Vincent Esche Date: Mon, 18 Mar 2019 13:57:51 +0100 Subject: [PATCH 11/15] =?UTF-8?q?Replaced=20self-reflective=20explicit=20t?= =?UTF-8?q?ypes=20with=20clearer=20`Self`=20or=20`Self::=E2=80=A6`=20in=20?= =?UTF-8?q?stdlib=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libcore/cmp.rs | 14 +++++----- src/libcore/iter/mod.rs | 2 +- src/libcore/iter/traits/collect.rs | 2 +- src/libcore/iter/traits/exact_size.rs | 2 +- src/libcore/ops/arith.rs | 40 +++++++++++++-------------- src/libcore/ops/bit.rs | 16 +++++------ src/libcore/ops/deref.rs | 6 ++-- src/libcore/ops/index.rs | 6 ++-- 8 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 7de94d25c76..ea52b0ea721 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -72,7 +72,7 @@ use self::Ordering::*; /// } /// /// impl PartialEq for Book { -/// fn eq(&self, other: &Book) -> bool { +/// fn eq(&self, other: &Self) -> bool { /// self.isbn == other.isbn /// } /// } @@ -233,7 +233,7 @@ pub trait PartialEq { /// format: BookFormat, /// } /// impl PartialEq for Book { -/// fn eq(&self, other: &Book) -> bool { +/// fn eq(&self, other: &Self) -> bool { /// self.isbn == other.isbn /// } /// } @@ -493,19 +493,19 @@ impl Ord for Reverse { /// } /// /// impl Ord for Person { -/// fn cmp(&self, other: &Person) -> Ordering { +/// fn cmp(&self, other: &Self) -> Ordering { /// self.height.cmp(&other.height) /// } /// } /// /// impl PartialOrd for Person { -/// fn partial_cmp(&self, other: &Person) -> Option { +/// fn partial_cmp(&self, other: &Self) -> Option { /// Some(self.cmp(other)) /// } /// } /// /// impl PartialEq for Person { -/// fn eq(&self, other: &Person) -> bool { +/// fn eq(&self, other: &Self) -> bool { /// self.height == other.height /// } /// } @@ -691,13 +691,13 @@ impl PartialOrd for Ordering { /// } /// /// impl PartialOrd for Person { -/// fn partial_cmp(&self, other: &Person) -> Option { +/// fn partial_cmp(&self, other: &Self) -> Option { /// self.height.partial_cmp(&other.height) /// } /// } /// /// impl PartialEq for Person { -/// fn eq(&self, other: &Person) -> bool { +/// fn eq(&self, other: &Self) -> bool { /// self.height == other.height /// } /// } diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 5dcca7ee0ca..e6a616b6802 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -101,7 +101,7 @@ //! type Item = usize; //! //! // next() is the only required method -//! fn next(&mut self) -> Option { +//! fn next(&mut self) -> Option { //! // Increment our count. This is why we started at zero. //! self.count += 1; //! diff --git a/src/libcore/iter/traits/collect.rs b/src/libcore/iter/traits/collect.rs index 5204f6a6425..cd61ab5c552 100644 --- a/src/libcore/iter/traits/collect.rs +++ b/src/libcore/iter/traits/collect.rs @@ -167,7 +167,7 @@ pub trait FromIterator: Sized { /// // and we'll implement IntoIterator /// impl IntoIterator for MyCollection { /// type Item = i32; -/// type IntoIter = ::std::vec::IntoIter; +/// type IntoIter = ::std::vec::IntoIter; /// /// fn into_iter(self) -> Self::IntoIter { /// self.0.into_iter() diff --git a/src/libcore/iter/traits/exact_size.rs b/src/libcore/iter/traits/exact_size.rs index d6eab40213e..8fc4ac93daa 100644 --- a/src/libcore/iter/traits/exact_size.rs +++ b/src/libcore/iter/traits/exact_size.rs @@ -45,7 +45,7 @@ /// # } /// # impl Iterator for Counter { /// # type Item = usize; -/// # fn next(&mut self) -> Option { +/// # fn next(&mut self) -> Option { /// # self.count += 1; /// # if self.count < 6 { /// # Some(self.count) diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 0252edee231..c5e908d7bb8 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -20,10 +20,10 @@ /// } /// /// impl Add for Point { -/// type Output = Point; +/// type Output = Self; /// -/// fn add(self, other: Point) -> Point { -/// Point { +/// fn add(self, other: Self) -> Self { +/// Self { /// x: self.x + other.x, /// y: self.y + other.y, /// } @@ -50,10 +50,10 @@ /// /// // Notice that the implementation uses the associated type `Output`. /// impl> Add for Point { -/// type Output = Point; +/// type Output = Self; /// -/// fn add(self, other: Point) -> Point { -/// Point { +/// fn add(self, other: Self) -> Self::Output { +/// Self { /// x: self.x + other.x, /// y: self.y + other.y, /// } @@ -158,9 +158,9 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// /// // Notice that the implementation uses the associated type `Output`. /// impl> Sub for Point { -/// type Output = Point; +/// type Output = Self; /// -/// fn sub(self, other: Point) -> Point { +/// fn sub(self, other: Self) -> Self::Output { /// Point { /// x: self.x - other.x, /// y: self.y - other.y, @@ -280,9 +280,9 @@ sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// struct Vector { value: Vec } /// /// impl Mul for Vector { -/// type Output = Vector; +/// type Output = Self; /// -/// fn mul(self, rhs: Scalar) -> Vector { +/// fn mul(self, rhs: Scalar) -> Self::Output { /// Vector { value: self.value.iter().map(|v| v * rhs.value).collect() } /// } /// } @@ -364,7 +364,7 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// // The division of rational numbers is a closed operation. /// type Output = Self; /// -/// fn div(self, rhs: Self) -> Self { +/// fn div(self, rhs: Self) -> Self::Output { /// if rhs.nominator == 0 { /// panic!("Cannot divide by zero-valued `Rational`!"); /// } @@ -404,9 +404,9 @@ mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// struct Vector { value: Vec } /// /// impl Div for Vector { -/// type Output = Vector; +/// type Output = Self; /// -/// fn div(self, rhs: Scalar) -> Vector { +/// fn div(self, rhs: Scalar) -> Self::Output { /// Vector { value: self.value.iter().map(|v| v / rhs.value).collect() } /// } /// } @@ -485,9 +485,9 @@ div_impl_float! { f32 f64 } /// } /// /// impl<'a, T> Rem for SplitSlice<'a, T> { -/// type Output = SplitSlice<'a, T>; +/// type Output = Self; /// -/// fn rem(self, modulus: usize) -> Self { +/// fn rem(self, modulus: usize) -> Self::Output { /// let len = self.slice.len(); /// let rem = len % modulus; /// let start = len - rem; @@ -571,7 +571,7 @@ rem_impl_float! { f32 f64 } /// impl Neg for Sign { /// type Output = Sign; /// -/// fn neg(self) -> Sign { +/// fn neg(self) -> Self::Output { /// match self { /// Sign::Negative => Sign::Positive, /// Sign::Zero => Sign::Zero, @@ -650,8 +650,8 @@ neg_impl_numeric! { isize i8 i16 i32 i64 i128 f32 f64 } /// } /// /// impl AddAssign for Point { -/// fn add_assign(&mut self, other: Point) { -/// *self = Point { +/// fn add_assign(&mut self, other: Self) { +/// *self = Self { /// x: self.x + other.x, /// y: self.y + other.y, /// }; @@ -706,8 +706,8 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// } /// /// impl SubAssign for Point { -/// fn sub_assign(&mut self, other: Point) { -/// *self = Point { +/// fn sub_assign(&mut self, other: Self) { +/// *self = Self { /// x: self.x - other.x, /// y: self.y - other.y, /// }; diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs index 2c9bf248633..c3615bdaafc 100644 --- a/src/libcore/ops/bit.rs +++ b/src/libcore/ops/bit.rs @@ -17,7 +17,7 @@ /// impl Not for Answer { /// type Output = Answer; /// -/// fn not(self) -> Answer { +/// fn not(self) -> Self::Output { /// match self { /// Answer::Yes => Answer::No, /// Answer::No => Answer::Yes @@ -75,7 +75,7 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// type Output = Self; /// /// // rhs is the "right-hand side" of the expression `a & b` -/// fn bitand(self, rhs: Self) -> Self { +/// fn bitand(self, rhs: Self) -> Self::Output { /// Scalar(self.0 & rhs.0) /// } /// } @@ -97,7 +97,7 @@ not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// impl BitAnd for BooleanVector { /// type Output = Self; /// -/// fn bitand(self, BooleanVector(rhs): Self) -> Self { +/// fn bitand(self, BooleanVector(rhs): Self) -> Self::Output { /// let BooleanVector(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect()) @@ -181,7 +181,7 @@ bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// impl BitOr for BooleanVector { /// type Output = Self; /// -/// fn bitor(self, BooleanVector(rhs): Self) -> Self { +/// fn bitor(self, BooleanVector(rhs): Self) -> Self::Output { /// let BooleanVector(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); /// BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect()) @@ -243,7 +243,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// type Output = Self; /// /// // rhs is the "right-hand side" of the expression `a ^ b` -/// fn bitxor(self, rhs: Self) -> Self { +/// fn bitxor(self, rhs: Self) -> Self::Output { /// Scalar(self.0 ^ rhs.0) /// } /// } @@ -265,7 +265,7 @@ bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// impl BitXor for BooleanVector { /// type Output = Self; /// -/// fn bitxor(self, BooleanVector(rhs): Self) -> Self { +/// fn bitxor(self, BooleanVector(rhs): Self) -> Self::Output { /// let BooleanVector(lhs) = self; /// assert_eq!(lhs.len(), rhs.len()); /// BooleanVector(lhs.iter() @@ -355,7 +355,7 @@ bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } /// impl Shl for SpinVector { /// type Output = Self; /// -/// fn shl(self, rhs: usize) -> SpinVector { +/// fn shl(self, rhs: usize) -> Self::Output { /// // Rotate the vector by `rhs` places. /// let (a, b) = self.vec.split_at(rhs); /// let mut spun_vector: Vec = vec![]; @@ -464,7 +464,7 @@ shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 } /// impl Shr for SpinVector { /// type Output = Self; /// -/// fn shr(self, rhs: usize) -> SpinVector { +/// fn shr(self, rhs: usize) -> Self::Output { /// // Rotate the vector by `rhs` places. /// let (a, b) = self.vec.split_at(self.vec.len() - rhs); /// let mut spun_vector: Vec = vec![]; diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs index eb76c2de11b..e44a6c4d2a0 100644 --- a/src/libcore/ops/deref.rs +++ b/src/libcore/ops/deref.rs @@ -49,7 +49,7 @@ /// impl Deref for DerefExample { /// type Target = T; /// -/// fn deref(&self) -> &T { +/// fn deref(&self) -> &Self::Target { /// &self.value /// } /// } @@ -139,13 +139,13 @@ impl Deref for &mut T { /// impl Deref for DerefMutExample { /// type Target = T; /// -/// fn deref(&self) -> &T { +/// fn deref(&self) -> &Self::Target { /// &self.value /// } /// } /// /// impl DerefMut for DerefMutExample { -/// fn deref_mut(&mut self) -> &mut T { +/// fn deref_mut(&mut self) -> &mut Self::Target { /// &mut self.value /// } /// } diff --git a/src/libcore/ops/index.rs b/src/libcore/ops/index.rs index d4ed8614276..3158f58e958 100644 --- a/src/libcore/ops/index.rs +++ b/src/libcore/ops/index.rs @@ -33,7 +33,7 @@ /// impl Index for NucleotideCount { /// type Output = usize; /// -/// fn index(&self, nucleotide: Nucleotide) -> &usize { +/// fn index(&self, nucleotide: Nucleotide) -> &Self::Output { /// match nucleotide { /// Nucleotide::A => &self.a, /// Nucleotide::C => &self.c, @@ -105,7 +105,7 @@ pub trait Index { /// impl Index for Balance { /// type Output = Weight; /// -/// fn index<'a>(&'a self, index: Side) -> &'a Weight { +/// fn index<'a>(&'a self, index: Side) -> &'a Self::Output { /// println!("Accessing {:?}-side of balance immutably", index); /// match index { /// Side::Left => &self.left, @@ -115,7 +115,7 @@ pub trait Index { /// } /// /// impl IndexMut for Balance { -/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Weight { +/// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output { /// println!("Accessing {:?}-side of balance mutably", index); /// match index { /// Side::Left => &mut self.left, From 9d408d972f7cf16162ec3ab35e11c659ccee9566 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 29 Nov 2018 21:50:49 +0300 Subject: [PATCH 12/15] Add todo!() macro The use-case of `todo!()` macro is to be a much easier to type alternative to `unimplemented!()` macro. --- src/libcore/macros.rs | 59 +++++++++++++++++++++++++++++++++++++++++++ src/libstd/lib.rs | 3 ++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index b052f59b0f5..d77936c7ddd 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -559,6 +559,65 @@ macro_rules! unimplemented { ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); } +/// A standardized placeholder for marking unfinished code. +/// +/// This can be useful if you are prototyping and are just looking to have your +/// code typecheck. `todo!` works exactly like `unimplemented!`, there only +/// difference between the two macros is the name. +/// +/// # Panics +/// +/// This will always [panic!](macro.panic.html) +/// +/// # Examples +/// +/// Here's an example of some in-progress code. We have a trait `Foo`: +/// +/// ``` +/// trait Foo { +/// fn bar(&self); +/// fn baz(&self); +/// } +/// ``` +/// +/// We want to implement `Foo` on one of our types, but we also want to work on +/// just `bar()` first. In order for our code to compile, we need to implement +/// `baz()`, so we can use `todo!`: +/// +/// ``` +/// #![feature(todo_macro)] +/// +/// # trait Foo { +/// # fn bar(&self); +/// # fn baz(&self); +/// # } +/// struct MyStruct; +/// +/// impl Foo for MyStruct { +/// fn bar(&self) { +/// // implementation goes here +/// } +/// +/// fn baz(&self) { +/// // let's not worry about implementing baz() for now +/// todo!(); +/// } +/// } +/// +/// fn main() { +/// let s = MyStruct; +/// s.bar(); +/// +/// // we aren't even using baz() yet, so this is fine. +/// } +/// ``` +#[macro_export] +#[unstable(feature = "todo_macro", issue = "59277")] +macro_rules! todo { + () => (panic!("not yet implemented")); + ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*))); +} + /// A macro to create an array of [`MaybeUninit`] /// /// This macro constructs an uninitialized array of the type `[MaybeUninit; N]`. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index fc8ac9a0b3e..296c4c88727 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -301,6 +301,7 @@ #![feature(stmt_expr_attributes)] #![feature(str_internals)] #![feature(thread_local)] +#![feature(todo_macro)] #![feature(toowned_clone_into)] #![feature(try_reserve)] #![feature(unboxed_closures)] @@ -323,7 +324,7 @@ use prelude::v1::*; #[stable(feature = "rust1", since = "1.0.0")] pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne}; #[stable(feature = "rust1", since = "1.0.0")] -pub use core::{unreachable, unimplemented, write, writeln, r#try}; +pub use core::{unreachable, unimplemented, write, writeln, r#try, todo}; #[allow(unused_imports)] // macros from `alloc` are not used on all platforms #[macro_use] From de4be2cd85b5c8b707185d0e1f10b3373be0a3d5 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Mon, 18 Mar 2019 12:01:16 -0700 Subject: [PATCH 13/15] Stabilize refcell_map_split feature - Closes #51476 --- src/libcore/cell.rs | 6 ++---- src/libcore/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 8383d305518..753f10e6a0a 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1186,7 +1186,6 @@ impl<'b, T: ?Sized> Ref<'b, T> { /// # Examples /// /// ``` - /// #![feature(refcell_map_split)] /// use std::cell::{Ref, RefCell}; /// /// let cell = RefCell::new([1, 2, 3, 4]); @@ -1195,7 +1194,7 @@ impl<'b, T: ?Sized> Ref<'b, T> { /// assert_eq!(*begin, [1, 2]); /// assert_eq!(*end, [3, 4]); /// ``` - #[unstable(feature = "refcell_map_split", issue = "51476")] + #[stable(feature = "refcell_map_split", since = "1.35.0")] #[inline] pub fn map_split(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>) where F: FnOnce(&T) -> (&U, &V) @@ -1268,7 +1267,6 @@ impl<'b, T: ?Sized> RefMut<'b, T> { /// # Examples /// /// ``` - /// #![feature(refcell_map_split)] /// use std::cell::{RefCell, RefMut}; /// /// let cell = RefCell::new([1, 2, 3, 4]); @@ -1279,7 +1277,7 @@ impl<'b, T: ?Sized> RefMut<'b, T> { /// begin.copy_from_slice(&[4, 3]); /// end.copy_from_slice(&[2, 1]); /// ``` - #[unstable(feature = "refcell_map_split", issue = "51476")] + #[stable(feature = "refcell_map_split", since = "1.35.0")] #[inline] pub fn map_split( orig: RefMut<'b, T>, f: F diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index a50310e195f..08dda4bcc3d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -16,7 +16,6 @@ #![feature(pattern)] #![feature(range_is_empty)] #![feature(raw)] -#![feature(refcell_map_split)] #![feature(refcell_replace_swap)] #![feature(slice_patterns)] #![feature(sort_internals)] From 8f261a6abe874f504c07d2aec937778a2f6df2a3 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Tue, 19 Mar 2019 08:49:45 +0100 Subject: [PATCH 14/15] Update since annotation for ExactSizeIterator for ToUppercase/Lowercase This functionality was added in 1.35.0, not 1.34.0. --- src/libcore/char/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index 95b7c066793..2191ce08b90 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -397,7 +397,7 @@ impl Iterator for ToLowercase { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToLowercase {} -#[stable(feature = "exact_size_case_mapping_iter", since = "1.34.0")] +#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] impl ExactSizeIterator for ToLowercase {} /// Returns an iterator that yields the uppercase equivalent of a `char`. @@ -425,7 +425,7 @@ impl Iterator for ToUppercase { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for ToUppercase {} -#[stable(feature = "exact_size_case_mapping_iter", since = "1.34.0")] +#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")] impl ExactSizeIterator for ToUppercase {} #[derive(Debug, Clone)] From ab41023fd49ef7776b6bf50be113e4063312a7c5 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 19 Mar 2019 12:38:18 +0100 Subject: [PATCH 15/15] Run branch cleanup after copy prop --- src/librustc_mir/transform/mod.rs | 1 + src/test/mir-opt/simplify_match.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 src/test/mir-opt/simplify_match.rs diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 0cd2cecf39c..8df0d72407b 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -285,6 +285,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx &simplify_branches::SimplifyBranches::new("after-const-prop"), &deaggregator::Deaggregator, ©_prop::CopyPropagation, + &simplify_branches::SimplifyBranches::new("after-copy-prop"), &remove_noop_landing_pads::RemoveNoopLandingPads, &simplify::SimplifyCfg::new("final"), &simplify::SimplifyLocals, diff --git a/src/test/mir-opt/simplify_match.rs b/src/test/mir-opt/simplify_match.rs new file mode 100644 index 00000000000..0192aa01d01 --- /dev/null +++ b/src/test/mir-opt/simplify_match.rs @@ -0,0 +1,22 @@ +fn main() { + match { let x = false; x } { + true => println!("hello world!"), + false => {}, + } +} + +// END RUST SOURCE +// START rustc.main.SimplifyBranches-after-copy-prop.before.mir +// bb0: { +// ... +// switchInt(const false) -> [false: bb3, otherwise: bb1]; +// } +// bb1: { +// END rustc.main.SimplifyBranches-after-copy-prop.before.mir +// START rustc.main.SimplifyBranches-after-copy-prop.after.mir +// bb0: { +// ... +// goto -> bb3; +// } +// bb1: { +// END rustc.main.SimplifyBranches-after-copy-prop.after.mir