From 4af560ecefe7c092f9584e20e43800b52bee4795 Mon Sep 17 00:00:00 2001 From: Alexis Bourget <alexis.bourget@gmail.com> Date: Mon, 14 Sep 2020 23:35:46 +0200 Subject: [PATCH 01/24] Move zero-sized-vec-push test --- library/alloc/tests/vec.rs | 17 ++++++++++++++++ src/test/ui/zero-sized/zero-sized-vec-push.rs | 20 ------------------- 2 files changed, 17 insertions(+), 20 deletions(-) delete mode 100644 src/test/ui/zero-sized/zero-sized-vec-push.rs diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 771a293b8e5d4..34995d7e40f21 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1912,3 +1912,20 @@ fn test_vec_cycle_wrapped() { c3.refs.v[0].set(Some(&c1)); c3.refs.v[1].set(Some(&c2)); } + +#[test] +fn test_zero_sized_vec_push() { + const N: usize = 8; + + for len in 0..N { + let mut tester = Vec::with_capacity(len); + assert_eq!(tester.len(), 0); + assert!(tester.capacity() >= len); + for _ in 0..len { + tester.push(()); + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } +} diff --git a/src/test/ui/zero-sized/zero-sized-vec-push.rs b/src/test/ui/zero-sized/zero-sized-vec-push.rs deleted file mode 100644 index 9e9fbc972d5c1..0000000000000 --- a/src/test/ui/zero-sized/zero-sized-vec-push.rs +++ /dev/null @@ -1,20 +0,0 @@ -// run-pass -#![allow(unused_variables)] -use std::iter::Iterator; -use std::vec::Vec; - -fn main() { - const N: usize = 8; - - for len in 0..N { - let mut tester = Vec::with_capacity(len); - assert_eq!(tester.len(), 0); - assert!(tester.capacity() >= len); - for bit in 0..len { - tester.push(()); - } - assert_eq!(tester.len(), len); - assert_eq!(tester.iter().count(), len); - tester.clear(); - } -} From 85afbd8a15a7e37b35a0653693bd6acf3138f301 Mon Sep 17 00:00:00 2001 From: Alexis Bourget <alexis.bourget@gmail.com> Date: Sat, 17 Oct 2020 18:47:58 +0200 Subject: [PATCH 02/24] Rebase conflicts --- library/alloc/tests/vec_deque.rs | 30 +++++++++++++++++ .../zero-sized/zero-sized-vec-deque-push.rs | 32 ------------------- 2 files changed, 30 insertions(+), 32 deletions(-) delete mode 100644 src/test/ui/zero-sized/zero-sized-vec-deque-push.rs diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 05cb3a2c03d79..705f0d62fbb7a 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1698,3 +1698,33 @@ fn test_binary_search_by_key() { assert_eq!(deque.binary_search_by_key(&3, |&(v,)| v), Ok(2)); assert_eq!(deque.binary_search_by_key(&4, |&(v,)| v), Err(3)); } + +#[test] +fn test_zero_sized_push() { + const N: usize = 8; + + // Zero sized type + struct Zst; + + // Test that for all possible sequences of push_front / push_back, + // we end up with a deque of the correct size + + for len in 0..N { + let mut tester = VecDeque::with_capacity(len); + assert_eq!(tester.len(), 0); + assert!(tester.capacity() >= len); + for case in 0..(1 << len) { + assert_eq!(tester.len(), 0); + for bit in 0..len { + if case & (1 << bit) != 0 { + tester.push_front(Zst); + } else { + tester.push_back(Zst); + } + } + assert_eq!(tester.len(), len); + assert_eq!(tester.iter().count(), len); + tester.clear(); + } + } +} diff --git a/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs b/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs deleted file mode 100644 index c541208703b6b..0000000000000 --- a/src/test/ui/zero-sized/zero-sized-vec-deque-push.rs +++ /dev/null @@ -1,32 +0,0 @@ -// run-pass -use std::collections::VecDeque; -use std::iter::Iterator; - -fn main() { - const N: usize = 8; - - // Zero sized type - struct Zst; - - // Test that for all possible sequences of push_front / push_back, - // we end up with a deque of the correct size - - for len in 0..N { - let mut tester = VecDeque::with_capacity(len); - assert_eq!(tester.len(), 0); - assert!(tester.capacity() >= len); - for case in 0..(1 << len) { - assert_eq!(tester.len(), 0); - for bit in 0..len { - if case & (1 << bit) != 0 { - tester.push_front(Zst); - } else { - tester.push_back(Zst); - } - } - assert_eq!(tester.len(), len); - assert_eq!(tester.iter().count(), len); - tester.clear(); - } - } -} From 4fd06b9bb566aa444fb293bbe7ef1eef71bc1e08 Mon Sep 17 00:00:00 2001 From: Alexis Bourget <alexis.bourget@gmail.com> Date: Sat, 3 Oct 2020 18:49:23 +0200 Subject: [PATCH 03/24] Move vec-macro-repeat test --- library/alloc/tests/vec.rs | 13 +++++++++++++ src/test/ui/array-slice-vec/vec-macro-repeat.rs | 15 --------------- 2 files changed, 13 insertions(+), 15 deletions(-) delete mode 100644 src/test/ui/array-slice-vec/vec-macro-repeat.rs diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 34995d7e40f21..ae7518bcad0e2 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1929,3 +1929,16 @@ fn test_zero_sized_vec_push() { tester.clear(); } } + +#[test] +fn test_vec_macro_repeat() { + assert_eq!(vec![1; 3], vec![1, 1, 1]); + assert_eq!(vec![1; 2], vec![1, 1]); + assert_eq!(vec![1; 1], vec![1]); + assert_eq!(vec![1; 0], vec![]); + + // from_elem syntax (see RFC 832) + let el = Box::new(1); + let n = 3; + assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); +} diff --git a/src/test/ui/array-slice-vec/vec-macro-repeat.rs b/src/test/ui/array-slice-vec/vec-macro-repeat.rs deleted file mode 100644 index 7be8dadbe170e..0000000000000 --- a/src/test/ui/array-slice-vec/vec-macro-repeat.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - - - -pub fn main() { - assert_eq!(vec![1; 3], vec![1, 1, 1]); - assert_eq!(vec![1; 2], vec![1, 1]); - assert_eq!(vec![1; 1], vec![1]); - assert_eq!(vec![1; 0], vec![]); - - // from_elem syntax (see RFC 832) - let el = Box::new(1); - let n = 3; - assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); -} From 42271a537a7a833c7ed448297b48be3bbc98de8c Mon Sep 17 00:00:00 2001 From: Alexis Bourget <alexis.bourget@gmail.com> Date: Sat, 3 Oct 2020 19:03:38 +0200 Subject: [PATCH 04/24] Move vec swap test --- library/alloc/tests/vec.rs | 14 +++++++++++++- src/test/ui/swap-2.rs | 14 -------------- 2 files changed, 13 insertions(+), 15 deletions(-) delete mode 100644 src/test/ui/swap-2.rs diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index ae7518bcad0e2..47ebe56f9fd3b 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -3,7 +3,7 @@ use std::cell::Cell; use std::collections::TryReserveError::*; use std::fmt::Debug; use std::iter::InPlaceIterable; -use std::mem::size_of; +use std::mem::{size_of, swap}; use std::ops::Bound::*; use std::panic::{catch_unwind, AssertUnwindSafe}; use std::rc::Rc; @@ -1942,3 +1942,15 @@ fn test_vec_macro_repeat() { let n = 3; assert_eq!(vec![el; n], vec![Box::new(1), Box::new(1), Box::new(1)]); } + +#[test] +fn test_vec_swap() { + let mut a: Vec<isize> = vec![0, 1, 2, 3, 4, 5, 6]; + a.swap(2, 4); + assert_eq!(a[2], 4); + assert_eq!(a[4], 2); + let mut n = 42; + swap(&mut n, &mut a[0]); + assert_eq!(a[0], 42); + assert_eq!(n, 0); +} diff --git a/src/test/ui/swap-2.rs b/src/test/ui/swap-2.rs deleted file mode 100644 index c8f298ec0e5cb..0000000000000 --- a/src/test/ui/swap-2.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -use std::mem::swap; - -pub fn main() { - let mut a: Vec<isize> = vec![0, 1, 2, 3, 4, 5, 6]; - a.swap(2, 4); - assert_eq!(a[2], 4); - assert_eq!(a[4], 2); - let mut n = 42; - swap(&mut n, &mut a[0]); - assert_eq!(a[0], 42); - assert_eq!(n, 0); -} From 1bdee96c5e6de445f09df34447a42553294f21ed Mon Sep 17 00:00:00 2001 From: Alexis Bourget <alexis.bourget@gmail.com> Date: Sat, 3 Oct 2020 19:19:50 +0200 Subject: [PATCH 05/24] Move subslice pattern tests to alloc/tests/slice.rs --- library/alloc/tests/slice.rs | 120 +++++++++++++++++ .../array-slice-vec/subslice-patterns-pass.rs | 126 ------------------ 2 files changed, 120 insertions(+), 126 deletions(-) delete mode 100644 src/test/ui/array-slice-vec/subslice-patterns-pass.rs diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs index 1f561bebd908b..a4f0fb415fb3c 100644 --- a/library/alloc/tests/slice.rs +++ b/library/alloc/tests/slice.rs @@ -1,5 +1,6 @@ use std::cell::Cell; use std::cmp::Ordering::{self, Equal, Greater, Less}; +use std::convert::identity; use std::mem; use std::panic; use std::rc::Rc; @@ -1778,3 +1779,122 @@ fn repeat_generic_slice() { assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]); assert_eq!([1, 2, 3, 4].repeat(3), vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]); } + +#[test] +#[allow(unreachable_patterns)] +fn subslice_patterns() { + // This test comprehensively checks the passing static and dynamic semantics + // of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..` + // in slice patterns `[$($pat), $(,)?]` . + + #[derive(PartialEq, Debug, Clone)] + struct N(u8); + + macro_rules! n { + ($($e:expr),* $(,)?) => { + [$(N($e)),*] + } + } + + macro_rules! c { + ($inp:expr, $typ:ty, $out:expr $(,)?) => { + assert_eq!($out, identity::<$typ>($inp)); + }; + } + + macro_rules! m { + ($e:expr, $p:pat => $b:expr) => { + match $e { + $p => $b, + _ => panic!(), + } + }; + } + + // == Slices == + + // Matching slices using `ref` patterns: + let mut v = vec![N(0), N(1), N(2), N(3), N(4)]; + let mut vc = (0..=4).collect::<Vec<u8>>(); + + let [..] = v[..]; // Always matches. + m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); + m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); + m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); + m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); + m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N])); + m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); + + // Matching slices using `ref mut` patterns: + let [..] = v[..]; // Always matches. + m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); + m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); + m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); + m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); + + // Matching slices using default binding modes (&): + let [..] = &v[..]; // Always matches. + m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); + m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); + m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); + m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); + m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N])); + m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4))); + + // Matching slices using default binding modes (&mut): + let [..] = &mut v[..]; // Always matches. + m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); + m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); + m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); + m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); + m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4))); + + // == Arrays == + let mut v = n![0, 1, 2, 3, 4]; + let vc = [0, 1, 2, 3, 4]; + + // Matching arrays by value: + m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3])); + m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4])); + m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3])); + m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0])); + m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0])); + m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4)))); + m!(v.clone(), [..] => ()); + + // Matching arrays by ref patterns: + m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); + m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); + m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); + m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4))); + + // Matching arrays by ref mut patterns: + m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); + m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); + m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); + m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); + m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); + + // Matching arrays by default binding modes (&): + m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); + m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); + m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); + m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); + m!(&v, [..] => ()); + m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4)))); + + // Matching arrays by default binding modes (&mut): + m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); + m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); + m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); + m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); + m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); + m!(&mut v, [..] => ()); + m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4)))); +} diff --git a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs deleted file mode 100644 index e05790911f52d..0000000000000 --- a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs +++ /dev/null @@ -1,126 +0,0 @@ -// This test comprehensively checks the passing static and dynamic semantics -// of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..` -// in slice patterns `[$($pat), $(,)?]` . - -// run-pass - -#![allow(unreachable_patterns)] - -use std::convert::identity; - -#[derive(PartialEq, Debug, Clone)] -struct N(u8); - -macro_rules! n { - ($($e:expr),* $(,)?) => { - [$(N($e)),*] - } -} - -macro_rules! c { - ($inp:expr, $typ:ty, $out:expr $(,)?) => { - assert_eq!($out, identity::<$typ>($inp)); - } -} - -macro_rules! m { - ($e:expr, $p:pat => $b:expr) => { - match $e { - $p => $b, - _ => panic!(), - } - } -} - -fn main() { - slices(); - arrays(); -} - -fn slices() { - // Matching slices using `ref` patterns: - let mut v = vec![N(0), N(1), N(2), N(3), N(4)]; - let mut vc = (0..=4).collect::<Vec<u8>>(); - - let [..] = v[..]; // Always matches. - m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); - m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); - m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); - m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); - m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N])); - m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); - - // Matching slices using `ref mut` patterns: - let [..] = v[..]; // Always matches. - m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); - m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); - m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); - m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4))); - - // Matching slices using default binding modes (&): - let [..] = &v[..]; // Always matches. - m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3])); - m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4])); - m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3])); - m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N])); - m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N])); - m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4))); - - // Matching slices using default binding modes (&mut): - let [..] = &mut v[..]; // Always matches. - m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3])); - m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4])); - m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3])); - m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N])); - m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4))); -} - -fn arrays() { - let mut v = n![0, 1, 2, 3, 4]; - let vc = [0, 1, 2, 3, 4]; - - // Matching arrays by value: - m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3])); - m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4])); - m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3])); - m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0])); - m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0])); - m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4)))); - m!(v.clone(), [..] => ()); - - // Matching arrays by ref patterns: - m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); - m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); - m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); - m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4))); - - // Matching arrays by ref mut patterns: - m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); - m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); - m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); - m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); - m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0])); - - // Matching arrays by default binding modes (&): - m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3])); - m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4])); - m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3])); - m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0])); - m!(&v, [..] => ()); - m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4)))); - - // Matching arrays by default binding modes (&mut): - m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3])); - m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4])); - m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3])); - m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); - m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0])); - m!(&mut v, [..] => ()); - m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4)))); -} From 20e032e65007ff1376e8480c1fbdb0a5068028fa Mon Sep 17 00:00:00 2001 From: Gus Wynn <guswynn@gmail.com> Date: Tue, 15 Sep 2020 13:14:35 -0700 Subject: [PATCH 06/24] Make it more clear when complaining about async fn's return types --- .../nice_region_error/different_lifetimes.rs | 112 ++++++++++++------ .../error_reporting/nice_region_error/util.rs | 54 +++++++++ .../async-await/issues/issue-63388-1.stderr | 6 +- .../ret-impl-trait-one.stderr | 5 +- src/test/ui/issues/issue-76547.rs | 38 ++++++ src/test/ui/issues/issue-76547.stderr | 25 ++++ ...f_types_pin_lifetime_mismatch-async.stderr | 21 ++-- .../ui/self/elision/lt-ref-self-async.stderr | 42 ++++--- .../ui/self/elision/ref-mut-self-async.stderr | 42 ++++--- .../self/elision/ref-mut-struct-async.stderr | 35 +++--- .../ui/self/elision/ref-self-async.stderr | 49 ++++---- .../ui/self/elision/ref-struct-async.stderr | 35 +++--- 12 files changed, 331 insertions(+), 133 deletions(-) create mode 100644 src/test/ui/issues/issue-76547.rs create mode 100644 src/test/ui/issues/issue-76547.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 7ab18e54f7ea2..59786059fae67 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -102,43 +102,89 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { None => String::new(), }; - let (span_1, span_2, main_label, span_label) = match (sup_is_ret_type, sub_is_ret_type) { - (None, None) => { - let (main_label_1, span_label_1) = if ty_sup.hir_id == ty_sub.hir_id { + let (span_1, span_2, main_label, span_label, future_return_type) = + match (sup_is_ret_type, sub_is_ret_type) { + (None, None) => { + let (main_label_1, span_label_1) = if ty_sup.hir_id == ty_sub.hir_id { + ( + "this type is declared with multiple lifetimes...".to_owned(), + "...but data with one lifetime flows into the other here".to_owned(), + ) + } else { + ( + "these two types are declared with different lifetimes...".to_owned(), + format!("...but data{} flows{} here", span_label_var1, span_label_var2), + ) + }; + (ty_sup.span, ty_sub.span, main_label_1, span_label_1, None) + } + + (Some(ret_span), _) => { + let sup_future = self.future_return_type(scope_def_id_sup); + let (return_type, action) = if let Some(_) = sup_future { + ("returned future", "held across an await point") + } else { + ("return type", "returned") + }; + ( - "this type is declared with multiple lifetimes...".to_owned(), - "...but data with one lifetime flows into the other here".to_owned(), + ty_sub.span, + ret_span, + format!( + "this parameter and the {} are declared with different lifetimes...", + return_type + ), + format!("...but data{} is {} here", span_label_var1, action), + sup_future, ) - } else { + } + (_, Some(ret_span)) => { + let sub_future = self.future_return_type(scope_def_id_sub); + let (return_type, action) = if let Some(_) = sub_future { + ("returned future", "held across an await point") + } else { + ("return type", "returned") + }; + ( - "these two types are declared with different lifetimes...".to_owned(), - format!("...but data{} flows{} here", span_label_var1, span_label_var2), + ty_sup.span, + ret_span, + format!( + "this parameter and the {} are declared with different lifetimes...", + return_type + ), + format!("...but data{} is {} here", span_label_var1, action), + sub_future, ) - }; - (ty_sup.span, ty_sub.span, main_label_1, span_label_1) - } - - (Some(ret_span), _) => ( - ty_sub.span, - ret_span, - "this parameter and the return type are declared with different lifetimes..." - .to_owned(), - format!("...but data{} is returned here", span_label_var1), - ), - (_, Some(ret_span)) => ( - ty_sup.span, - ret_span, - "this parameter and the return type are declared with different lifetimes..." - .to_owned(), - format!("...but data{} is returned here", span_label_var1), - ), - }; - - struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch") - .span_label(span_1, main_label) - .span_label(span_2, String::new()) - .span_label(span, span_label) - .emit(); + } + }; + + let mut e = struct_span_err!(self.tcx().sess, span, E0623, "lifetime mismatch"); + + e.span_label(span_1, main_label); + e.span_label(span_2, String::new()); + e.span_label(span, span_label); + + if let Some(t) = future_return_type { + let snip = self + .tcx() + .sess + .source_map() + .span_to_snippet(t.span) + .ok() + .and_then(|s| match (&t.kind, s.as_str()) { + (rustc_hir::TyKind::Tup(&[]), "") => Some("()".to_string()), + (_, "") => None, + _ => Some(s), + }) + .unwrap_or("{unnamed_type}".to_string()); + + e.span_label( + t.span, + &format!("this `async fn` implicitly returns an `impl Future<Output = {}>`", snip), + ); + } + e.emit(); Some(ErrorReported) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index c055fed43f6d5..ca93b2777ab2a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -85,6 +85,60 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { }) } + pub(super) fn future_return_type( + &self, + local_def_id: LocalDefId, + ) -> Option<&rustc_hir::Ty<'_>> { + if let Some(hir::IsAsync::Async) = self.asyncness(local_def_id) { + if let rustc_middle::ty::Opaque(def_id, _) = + self.tcx().type_of(local_def_id).fn_sig(self.tcx()).output().skip_binder().kind() + { + match self.tcx().hir().get_if_local(*def_id) { + Some(hir::Node::Item(hir::Item { + kind: + hir::ItemKind::OpaqueTy(hir::OpaqueTy { + bounds, + origin: hir::OpaqueTyOrigin::AsyncFn, + .. + }), + .. + })) => { + for b in bounds.iter() { + if let hir::GenericBound::LangItemTrait( + hir::LangItem::Future, + _span, + _hir_id, + generic_args, + ) = b + { + for type_binding in generic_args.bindings.iter() { + if type_binding.ident.name == rustc_span::sym::Output { + if let hir::TypeBindingKind::Equality { ty } = + type_binding.kind + { + return Some(ty); + } + } + } + } + } + } + _ => {} + } + } + } + None + } + + pub(super) fn asyncness(&self, local_def_id: LocalDefId) -> Option<hir::IsAsync> { + // similar to the asyncness fn in rustc_ty::ty + let hir_id = self.tcx().hir().local_def_id_to_hir_id(local_def_id); + let node = self.tcx().hir().get(hir_id); + let fn_like = rustc_middle::hir::map::blocks::FnLikeNode::from_node(node)?; + + Some(fn_like.asyncness()) + } + // Here, we check for the case where the anonymous region // is in the return type. // FIXME(#42703) - Need to handle certain cases here. diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr index 8813183312ddf..ac29cca9d3f60 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -2,12 +2,14 @@ error[E0623]: lifetime mismatch --> $DIR/issue-63388-1.rs:14:9 | LL | &'a self, foo: &dyn Foo - | -------- this parameter and the return type are declared with different lifetimes... + | -------- this parameter and the returned future are declared with different lifetimes... LL | ) -> &dyn Foo | -------- + | | + | this `async fn` implicitly returns an `impl Future<Output = &dyn Foo>` LL | { LL | foo - | ^^^ ...but data from `foo` is returned here + | ^^^ ...but data from `foo` is held across an await point here error: aborting due to previous error diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr index 7b8f290d6c2f8..5041b39a9e9d1 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr @@ -4,8 +4,9 @@ error[E0623]: lifetime mismatch LL | async fn async_ret_impl_trait1<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> { | ------ ^^^^^^^^^^^^^^ | | | - | | ...but data from `b` is returned here - | this parameter and the return type are declared with different lifetimes... + | | ...but data from `b` is held across an await point here + | | this `async fn` implicitly returns an `impl Future<Output = impl Trait<'a>>` + | this parameter and the returned future are declared with different lifetimes... error: aborting due to previous error diff --git a/src/test/ui/issues/issue-76547.rs b/src/test/ui/issues/issue-76547.rs new file mode 100644 index 0000000000000..feec086764a34 --- /dev/null +++ b/src/test/ui/issues/issue-76547.rs @@ -0,0 +1,38 @@ +// Test for for diagnostic improvement issue #76547 +// edition:2018 + +use std::{ + future::Future, + task::{Context, Poll} +}; +use std::pin::Pin; + +pub struct ListFut<'a>(&'a mut [&'a mut [u8]]); +impl<'a> Future for ListFut<'a> { + type Output = (); + + fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> { + unimplemented!() + } +} + +async fn fut(bufs: &mut [&mut [u8]]) { + ListFut(bufs).await + //~^ ERROR lifetime mismatch +} + +pub struct ListFut2<'a>(&'a mut [&'a mut [u8]]); +impl<'a> Future for ListFut2<'a> { + type Output = i32; + + fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> { + unimplemented!() + } +} + +async fn fut2(bufs: &mut [&mut [u8]]) -> i32 { + ListFut2(bufs).await + //~^ ERROR lifetime mismatch +} + +fn main() {} diff --git a/src/test/ui/issues/issue-76547.stderr b/src/test/ui/issues/issue-76547.stderr new file mode 100644 index 0000000000000..9bfb0f28028cb --- /dev/null +++ b/src/test/ui/issues/issue-76547.stderr @@ -0,0 +1,25 @@ +error[E0623]: lifetime mismatch + --> $DIR/issue-76547.rs:20:13 + | +LL | async fn fut(bufs: &mut [&mut [u8]]) { + | --------- - + | | | + | | this `async fn` implicitly returns an `impl Future<Output = ()>` + | this parameter and the returned future are declared with different lifetimes... +LL | ListFut(bufs).await + | ^^^^ ...but data from `bufs` is held across an await point here + +error[E0623]: lifetime mismatch + --> $DIR/issue-76547.rs:34:14 + | +LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 { + | --------- --- + | | | + | | this `async fn` implicitly returns an `impl Future<Output = i32>` + | this parameter and the returned future are declared with different lifetimes... +LL | ListFut2(bufs).await + | ^^^^ ...but data from `bufs` is held across an await point here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr index 37297032632e1..e6846fb40494f 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr @@ -2,25 +2,28 @@ error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | ---- ---- ^ ...but data from `f` is returned here - | | - | this parameter and the return type are declared with different lifetimes... + | ---- ---- ^ ...but data from `f` is held across an await point here + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &Foo>` + | this parameter and the returned future are declared with different lifetimes... error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:82 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | ----- ----------------- ^ ...but data from `f` is returned here - | | - | this parameter and the return type are declared with different lifetimes... + | ----- ----------------- ^ ...but data from `f` is held across an await point here + | | | + | | this `async fn` implicitly returns an `impl Future<Output = (Pin<&Foo>, &Foo)>` + | this parameter and the returned future are declared with different lifetimes... error[E0623]: lifetime mismatch --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | ----- --- ^^^ ...but data from `arg` is returned here - | | - | this parameter and the return type are declared with different lifetimes... + | ----- --- ^^^ ...but data from `arg` is held across an await point here + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &()>` + | this parameter and the returned future are declared with different lifetimes... error: aborting due to 3 previous errors diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr index badd973c37f08..3221d27085096 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -3,60 +3,66 @@ error[E0623]: lifetime mismatch | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:19:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:23:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:27:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:31:9 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/lt-ref-self-async.rs:35:9 | LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr index 73d942a83f89a..b6ca986923d2e 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -3,60 +3,66 @@ error[E0623]: lifetime mismatch | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | --------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:19:9 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | --------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:23:9 | LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | --------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:27:9 | LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | --------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:31:9 | LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | --------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-self-async.rs:35:9 | LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | --------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr index 7d613c574486c..eda15d76390b6 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -3,50 +3,55 @@ error[E0623]: lifetime mismatch | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | ----------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | ----------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | ----------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { | ----------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-mut-struct-async.rs:29:9 | LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { | ----------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr index bda958241b67b..b42caa88c6fef 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -3,70 +3,77 @@ error[E0623]: lifetime mismatch | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:29:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:33:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:37:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:41:9 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:45:9 | LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | ----- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-self-async.rs:49:9 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | ----- --- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u8>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr index fc85450c4a7cd..599becd308062 100644 --- a/src/test/ui/self/elision/ref-struct-async.stderr +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -3,50 +3,55 @@ error[E0623]: lifetime mismatch | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | ------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | ------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | ------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error[E0623]: lifetime mismatch --> $DIR/ref-struct-async.rs:29:9 | LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | ------- ---- - | | - | this parameter and the return type are declared with different lifetimes... + | | | + | | this `async fn` implicitly returns an `impl Future<Output = &u32>` + | this parameter and the returned future are declared with different lifetimes... LL | f - | ^ ...but data from `f` is returned here + | ^ ...but data from `f` is held across an await point here error: aborting due to 5 previous errors From 251f6da276c3bee6a0737b8b42d5d13295c3a4d8 Mon Sep 17 00:00:00 2001 From: Florian Warzecha <liketechnik@disroot.org> Date: Sun, 25 Oct 2020 20:45:05 +0100 Subject: [PATCH 07/24] (rustdoc) fix test for trait impl display --- src/test/rustdoc/impl-everywhere.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/rustdoc/impl-everywhere.rs b/src/test/rustdoc/impl-everywhere.rs index 9d86dd3c29e98..742813262589b 100644 --- a/src/test/rustdoc/impl-everywhere.rs +++ b/src/test/rustdoc/impl-everywhere.rs @@ -8,23 +8,23 @@ pub struct Bar; impl Foo for Bar {} impl Foo2 for Bar {} -// @!has foo/fn.foo.html '//section[@id="main"]//pre' "x: &\'x impl Foo" -// @!has foo/fn.foo.html '//section[@id="main"]//pre' "-> &\'x impl Foo {" +// @has foo/fn.foo.html '//section[@id="main"]//pre' "x: &'x impl Foo" +// @has foo/fn.foo.html '//section[@id="main"]//pre' "-> &'x impl Foo" pub fn foo<'x>(x: &'x impl Foo) -> &'x impl Foo { x } -// @!has foo/fn.foo2.html '//section[@id="main"]//pre' "x: &\'x impl Foo" -// @!has foo/fn.foo2.html '//section[@id="main"]//pre' '-> impl Foo2 {' +// @has foo/fn.foo2.html '//section[@id="main"]//pre' "x: &'x impl Foo" +// @has foo/fn.foo2.html '//section[@id="main"]//pre' '-> impl Foo2' pub fn foo2<'x>(_x: &'x impl Foo) -> impl Foo2 { Bar } -// @!has foo/fn.foo_foo.html '//section[@id="main"]//pre' '-> impl Foo + Foo2 {' +// @has foo/fn.foo_foo.html '//section[@id="main"]//pre' '-> impl Foo + Foo2' pub fn foo_foo() -> impl Foo + Foo2 { Bar } -// @!has foo/fn.foo2.html '//section[@id="main"]//pre' "x: &'x (impl Foo + Foo2)" +// @has foo/fn.foo_foo_foo.html '//section[@id="main"]//pre' "x: &'x impl Foo + Foo2" pub fn foo_foo_foo<'x>(_x: &'x (impl Foo + Foo2)) { } From e4d109613eb0c61ab528c9ff632c5807a259b505 Mon Sep 17 00:00:00 2001 From: est31 <MTest31@outlook.com> Date: Wed, 28 Oct 2020 01:55:17 +0100 Subject: [PATCH 08/24] =?UTF-8?q?Change=20as=5Fstr=20=E2=86=92=20to=5Fstri?= =?UTF-8?q?ng=20in=20proc=5Fmacro::Ident::span()=20docs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no `as_str` function on Ident any more. Also change it to an intra doc link while we're at it. --- library/proc_macro/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 139b3591206e7..ad8f6e86766e0 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -881,7 +881,7 @@ impl Ident { } /// Returns the span of this `Ident`, encompassing the entire string returned - /// by `as_str`. + /// by [`to_string`](Self::to_string). #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn span(&self) -> Span { Span(self.0.span()) From 300362e0e4e30439bd2f55f3dc94596ab197607e Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 30 Oct 2020 13:03:01 -0700 Subject: [PATCH 09/24] Close the theme picker when Escape is pressed --- src/librustdoc/html/static/main.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 28bd1ba5247d6..69873524bd729 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -4,6 +4,7 @@ // Local js definitions: /* global addClass, getCurrentValue, hasClass */ /* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ +/* global hideThemeButtonState */ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { @@ -137,10 +138,6 @@ function defocusSearchBar() { sidebar.appendChild(div); } } - var themePickers = document.getElementsByClassName("theme-picker"); - if (themePickers && themePickers.length > 0) { - themePickers[0].style.display = "none"; - } } function hideSidebar() { @@ -155,10 +152,6 @@ function defocusSearchBar() { filler.remove(); } document.getElementsByTagName("body")[0].style.marginTop = ""; - var themePickers = document.getElementsByClassName("theme-picker"); - if (themePickers && themePickers.length > 0) { - themePickers[0].style.display = null; - } } function showSearchResults(search) { @@ -376,6 +369,7 @@ function defocusSearchBar() { document.title = titleBeforeSearch; } defocusSearchBar(); + hideThemeButtonState(); } function handleShortcut(ev) { From ac3a434ed947058635fbe1f09b1da8bd6f1ea242 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 30 Oct 2020 13:34:30 -0700 Subject: [PATCH 10/24] Allow the theme picker to work with arrow keys This is mostly motivated by docs.rs. It's really weird when arrow keys work in the top dropdown menu, but don't work in other dropdown menus on the same page. --- src/librustdoc/html/render/mod.rs | 48 +++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 0621eafd91347..8d07f479b6eae 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -798,17 +798,61 @@ function handleThemeButtonsBlur(e) {{ var active = document.activeElement; var related = e.relatedTarget; - if (active.id !== "themePicker" && + if (active.id !== "theme-picker" && (!active.parentNode || active.parentNode.id !== "theme-choices") && (!related || - (related.id !== "themePicker" && + (related.id !== "theme-picker" && (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{ hideThemeButtonState(); }} }} +function handleThemeKeyPress(e) {{ + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {{ return; }} + if (!themePicker.parentNode.contains(e.target)) {{ return; }} + var active = document.activeElement; + switch (e.key) {{ + case "ArrowUp": + e.preventDefault(); + if (active.previousElementSibling && e.target.id !== "theme-picker") {{ + active.previousElementSibling.focus(); + }} else {{ + showThemeButtonState(); + themes.lastElementChild.focus(); + }} + break; + case "ArrowDown": + e.preventDefault(); + if (active.nextElementSibling && e.target.id !== "theme-picker") {{ + active.nextElementSibling.focus(); + }} else {{ + showThemeButtonState(); + themes.firstElementChild.focus(); + }} + break; + case "Enter": + case "Return": + case "Space": + if (e.target.id === "theme-picker" && themes.style.display === "none") {{ + e.preventDefault(); + showThemeButtonState(); + themes.firstElementChild.focus(); + }} + break; + case "Home": + e.preventDefault(); + themes.firstElementChild.focus(); + break; + case "End": + e.preventDefault(); + themes.lastElementChild.focus(); + break; + }} +}}; + themePicker.onclick = switchThemeButtonState; themePicker.onblur = handleThemeButtonsBlur; +document.addEventListener("keydown", handleThemeKeyPress); {}.forEach(function(item) {{ var but = document.createElement("button"); but.textContent = item; From 6918a17aa4ed5d06c1fce292763ff26605c52b97 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 30 Oct 2020 13:35:41 -0700 Subject: [PATCH 11/24] Add aria roles for theme picker menu --- src/librustdoc/html/layout.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index b089bcb0862a5..db73af7ec1689 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -79,12 +79,12 @@ pub fn render<T: Print, S: Print>( {sidebar}\ </nav>\ <div class=\"theme-picker\">\ - <button id=\"theme-picker\" aria-label=\"Pick another theme!\">\ + <button id=\"theme-picker\" aria-label=\"Pick another theme!\" aria-haspopup=\"menu\">\ <img src=\"{static_root_path}brush{suffix}.svg\" \ width=\"18\" \ alt=\"Pick another theme!\">\ </button>\ - <div id=\"theme-choices\"></div>\ + <div id=\"theme-choices\" role=\"menu\"></div>\ </div>\ <script src=\"{static_root_path}theme{suffix}.js\"></script>\ <nav class=\"sub\">\ From 90c7c634e39944873a031624c4fb1dc0aa776e3a Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 30 Oct 2020 13:54:36 -0700 Subject: [PATCH 12/24] Add comment describing the Escape key weirdness --- src/librustdoc/html/render/mod.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8d07f479b6eae..bbcf3ce97e1dd 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -807,7 +807,7 @@ function handleThemeButtonsBlur(e) {{ }} }} -function handleThemeKeyPress(e) {{ +function handleThemeKeyDown(e) {{ if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {{ return; }} if (!themePicker.parentNode.contains(e.target)) {{ return; }} var active = document.activeElement; @@ -847,12 +847,18 @@ function handleThemeKeyPress(e) {{ e.preventDefault(); themes.lastElementChild.focus(); break; + // The escape key is handled in main.js, instead of here, for two reasons: + // + // 1 Escape should close the menu, even if it's not focused. + // 2 The escape event handler is bound to both keydown and keypress, to work + // around browser inconsistencies. That sort of logic doesn't apply to the + // rest of these keybindings. }} }}; themePicker.onclick = switchThemeButtonState; themePicker.onblur = handleThemeButtonsBlur; -document.addEventListener("keydown", handleThemeKeyPress); +document.addEventListener("keydown", handleThemeKeyDown); {}.forEach(function(item) {{ var but = document.createElement("button"); but.textContent = item; From 17b8ca952baf5d32ef6e9653b0eda6516386400c Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 30 Oct 2020 14:27:00 -0700 Subject: [PATCH 13/24] Pull theme picker keyboard code into main.js Most of the code in mod.rs should be code that really needs to have the list of available themes inlined into it. --- src/librustdoc/html/render/mod.rs | 50 ------------------------- src/librustdoc/html/static/main.js | 60 +++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 51 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index bbcf3ce97e1dd..5ac0ffcfbf1c2 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -807,58 +807,8 @@ function handleThemeButtonsBlur(e) {{ }} }} -function handleThemeKeyDown(e) {{ - if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {{ return; }} - if (!themePicker.parentNode.contains(e.target)) {{ return; }} - var active = document.activeElement; - switch (e.key) {{ - case "ArrowUp": - e.preventDefault(); - if (active.previousElementSibling && e.target.id !== "theme-picker") {{ - active.previousElementSibling.focus(); - }} else {{ - showThemeButtonState(); - themes.lastElementChild.focus(); - }} - break; - case "ArrowDown": - e.preventDefault(); - if (active.nextElementSibling && e.target.id !== "theme-picker") {{ - active.nextElementSibling.focus(); - }} else {{ - showThemeButtonState(); - themes.firstElementChild.focus(); - }} - break; - case "Enter": - case "Return": - case "Space": - if (e.target.id === "theme-picker" && themes.style.display === "none") {{ - e.preventDefault(); - showThemeButtonState(); - themes.firstElementChild.focus(); - }} - break; - case "Home": - e.preventDefault(); - themes.firstElementChild.focus(); - break; - case "End": - e.preventDefault(); - themes.lastElementChild.focus(); - break; - // The escape key is handled in main.js, instead of here, for two reasons: - // - // 1 Escape should close the menu, even if it's not focused. - // 2 The escape event handler is bound to both keydown and keypress, to work - // around browser inconsistencies. That sort of logic doesn't apply to the - // rest of these keybindings. - }} -}}; - themePicker.onclick = switchThemeButtonState; themePicker.onblur = handleThemeButtonsBlur; -document.addEventListener("keydown", handleThemeKeyDown); {}.forEach(function(item) {{ var but = document.createElement("button"); but.textContent = item; diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 69873524bd729..de4792a5bd2f7 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -4,7 +4,7 @@ // Local js definitions: /* global addClass, getCurrentValue, hasClass */ /* global onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */ -/* global hideThemeButtonState */ +/* global hideThemeButtonState, showThemeButtonState */ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { @@ -48,6 +48,14 @@ function getSearchElement() { return document.getElementById("search"); } +function getThemesElement() { + return document.getElementById("theme-choices"); +} + +function getThemePickerElement() { + return document.getElementById("theme-picker"); +} + // Sets the focus on the search bar at the top of the page function focusSearchBar() { getSearchInput().focus(); @@ -406,7 +414,57 @@ function defocusSearchBar() { case "?": displayHelp(true, ev); break; + + default: + var themePicker = getThemePickerElement(); + if (themePicker.parentNode.contains(ev.target)) { + handleThemeKeyDown(ev); + } + } + } + } + + function handleThemeKeyDown(ev) { + var active = document.activeElement; + var themes = getThemesElement(); + switch (getVirtualKey(ev)) { + case "ArrowUp": + ev.preventDefault(); + if (active.previousElementSibling && ev.target.id !== "theme-picker") { + active.previousElementSibling.focus(); + } else { + showThemeButtonState(); + themes.lastElementChild.focus(); } + break; + case "ArrowDown": + ev.preventDefault(); + if (active.nextElementSibling && ev.target.id !== "theme-picker") { + active.nextElementSibling.focus(); + } else { + showThemeButtonState(); + themes.firstElementChild.focus(); + } + break; + case "Enter": + case "Return": + case "Space": + if (ev.target.id === "theme-picker" && themes.style.display === "none") { + ev.preventDefault(); + showThemeButtonState(); + themes.firstElementChild.focus(); + } + break; + case "Home": + ev.preventDefault(); + themes.firstElementChild.focus(); + break; + case "End": + ev.preventDefault(); + themes.lastElementChild.focus(); + break; + // The escape key is handled in handleEscape, not here, + // so that pressing escape will close the menu even if it isn't focused } } From 5801109ba961b07364e915e6d1d8fa5e81ac6e47 Mon Sep 17 00:00:00 2001 From: est31 <MTest31@outlook.com> Date: Wed, 4 Nov 2020 01:28:37 +0100 Subject: [PATCH 14/24] Move Copy and Clone into the list of traits implemented for all sizes --- library/std/src/primitive_docs.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index ae678479234a8..88ab671b94eb9 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -491,6 +491,8 @@ mod prim_pointer {} /// /// Arrays of *any* size implement the following traits if the element type allows it: /// +/// - [`Copy`] +/// - [`Clone`] /// - [`Debug`] /// - [`IntoIterator`] (implemented for `&[T; N]` and `&mut [T; N]`) /// - [`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] @@ -498,15 +500,10 @@ mod prim_pointer {} /// - [`AsRef`], [`AsMut`] /// - [`Borrow`], [`BorrowMut`] /// -/// Arrays of sizes from 0 to 32 (inclusive) implement [`Default`] trait +/// Arrays of sizes from 0 to 32 (inclusive) implement the [`Default`] trait /// if the element type allows it. As a stopgap, trait implementations are /// statically generated up to size 32. /// -/// Arrays of *any* size are [`Copy`] if the element type is [`Copy`] -/// and [`Clone`] if the element type is [`Clone`]. This works -/// because [`Copy`] and [`Clone`] traits are specially known -/// to the compiler. -/// /// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on /// an array. Indeed, this provides most of the API for working with arrays. /// Slices have a dynamic size and do not coerce to arrays. From 93fa023111ddfa1997e32b117a3fff01c03c4db1 Mon Sep 17 00:00:00 2001 From: est31 <MTest31@outlook.com> Date: Wed, 4 Nov 2020 01:48:28 +0100 Subject: [PATCH 15/24] Fix outdated comment next to array_impl_default The comment has become outdated as the array_impl macro has been removed. --- library/core/src/array/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 966272ca11549..c8748d788161a 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -353,8 +353,9 @@ impl<T: Ord, const N: usize> Ord for [T; N] { } } -// The Default impls cannot be generated using the array_impls! macro because -// they require array literals. +// The Default impls cannot be done with const generics because `[T; 0]` doesn't +// require Default to be implemented, and having different impl blocks for +// different numbers isn't supported yet. macro_rules! array_impl_default { {$n:expr, $t:ident $($ts:ident)*} => { From bcd2f2df67ac755b23f540a0657572eade281f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de> Date: Wed, 4 Nov 2020 13:48:50 +0100 Subject: [PATCH 16/24] fix a couple of clippy warnings: filter_next manual_strip redundant_static_lifetimes single_char_pattern unnecessary_cast unused_unit op_ref redundant_closure useless_conversion --- compiler/rustc_ast/src/attr/mod.rs | 2 +- .../src/infer/error_reporting/need_type_info.rs | 1 - compiler/rustc_interface/src/util.rs | 9 ++++----- compiler/rustc_middle/src/middle/stability.rs | 2 +- compiler/rustc_middle/src/mir/terminator.rs | 2 +- .../src/borrow_check/diagnostics/conflict_errors.rs | 2 +- compiler/rustc_mir/src/transform/match_branches.rs | 2 +- compiler/rustc_resolve/src/late/diagnostics.rs | 5 ++--- compiler/rustc_span/src/lib.rs | 2 +- .../src/traits/error_reporting/mod.rs | 6 +----- compiler/rustc_trait_selection/src/traits/fulfill.rs | 2 +- 11 files changed, 14 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 70ad43ecad219..ec87a88f4aba7 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -360,7 +360,7 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { impl MetaItem { fn token_trees_and_spacings(&self) -> Vec<TreeAndSpacing> { let mut idents = vec![]; - let mut last_pos = BytePos(0 as u32); + let mut last_pos = BytePos(0_u32); for (i, segment) in self.path.segments.iter().enumerate() { let is_first = i == 0; if !is_first { diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 21023a06bb2d9..868989539d4fd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -739,7 +739,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { "cannot infer {} {} {} `{}`{}", kind_str, preposition, descr, type_name, parent_desc ) - .into() } } } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 46a6c5861d59d..3ed7d20ae4571 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -246,10 +246,10 @@ pub fn get_codegen_backend(sopts: &config::Options) -> Box<dyn CodegenBackend> { INIT.call_once(|| { #[cfg(feature = "llvm")] - const DEFAULT_CODEGEN_BACKEND: &'static str = "llvm"; + const DEFAULT_CODEGEN_BACKEND: &str = "llvm"; #[cfg(not(feature = "llvm"))] - const DEFAULT_CODEGEN_BACKEND: &'static str = "cranelift"; + const DEFAULT_CODEGEN_BACKEND: &str = "cranelift"; let codegen_name = sopts .debugging_opts @@ -414,11 +414,10 @@ pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend let libdir = filesearch::relative_target_lib_path(&sysroot, &target); sysroot.join(libdir).with_file_name("codegen-backends") }) - .filter(|f| { + .find(|f| { info!("codegen backend candidate: {}", f.display()); f.exists() - }) - .next(); + }); let sysroot = sysroot.unwrap_or_else(|| { let candidates = sysroot_candidates .iter() diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 1a206b245d37b..978f08927c6ef 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -399,7 +399,7 @@ impl<'tcx> TyCtxt<'tcx> { def_id: DefId, id: Option<HirId>, span: Span, - unmarked: impl FnOnce(Span, DefId) -> (), + unmarked: impl FnOnce(Span, DefId), ) { let soft_handler = |lint, span, msg: &_| { self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index c9493c679879e..709ffc3049ab8 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -46,7 +46,7 @@ impl SwitchTargets { pub fn new(targets: impl Iterator<Item = (u128, BasicBlock)>, otherwise: BasicBlock) -> Self { let (values, mut targets): (SmallVec<_>, SmallVec<_>) = targets.unzip(); targets.push(otherwise); - Self { values: values.into(), targets } + Self { values, targets } } /// Builds a switch targets definition that jumps to `then` if the tested value equals `value`, diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs index dca0d6d7790d4..1474c7abfadaf 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs @@ -120,7 +120,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let move_out = self.move_data.moves[(*move_site).moi]; let moved_place = &self.move_data.move_paths[move_out.path].place; // `*(_1)` where `_1` is a `Box` is actually a move out. - let is_box_move = moved_place.as_ref().projection == &[ProjectionElem::Deref] + let is_box_move = moved_place.as_ref().projection == [ProjectionElem::Deref] && self.body.local_decls[moved_place.local].ty.is_box(); !is_box_move diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index 06690dcbf6eb7..82c0b924f287e 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -63,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { }; // Check that destinations are identical, and if not, then don't optimize this block - if &bbs[first].terminator().kind != &bbs[second].terminator().kind { + if bbs[first].terminator().kind != bbs[second].terminator().kind { continue; } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a3e0028dc75d7..14f8c7b09f8e1 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1886,9 +1886,8 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { if snippet.starts_with('&') && !snippet.starts_with("&'") { introduce_suggestion .push((param.span, format!("&'a {}", &snippet[1..]))); - } else if snippet.starts_with("&'_ ") { - introduce_suggestion - .push((param.span, format!("&'a {}", &snippet[4..]))); + } else if let Some(stripped) = snippet.strip_prefix("&'_ ") { + introduce_suggestion.push((param.span, format!("&'a {}", &stripped))); } } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 97b5c11b0fefb..f52b64f488345 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1574,7 +1574,7 @@ fn normalize_src(src: &mut String, start_pos: BytePos) -> Vec<NormalizedPos> { /// Removes UTF-8 BOM, if any. fn remove_bom(src: &mut String, normalized_pos: &mut Vec<NormalizedPos>) { - if src.starts_with("\u{feff}") { + if src.starts_with('\u{feff}') { src.drain(..3); normalized_pos.push(NormalizedPos { pos: BytePos(0), diff: 3 }); } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f8bd3ab96e254..2d57c39f7c7e1 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1388,11 +1388,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { trait_ref: &ty::PolyTraitRef<'tcx>, ) { let get_trait_impl = |trait_def_id| { - self.tcx.find_map_relevant_impl( - trait_def_id, - trait_ref.skip_binder().self_ty(), - |impl_def_id| Some(impl_def_id), - ) + self.tcx.find_map_relevant_impl(trait_def_id, trait_ref.skip_binder().self_ty(), Some) }; let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); let all_traits = self.tcx.all_traits(LOCAL_CRATE); diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 9a8b5534dfe83..538c14c6b720e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -499,7 +499,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { Err(ErrorHandled::TooGeneric) => { pending_obligation.stalled_on = substs .iter() - .filter_map(|ty| TyOrConstInferVar::maybe_from_generic_arg(ty)) + .filter_map(TyOrConstInferVar::maybe_from_generic_arg) .collect(); ProcessResult::Unchanged } From 69e5729c58481e1a2ce4e4a5982d38deab1fc6b2 Mon Sep 17 00:00:00 2001 From: Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com> Date: Wed, 4 Nov 2020 14:54:22 +0100 Subject: [PATCH 17/24] Simplify the implementation of `get_mut` (no unsafe) --- library/core/src/cell.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 7140218fa9101..ef2a5dd570f73 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1733,8 +1733,7 @@ impl<T: ?Sized> UnsafeCell<T> { #[inline] #[unstable(feature = "unsafe_cell_get_mut", issue = "76943")] pub fn get_mut(&mut self) -> &mut T { - // SAFETY: (outer) `&mut` guarantees unique access. - unsafe { &mut *self.get() } + &mut self.value } /// Gets a mutable pointer to the wrapped value. From 232b9ba129b75fdf6b120c44f3696233915be40e Mon Sep 17 00:00:00 2001 From: Daiki Ihara <sasurau4@gmail.com> Date: Wed, 4 Nov 2020 23:59:04 +0900 Subject: [PATCH 18/24] Move range in ui test to ops test in library/core --- library/core/tests/ops.rs | 59 ++++++++++++++++++++++++++++++++++++++- src/test/ui/range.rs | 51 --------------------------------- 2 files changed, 58 insertions(+), 52 deletions(-) delete mode 100644 src/test/ui/range.rs diff --git a/library/core/tests/ops.rs b/library/core/tests/ops.rs index 3c83f0f230003..8f0cd3be4066e 100644 --- a/library/core/tests/ops.rs +++ b/library/core/tests/ops.rs @@ -1,6 +1,6 @@ use core::ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo}; -// Test the Range structs without the syntactic sugar. +// Test the Range structs and syntax. #[test] fn test_range() { @@ -94,3 +94,60 @@ fn test_bound_cloned_included() { fn test_bound_cloned_excluded() { assert_eq!(Bound::Excluded(&3).cloned(), Bound::Excluded(3)); } + +#[test] +#[allow(unused_comparisons)] +#[allow(unused_mut)] +fn test_range_syntax() { + let mut count = 0; + for i in 0_usize..10 { + assert!(i >= 0 && i < 10); + count += i; + } + assert_eq!(count, 45); + + let mut count = 0; + let mut range = 0_usize..10; + for i in range { + assert!(i >= 0 && i < 10); + count += i; + } + assert_eq!(count, 45); + + let mut count = 0; + let mut rf = 3_usize..; + for i in rf.take(10) { + assert!(i >= 3 && i < 13); + count += i; + } + assert_eq!(count, 75); + + let _ = 0_usize..4 + 4 - 3; + + fn foo() -> isize { + 42 + } + let _ = 0..foo(); + + let _ = { &42..&100 }; // references to literals are OK + let _ = ..42_usize; + + // Test we can use two different types with a common supertype. + let x = &42; + { + let y = 42; + let _ = x..&y; + } +} + +#[test] +#[allow(dead_code)] +fn test_range_syntax_in_return_statement() { + fn return_range_to() -> RangeTo<i32> { + return ..1; + } + fn return_full_range() -> RangeFull { + return ..; + } + // Not much to test. +} diff --git a/src/test/ui/range.rs b/src/test/ui/range.rs deleted file mode 100644 index f3f7508d12434..0000000000000 --- a/src/test/ui/range.rs +++ /dev/null @@ -1,51 +0,0 @@ -// run-pass -#![allow(unused_braces)] -#![allow(unused_comparisons)] -#![allow(dead_code)] -#![allow(unused_mut)] -// Test range syntax. - - -fn foo() -> isize { 42 } - -// Test that range syntax works in return statements -fn return_range_to() -> ::std::ops::RangeTo<i32> { return ..1; } -fn return_full_range() -> ::std::ops::RangeFull { return ..; } - -pub fn main() { - let mut count = 0; - for i in 0_usize..10 { - assert!(i >= 0 && i < 10); - count += i; - } - assert_eq!(count, 45); - - let mut count = 0; - let mut range = 0_usize..10; - for i in range { - assert!(i >= 0 && i < 10); - count += i; - } - assert_eq!(count, 45); - - let mut count = 0; - let mut rf = 3_usize..; - for i in rf.take(10) { - assert!(i >= 3 && i < 13); - count += i; - } - assert_eq!(count, 75); - - let _ = 0_usize..4+4-3; - let _ = 0..foo(); - - let _ = { &42..&100 }; // references to literals are OK - let _ = ..42_usize; - - // Test we can use two different types with a common supertype. - let x = &42; - { - let y = 42; - let _ = x..&y; - } -} From 308dbdd9fe6f9df10386e80cbd767000ca5a3c11 Mon Sep 17 00:00:00 2001 From: Pietro Albini <pietro@pietroalbini.org> Date: Thu, 5 Nov 2020 00:05:20 +0100 Subject: [PATCH 19/24] ci: bump actions/checkout to version 2 This was recommended by GitHub Support to try reducing the things that could've caused #78743. I checked the changelog and there should be no practical impact for us (we already set an explicit fetch-depth). --- .github/workflows/ci.yml | 8 ++++---- src/ci/github-actions/ci.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6025808eb615d..91241d2b214f9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted @@ -427,7 +427,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted @@ -537,7 +537,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted @@ -644,7 +644,7 @@ jobs: - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 - name: configure the PR in which the error message will be posted diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 01f15a82f0f5a..0df191f8f7404 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -99,7 +99,7 @@ x--expand-yaml-anchors--remove: run: git config --global core.autocrlf false - name: checkout the source code - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: fetch-depth: 2 From d8afe98eba85f2f8033d98ef1fdd030c6032b6e5 Mon Sep 17 00:00:00 2001 From: Camelid <camelidcamel@gmail.com> Date: Sun, 18 Oct 2020 18:05:29 -0700 Subject: [PATCH 20/24] Clean up docs for 'as' keyword --- library/std/src/keyword_docs.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index 9b704ee9ecab2..b990b78570393 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -15,18 +15,24 @@ /// ``` /// /// In general, any cast that can be performed via ascribing the type can also be done using `as`, -/// so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note: `let x: u32 -/// = 123` would be best in that situation). The same is not true in the other direction, however, +/// so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (note: `let x: u32 +/// = 123` would be best in that situation). The same is not true in the other direction, however; /// explicitly using `as` allows a few more coercions that aren't allowed implicitly, such as /// changing the type of a raw pointer or turning closures into raw pointers. /// -/// Other places `as` is used include as extra syntax for [`crate`] and `use`, to change the name -/// something is imported as. +/// `as` is also used to rename imports in [`use`] and [`extern crate`] statements: /// -/// For more information on what `as` is capable of, see the [Reference] +/// ``` +/// # #[allow(unused_imports)] +/// use std::{mem as memory, net as network}; +/// // Now you can use the names `memory` and `network` to refer to `std::mem` and `std::net`. +/// ``` +/// +/// For more information on what `as` is capable of, see the [Reference]. /// /// [Reference]: ../reference/expressions/operator-expr.html#type-cast-expressions -/// [`crate`]: keyword.crate.html +/// [`use`]: keyword.use.html +/// [`extern crate`]: keyword.crate.html mod as_keyword {} #[doc(keyword = "break")] @@ -397,6 +403,7 @@ mod enum_keyword {} /// [Rust book]: /// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code /// [Reference]: ../reference/items/external-blocks.html +/// [`crate`]: keyword.crate.html mod extern_keyword {} #[doc(keyword = "false")] From 3084a55d54c2e0ee1c97525f64f40b54091b93e4 Mon Sep 17 00:00:00 2001 From: Camelid <camelidcamel@gmail.com> Date: Wed, 4 Nov 2020 18:42:37 -0800 Subject: [PATCH 21/24] Don't use `crate` in link text `crate::` -> `core::` It looks weird to have `crate::` in the link text and we use the actual crate name everywhere else. If anyone is curious, I used this Vim command to update all the links: %s/\(\s\)\[`crate::\(.*\)`\]/\1[`core::\2`](crate::\2)/g --- library/core/src/intrinsics.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3e5d7caa2fe5d..7d0ba97de6eba 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -719,7 +719,7 @@ extern "rust-intrinsic" { /// macro, which panics when it is executed, it is *undefined behavior* to /// reach code marked with this function. /// - /// The stabilized version of this intrinsic is [`crate::hint::unreachable_unchecked`]. + /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`](crate::hint::unreachable_unchecked). #[rustc_const_unstable(feature = "const_unreachable_unchecked", issue = "53188")] pub fn unreachable() -> !; @@ -764,7 +764,7 @@ extern "rust-intrinsic" { /// More specifically, this is the offset in bytes between successive /// items of the same type, including alignment padding. /// - /// The stabilized version of this intrinsic is [`crate::mem::size_of`]. + /// The stabilized version of this intrinsic is [`core::mem::size_of`](crate::mem::size_of). #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] pub fn size_of<T>() -> usize; @@ -772,12 +772,12 @@ extern "rust-intrinsic" { /// /// Drop glue is not run on the destination. /// - /// The stabilized version of this intrinsic is [`crate::ptr::write`]. + /// The stabilized version of this intrinsic is [`core::ptr::write`](crate::ptr::write). pub fn move_val_init<T>(dst: *mut T, src: T); /// The minimum alignment of a type. /// - /// The stabilized version of this intrinsic is [`crate::mem::align_of`]. + /// The stabilized version of this intrinsic is [`core::mem::align_of`](crate::mem::align_of). #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] pub fn min_align_of<T>() -> usize; /// The preferred alignment of a type. @@ -793,13 +793,13 @@ extern "rust-intrinsic" { pub fn size_of_val<T: ?Sized>(_: *const T) -> usize; /// The required alignment of the referenced value. /// - /// The stabilized version of this intrinsic is [`crate::mem::align_of_val`]. + /// The stabilized version of this intrinsic is [`core::mem::align_of_val`](crate::mem::align_of_val). #[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")] pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize; /// Gets a static string slice containing the name of a type. /// - /// The stabilized version of this intrinsic is [`crate::any::type_name`]. + /// The stabilized version of this intrinsic is [`core::any::type_name`](crate::any::type_name). #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] pub fn type_name<T: ?Sized>() -> &'static str; @@ -807,7 +807,7 @@ extern "rust-intrinsic" { /// function will return the same value for a type regardless of whichever /// crate it is invoked in. /// - /// The stabilized version of this intrinsic is [`crate::any::TypeId::of`]. + /// The stabilized version of this intrinsic is [`core::any::TypeId::of`](crate::any::TypeId::of). #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] pub fn type_id<T: ?Sized + 'static>() -> u64; @@ -831,7 +831,7 @@ extern "rust-intrinsic" { /// Gets a reference to a static `Location` indicating where it was called. /// - /// Consider using [`crate::panic::Location::caller`] instead. + /// Consider using [`core::panic::Location::caller`](crate::panic::Location::caller) instead. #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")] pub fn caller_location() -> &'static crate::panic::Location<'static>; @@ -1152,11 +1152,11 @@ extern "rust-intrinsic" { /// Performs a volatile load from the `src` pointer. /// - /// The stabilized version of this intrinsic is [`crate::ptr::read_volatile`]. + /// The stabilized version of this intrinsic is [`core::ptr::read_volatile`](crate::ptr::read_volatile). pub fn volatile_load<T>(src: *const T) -> T; /// Performs a volatile store to the `dst` pointer. /// - /// The stabilized version of this intrinsic is [`crate::ptr::write_volatile`]. + /// The stabilized version of this intrinsic is [`core::ptr::write_volatile`](crate::ptr::write_volatile). pub fn volatile_store<T>(dst: *mut T, val: T); /// Performs a volatile load from the `src` pointer @@ -1697,7 +1697,7 @@ extern "rust-intrinsic" { /// Returns the value of the discriminant for the variant in 'v', /// cast to a `u64`; if `T` has no discriminant, returns 0. /// - /// The stabilized version of this intrinsic is [`crate::mem::discriminant`]. + /// The stabilized version of this intrinsic is [`core::mem::discriminant`](crate::mem::discriminant). #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")] pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant; From bbdb1f0f66c71e0f0add60dd168f67e388519e03 Mon Sep 17 00:00:00 2001 From: Camelid <camelidcamel@gmail.com> Date: Wed, 4 Nov 2020 18:57:52 -0800 Subject: [PATCH 22/24] Clean up some intra-doc links --- library/std/src/primitive_docs.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index ae678479234a8..9353642767a62 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -389,7 +389,7 @@ mod prim_unit {} // /// Raw, unsafe pointers, `*const T`, and `*mut T`. /// -/// *[See also the `std::ptr` module][`ptr`].* +/// *[See also the `std::ptr` module](ptr).* /// /// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. /// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is @@ -580,7 +580,7 @@ mod prim_array {} /// means that elements are laid out so that every element is the same /// distance from its neighbors. /// -/// *[See also the `std::slice` module][`crate::slice`].* +/// *[See also the `std::slice` module](crate::slice).* /// /// Slices are a view into a block of memory represented as a pointer and a /// length. @@ -625,7 +625,7 @@ mod prim_slice {} // /// String slices. /// -/// *[See also the `std::str` module][`crate::str`].* +/// *[See also the `std::str` module](crate::str).* /// /// The `str` type, also called a 'string slice', is the most primitive string /// type. It is usually seen in its borrowed form, `&str`. It is also the type @@ -820,7 +820,7 @@ mod prim_tuple {} /// /// For more information on floating point numbers, see [Wikipedia][wikipedia]. /// -/// *[See also the `std::f32::consts` module][`crate::f32::consts`].* +/// *[See also the `std::f32::consts` module](crate::f32::consts).* /// /// [wikipedia]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format #[stable(feature = "rust1", since = "1.0.0")] @@ -834,7 +834,7 @@ mod prim_f32 {} /// `f32`][`f32`] or [Wikipedia on double precision /// values][wikipedia] for more information. /// -/// *[See also the `std::f64::consts` module][`crate::f64::consts`].* +/// *[See also the `std::f64::consts` module](crate::f64::consts).* /// /// [`f32`]: prim@f32 /// [wikipedia]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format From 677b2acb482835e151c519da0b8517174b399e35 Mon Sep 17 00:00:00 2001 From: Camelid <camelidcamel@gmail.com> Date: Wed, 4 Nov 2020 18:52:02 -0800 Subject: [PATCH 23/24] Add missing comma 'Note however,' -> 'Note, however,' --- library/std/src/primitive_docs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 9353642767a62..c7d104a401f27 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -800,7 +800,7 @@ mod prim_tuple {} /// calculation with floats round to a nearby representable number. For example, /// `5.0` and `1.0` can be exactly represented as `f32`, but `1.0 / 5.0` results /// in `0.20000000298023223876953125` since `0.2` cannot be exactly represented -/// as `f32`. Note however, that printing floats with `println` and friends will +/// as `f32`. Note, however, that printing floats with `println` and friends will /// often discard insignificant digits: `println!("{}", 1.0f32 / 5.0f32)` will /// print `0.2`. /// From 873ebcb243a6ddf27ed4f8282ed3acf84513dc81 Mon Sep 17 00:00:00 2001 From: Ikko Ashimine <eltociear@gmail.com> Date: Thu, 5 Nov 2020 12:08:32 +0900 Subject: [PATCH 24/24] Fixed typo in comment paramter -> parameter --- compiler/rustc_middle/src/ty/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0a7bec1a342f3..aa5a696b09c3b 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1641,7 +1641,7 @@ pub type PlaceholderConst = Placeholder<BoundVar>; #[derive(Hash, HashStable)] pub struct WithOptConstParam<T> { pub did: T, - /// The `DefId` of the corresponding generic paramter in case `did` is + /// The `DefId` of the corresponding generic parameter in case `did` is /// a const argument. /// /// Note that even if `did` is a const argument, this may still be `None`.