Auto merge of #59293 - Centril:rollup, r=Centril

Rollup of 11 pull requests

Successful merges:

 - #56348 (Add todo!() macro)
 - #57729 (extra testing of how NLL handles wildcard type `_`)
 - #57847 (dbg!() without parameters)
 - #58778 (Implement ExactSizeIterator for ToLowercase and ToUppercase)
 - #58812 (Clarify distinction between floor() and trunc())
 - #58939 (Fix a tiny error in documentation of std::pin.)
 - #59116 (Be more discerning on when to attempt suggesting a comma in a macro invocation)
 - #59252 (add self to mailmap)
 - #59275 (Replaced self-reflective explicit types with clearer `Self` or `Self::…` in stdlib docs)
 - #59280 (Stabilize refcell_map_split feature)
 - #59290 (Run branch cleanup after copy prop)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-03-19 14:30:42 +00:00
commit 7a4df3b53d
27 changed files with 315 additions and 72 deletions

View File

@ -29,6 +29,7 @@ Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> Ariel Ben-Yehuda <ariel.byd@gmail.com>
Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> arielb1 <arielb1@mail.tau.ac.il>
Austin Seipp <mad.one@gmail.com> <as@hacks.yi.org>
Aydin Kim <ladinjin@hanmail.net> aydin.kim <aydin.kim@samsung.com>
Bastian Kauschke <bastian_kauschke@hotmail.de>
Barosl Lee <vcs@barosl.com> Barosl LEE <github@barosl.com>
Ben Alpert <ben@benalpert.com> <spicyjalapeno@gmail.com>
Ben Sago <ogham@users.noreply.github.com> Ben S <ogham@bsago.me>

View File

@ -1186,7 +1186,6 @@ pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
/// # Examples
///
/// ```
/// #![feature(refcell_map_split)]
/// use std::cell::{Ref, RefCell};
///
/// let cell = RefCell::new([1, 2, 3, 4]);
@ -1195,7 +1194,7 @@ pub fn map<U: ?Sized, F>(orig: Ref<'b, T>, f: F) -> Ref<'b, U>
/// 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<U: ?Sized, V: ?Sized, F>(orig: Ref<'b, T>, f: F) -> (Ref<'b, U>, Ref<'b, V>)
where F: FnOnce(&T) -> (&U, &V)
@ -1268,7 +1267,6 @@ pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
/// # Examples
///
/// ```
/// #![feature(refcell_map_split)]
/// use std::cell::{RefCell, RefMut};
///
/// let cell = RefCell::new([1, 2, 3, 4]);
@ -1279,7 +1277,7 @@ pub fn map<U: ?Sized, F>(orig: RefMut<'b, T>, f: F) -> RefMut<'b, U>
/// 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<U: ?Sized, V: ?Sized, F>(
orig: RefMut<'b, T>, f: F

View File

@ -389,11 +389,17 @@ impl Iterator for ToLowercase {
fn next(&mut self) -> Option<char> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToLowercase {}
#[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`.
///
/// 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<char> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToUppercase {}
#[stable(feature = "exact_size_case_mapping_iter", since = "1.35.0")]
impl ExactSizeIterator for ToUppercase {}
#[derive(Debug, Clone)]
enum CaseMappingIter {
Three(char, char, char),
@ -457,6 +469,16 @@ fn next(&mut self) -> Option<char> {
CaseMappingIter::Zero => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let size = match self {
CaseMappingIter::Three(..) => 3,
CaseMappingIter::Two(..) => 2,
CaseMappingIter::One(_) => 1,
CaseMappingIter::Zero => 0,
};
(size, Some(size))
}
}
impl fmt::Display for CaseMappingIter {

View File

@ -72,7 +72,7 @@
/// }
///
/// impl PartialEq for Book {
/// fn eq(&self, other: &Book) -> bool {
/// fn eq(&self, other: &Self) -> bool {
/// self.isbn == other.isbn
/// }
/// }
@ -233,7 +233,7 @@ fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
/// 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 @@ fn cmp(&self, other: &Reverse<T>) -> Ordering {
/// }
///
/// 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<Ordering> {
/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// 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 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
/// }
///
/// impl PartialOrd for Person {
/// fn partial_cmp(&self, other: &Person) -> Option<Ordering> {
/// fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
/// 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
/// }
/// }

View File

@ -101,7 +101,7 @@
//! type Item = usize;
//!
//! // next() is the only required method
//! fn next(&mut self) -> Option<usize> {
//! fn next(&mut self) -> Option<Self::Item> {
//! // Increment our count. This is why we started at zero.
//! self.count += 1;
//!

View File

@ -167,7 +167,7 @@ pub trait FromIterator<A>: Sized {
/// // and we'll implement IntoIterator
/// impl IntoIterator for MyCollection {
/// type Item = i32;
/// type IntoIter = ::std::vec::IntoIter<i32>;
/// type IntoIter = ::std::vec::IntoIter<Self::Item>;
///
/// fn into_iter(self) -> Self::IntoIter {
/// self.0.into_iter()

View File

@ -45,7 +45,7 @@
/// # }
/// # impl Iterator for Counter {
/// # type Item = usize;
/// # fn next(&mut self) -> Option<usize> {
/// # fn next(&mut self) -> Option<Self::Item> {
/// # self.count += 1;
/// # if self.count < 6 {
/// # Some(self.count)

View File

@ -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<K>; N]`.

View File

@ -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<T: Add<Output = T>> Add for Point<T> {
/// type Output = Point<T>;
/// type Output = Self;
///
/// fn add(self, other: Point<T>) -> Point<T> {
/// Point {
/// fn add(self, other: Self) -> Self::Output {
/// Self {
/// x: self.x + other.x,
/// y: self.y + other.y,
/// }
@ -158,9 +158,9 @@ fn add(self, other: $t) -> $t { self + other }
///
/// // Notice that the implementation uses the associated type `Output`.
/// impl<T: Sub<Output = T>> Sub for Point<T> {
/// type Output = Point<T>;
/// type Output = Self;
///
/// fn sub(self, other: Point<T>) -> Point<T> {
/// fn sub(self, other: Self) -> Self::Output {
/// Point {
/// x: self.x - other.x,
/// y: self.y - other.y,
@ -280,9 +280,9 @@ fn sub(self, other: $t) -> $t { self - other }
/// struct Vector { value: Vec<usize> }
///
/// impl Mul<Scalar> 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 @@ fn mul(self, other: $t) -> $t { self * other }
/// // 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 @@ fn mul(self, other: $t) -> $t { self * other }
/// struct Vector { value: Vec<f32> }
///
/// impl Div<Scalar> 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 @@ fn div(self, other: $t) -> $t { self / other }
/// }
///
/// impl<'a, T> Rem<usize> 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 @@ fn rem(self, other: $t) -> $t { self % other }
/// 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 @@ macro_rules! neg_impl_unsigned {
/// }
///
/// 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 @@ fn add_assign(&mut self, other: $t) { *self += other }
/// }
///
/// 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,
/// };

View File

@ -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 @@ fn not(self) -> $t { !self }
/// 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 @@ fn not(self) -> $t { !self }
/// 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 @@ fn bitand(self, rhs: $t) -> $t { self & rhs }
/// 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 @@ fn bitor(self, rhs: $t) -> $t { self | rhs }
/// 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 @@ fn bitor(self, rhs: $t) -> $t { self | rhs }
/// 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 @@ fn bitxor(self, other: $t) -> $t { self ^ other }
/// impl<T: Clone> Shl<usize> for SpinVector<T> {
/// type Output = Self;
///
/// fn shl(self, rhs: usize) -> SpinVector<T> {
/// 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<T> = vec![];
@ -464,7 +464,7 @@ macro_rules! shl_impl_all {
/// impl<T: Clone> Shr<usize> for SpinVector<T> {
/// type Output = Self;
///
/// fn shr(self, rhs: usize) -> SpinVector<T> {
/// 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<T> = vec![];

View File

@ -49,7 +49,7 @@
/// impl<T> Deref for DerefExample<T> {
/// type Target = T;
///
/// fn deref(&self) -> &T {
/// fn deref(&self) -> &Self::Target {
/// &self.value
/// }
/// }
@ -139,13 +139,13 @@ fn deref(&self) -> &T { *self }
/// impl<T> Deref for DerefMutExample<T> {
/// type Target = T;
///
/// fn deref(&self) -> &T {
/// fn deref(&self) -> &Self::Target {
/// &self.value
/// }
/// }
///
/// impl<T> DerefMut for DerefMutExample<T> {
/// fn deref_mut(&mut self) -> &mut T {
/// fn deref_mut(&mut self) -> &mut Self::Target {
/// &mut self.value
/// }
/// }

View File

@ -33,7 +33,7 @@
/// impl Index<Nucleotide> 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<Idx: ?Sized> {
/// impl Index<Side> 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<Idx: ?Sized> {
/// }
///
/// impl IndexMut<Side> 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,

View File

@ -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);
//! ```
//!

View File

@ -76,6 +76,8 @@ fn test_to_digit() {
#[test]
fn test_to_lowercase() {
fn lower(c: char) -> String {
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();
assert_eq!(iter, disp);
@ -101,6 +103,8 @@ fn lower(c: char) -> String {
#[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);

View File

@ -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)]

View File

@ -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,
&copy_prop::CopyPropagation,
&simplify_branches::SimplifyBranches::new("after-copy-prop"),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("final"),
&simplify::SimplifyLocals,

View File

@ -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 @@ pub fn round(self) -> 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]

View File

@ -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 @@ pub fn round(self) -> 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]

View File

@ -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 @@
#[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]

View File

@ -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

View File

@ -178,9 +178,11 @@ pub(crate) fn add_comma(&self) -> Option<(TokenStream, Span)> {
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,
};

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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, T);
fn uncoupled_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
let ((mut y, mut _z),): (PairUncoupled<u32>,) = ((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<u32>) {
::std::mem::swap(&mut y, &mut _z);
}
fn coupled_regions_lhs<'a>(_x: &'a u32, s: &'static u32) -> &'static u32 {
let ((y, _z),): (PairCoupledRegions<u32>,) = ((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);
}

View File

@ -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

View File

@ -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<String>) {
" 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",
]);
}