Auto merge of #60211 - Centril:rollup-akw4r85, r=Centril

Rollup of 6 pull requests

Successful merges:

 - #59823 ([wg-async-await] Drop `async fn` arguments in async block )
 - #59839 (Warn on unused results for operation methods on nums)
 - #60146 (Update fonts used by rustdoc)
 - #60169 (Warn when ignore-tidy-linelength is present, but no lines are too long)
 - #60177 (Promote rust comments to rustdoc)
 - #60191 (Add f16c target_feature)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-04-23 19:52:05 +00:00
commit e938c2b9aa
160 changed files with 1182 additions and 546 deletions

View File

@ -1,5 +1,4 @@
#!/usr/bin/env bash
# ignore-tidy-linelength
set -ex

View File

@ -1,7 +1,5 @@
#!/usr/bin/env bash
# ignore-tidy-linelength
set -ex
source shared.sh

View File

@ -377,6 +377,8 @@ let m = ", $rot_result, ";
assert_eq!(n.rotate_left(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn rotate_left(self, n: u32) -> Self {
(self as $UnsignedT).rotate_left(n) as Self
@ -401,6 +403,8 @@ let m = ", $rot_op, ";
assert_eq!(n.rotate_right(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn rotate_right(self, n: u32) -> Self {
(self as $UnsignedT).rotate_right(n) as Self
@ -598,6 +602,8 @@ assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_add(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_add(rhs);
@ -620,6 +626,8 @@ assert_eq!((", stringify!($SelfT), "::min_value() + 2).checked_sub(3), None);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_sub(rhs);
@ -642,6 +650,8 @@ assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_mul(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_mul(rhs);
@ -665,6 +675,8 @@ assert_eq!((1", stringify!($SelfT), ").checked_div(0), None);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_div(self, rhs: Self) -> Option<Self> {
if rhs == 0 || (self == Self::min_value() && rhs == -1) {
@ -691,6 +703,8 @@ assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euclid(-1), None);
assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
if rhs == 0 || (self == Self::min_value() && rhs == -1) {
@ -718,6 +732,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.checked_rem(-1), None);",
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_rem(self, rhs: Self) -> Option<Self> {
if rhs == 0 || (self == Self::min_value() && rhs == -1) {
@ -745,6 +761,8 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
if rhs == 0 || (self == Self::min_value() && rhs == -1) {
@ -791,6 +809,8 @@ assert_eq!(0x1", stringify!($SelfT), ".checked_shl(129), None);",
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_shl(self, rhs: u32) -> Option<Self> {
let (a, b) = self.overflowing_shl(rhs);
@ -812,6 +832,8 @@ assert_eq!(0x10", stringify!($SelfT), ".checked_shr(128), None);",
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_shr(self, rhs: u32) -> Option<Self> {
let (a, b) = self.overflowing_shr(rhs);
@ -860,6 +882,8 @@ $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
let mut base = self;
@ -901,6 +925,8 @@ $EndFeature, "
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn saturating_add(self, rhs: Self) -> Self {
intrinsics::saturating_add(self, rhs)
@ -924,6 +950,8 @@ $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn saturating_sub(self, rhs: Self) -> Self {
intrinsics::saturating_sub(self, rhs)
@ -947,6 +975,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_mul(10), ", stringify!($Self
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_mul(self, rhs: Self) -> Self {
self.checked_mul(rhs).unwrap_or_else(|| {
@ -976,6 +1006,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.saturating_pow(3), ", stringify!($SelfT
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_pow(self, exp: u32) -> Self {
match self.checked_pow(exp) {
@ -1001,6 +1033,8 @@ assert_eq!(", stringify!($SelfT), "::max_value().wrapping_add(2), ", stringify!(
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_add(self, rhs: Self) -> Self {
intrinsics::overflowing_add(self, rhs)
@ -1022,6 +1056,8 @@ stringify!($SelfT), "::max_value());",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_sub(self, rhs: Self) -> Self {
intrinsics::overflowing_sub(self, rhs)
@ -1042,6 +1078,8 @@ assert_eq!(11i8.wrapping_mul(12), -124);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_mul(self, rhs: Self) -> Self {
intrinsics::overflowing_mul(self, rhs)
@ -1070,6 +1108,8 @@ assert_eq!((-128i8).wrapping_div(-1), -128);",
$EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_div(self, rhs: Self) -> Self {
self.overflowing_div(rhs).0
@ -1098,6 +1138,8 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
assert_eq!((-128i8).wrapping_div_euclid(-1), -128);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_div_euclid(self, rhs: Self) -> Self {
self.overflowing_div_euclid(rhs).0
@ -1126,6 +1168,8 @@ assert_eq!((-128i8).wrapping_rem(-1), 0);",
$EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_rem(self, rhs: Self) -> Self {
self.overflowing_rem(rhs).0
@ -1153,6 +1197,8 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
assert_eq!((-128i8).wrapping_rem_euclid(-1), 0);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
self.overflowing_rem_euclid(rhs).0
@ -1203,6 +1249,8 @@ assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);",
$EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
unsafe {
@ -1230,6 +1278,8 @@ assert_eq!((-128i16).wrapping_shr(64), -128);",
$EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_shr(self, rhs: u32) -> Self {
unsafe {
@ -1284,6 +1334,8 @@ assert_eq!(3i8.wrapping_pow(6), -39);",
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_pow(self, mut exp: u32) -> Self {
let mut base = self;
@ -1326,6 +1378,8 @@ assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (", stringify!($Sel
"::MIN, true));", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
@ -1351,6 +1405,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_sub(1), (", stringify!($Sel
"::MAX, true));", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
@ -1374,6 +1430,8 @@ assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true));",
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
@ -1405,6 +1463,8 @@ $EndFeature, "
```"),
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
if self == Self::min_value() && rhs == -1 {
(self, true)
@ -1438,6 +1498,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringi
```"),
#[inline]
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
if self == Self::min_value() && rhs == -1 {
(self, true)
@ -1470,6 +1532,8 @@ $EndFeature, "
```"),
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
if self == Self::min_value() && rhs == -1 {
(0, true)
@ -1502,6 +1566,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true));
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
if self == Self::min_value() && rhs == -1 {
@ -1555,6 +1621,8 @@ assert_eq!(0x1i32.overflowing_shl(36), (0x10, true));",
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
@ -1578,6 +1646,8 @@ assert_eq!(0x10i32.overflowing_shr(36), (0x1, true));",
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
@ -1630,6 +1700,8 @@ assert_eq!(3i8.overflowing_pow(5), (-13, true));",
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
let mut base = self;
@ -1677,6 +1749,8 @@ assert_eq!(x.pow(5), 32);",
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
pub fn pow(self, mut exp: u32) -> Self {
@ -1732,6 +1806,8 @@ assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2
assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
pub fn div_euclid(self, rhs: Self) -> Self {
@ -1770,6 +1846,8 @@ assert_eq!(a.rem_euclid(-b), 3);
assert_eq!((-a).rem_euclid(-b), 1);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
pub fn rem_euclid(self, rhs: Self) -> Self {
@ -2277,6 +2355,8 @@ let m = ", $rot_result, ";
assert_eq!(n.rotate_left(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn rotate_left(self, n: u32) -> Self {
intrinsics::rotate_left(self, n as $SelfT)
@ -2301,6 +2381,8 @@ let m = ", $rot_op, ";
assert_eq!(n.rotate_right(", $rot, "), m);
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn rotate_right(self, n: u32) -> Self {
intrinsics::rotate_right(self, n as $SelfT)
@ -2496,6 +2578,8 @@ Basic usage:
assert_eq!((", stringify!($SelfT), "::max_value() - 2).checked_add(3), None);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_add(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_add(rhs);
@ -2516,6 +2600,8 @@ Basic usage:
assert_eq!(0", stringify!($SelfT), ".checked_sub(1), None);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_sub(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_sub(rhs);
@ -2536,6 +2622,8 @@ Basic usage:
assert_eq!(", stringify!($SelfT), "::max_value().checked_mul(2), None);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_mul(self, rhs: Self) -> Option<Self> {
let (a, b) = self.overflowing_mul(rhs);
@ -2556,6 +2644,8 @@ Basic usage:
assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_div(self, rhs: Self) -> Option<Self> {
match rhs {
@ -2579,6 +2669,8 @@ assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));
assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
if rhs == 0 {
@ -2603,6 +2695,8 @@ Basic usage:
assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_rem(self, rhs: Self) -> Option<Self> {
if rhs == 0 {
@ -2627,6 +2721,8 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
if rhs == 0 {
@ -2672,6 +2768,8 @@ Basic usage:
assert_eq!(0x10", stringify!($SelfT), ".checked_shl(129), None);", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_shl(self, rhs: u32) -> Option<Self> {
let (a, b) = self.overflowing_shl(rhs);
@ -2692,6 +2790,8 @@ Basic usage:
assert_eq!(0x10", stringify!($SelfT), ".checked_shr(129), None);", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_shr(self, rhs: u32) -> Option<Self> {
let (a, b) = self.overflowing_shr(rhs);
@ -2712,6 +2812,8 @@ Basic usage:
assert_eq!(", stringify!($SelfT), "::max_value().checked_pow(2), None);", $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn checked_pow(self, mut exp: u32) -> Option<Self> {
let mut base = self;
@ -2750,6 +2852,8 @@ assert_eq!(200u8.saturating_add(127), 255);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[inline]
pub const fn saturating_add(self, rhs: Self) -> Self {
@ -2770,6 +2874,8 @@ Basic usage:
assert_eq!(13", stringify!($SelfT), ".saturating_sub(127), 0);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[rustc_const_unstable(feature = "const_saturating_int_methods")]
#[inline]
pub const fn saturating_sub(self, rhs: Self) -> Self {
@ -2793,6 +2899,8 @@ assert_eq!((", stringify!($SelfT), "::MAX).saturating_mul(10), ", stringify!($Se
"::MAX);", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_mul(self, rhs: Self) -> Self {
self.checked_mul(rhs).unwrap_or(Self::max_value())
@ -2815,6 +2923,8 @@ assert_eq!(", stringify!($SelfT), "::MAX.saturating_pow(2), ", stringify!($SelfT
$EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn saturating_pow(self, exp: u32) -> Self {
match self.checked_pow(exp) {
@ -2838,6 +2948,8 @@ assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::ma
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_add(self, rhs: Self) -> Self {
intrinsics::overflowing_add(self, rhs)
@ -2858,6 +2970,8 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::ma
$EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_sub(self, rhs: Self) -> Self {
intrinsics::overflowing_sub(self, rhs)
@ -2879,6 +2993,8 @@ $EndFeature, "
/// assert_eq!(25u8.wrapping_mul(12), 44);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_mul(self, rhs: Self) -> Self {
intrinsics::overflowing_mul(self, rhs)
@ -2899,6 +3015,8 @@ Basic usage:
", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_div(10), 10);", $EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_div(self, rhs: Self) -> Self {
self / rhs
@ -2924,6 +3042,8 @@ Basic usage:
assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_div_euclid(self, rhs: Self) -> Self {
self / rhs
@ -2946,6 +3066,8 @@ Basic usage:
", $Feature, "assert_eq!(100", stringify!($SelfT), ".wrapping_rem(10), 0);", $EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_rem(self, rhs: Self) -> Self {
self % rhs
@ -2972,6 +3094,8 @@ Basic usage:
assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
self % rhs
@ -3026,6 +3150,8 @@ Basic usage:
assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_shl(self, rhs: u32) -> Self {
unsafe {
@ -3055,6 +3181,8 @@ Basic usage:
assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, "
```"),
#[stable(feature = "num_wrapping", since = "1.2.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn wrapping_shr(self, rhs: u32) -> Self {
unsafe {
@ -3076,6 +3204,8 @@ Basic usage:
assert_eq!(3u8.wrapping_pow(6), 217);", $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn wrapping_pow(self, mut exp: u32) -> Self {
let mut base = self;
@ -3118,6 +3248,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_add(2), (7, false));
assert_eq!(", stringify!($SelfT), "::MAX.overflowing_add(1), (0, true));", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::add_with_overflow(self as $ActualT, rhs as $ActualT);
@ -3144,6 +3276,8 @@ assert_eq!(0", stringify!($SelfT), ".overflowing_sub(1), (", stringify!($SelfT),
$EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::sub_with_overflow(self as $ActualT, rhs as $ActualT);
@ -3169,6 +3303,8 @@ $EndFeature, "
/// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true));
/// ```
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
let (a, b) = intrinsics::mul_with_overflow(self as $ActualT, rhs as $ActualT);
@ -3196,6 +3332,8 @@ Basic usage
```"),
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_div(self, rhs: Self) -> (Self, bool) {
(self / rhs, false)
}
@ -3226,6 +3364,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
```"),
#[inline]
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
(self / rhs, false)
}
@ -3252,6 +3392,8 @@ Basic usage
```"),
#[inline]
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
(self % rhs, false)
}
@ -3282,6 +3424,8 @@ assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
```"),
#[inline]
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
(self % rhs, false)
}
@ -3329,6 +3473,8 @@ Basic usage
assert_eq!(0x1", stringify!($SelfT), ".overflowing_shl(132), (0x10, true));", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_shl(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shl(rhs), (rhs > ($BITS - 1)))
@ -3353,6 +3499,8 @@ Basic usage
assert_eq!(0x10", stringify!($SelfT), ".overflowing_shr(132), (0x1, true));", $EndFeature, "
```"),
#[stable(feature = "wrapping", since = "1.7.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn overflowing_shr(self, rhs: u32) -> (Self, bool) {
(self.wrapping_shr(rhs), (rhs > ($BITS - 1)))
@ -3374,6 +3522,8 @@ Basic usage:
assert_eq!(3u8.overflowing_pow(6), (217, true));", $EndFeature, "
```"),
#[stable(feature = "no_panic_pow", since = "1.34.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn overflowing_pow(self, mut exp: u32) -> (Self, bool) {
let mut base = self;
@ -3418,6 +3568,8 @@ Basic usage:
", $Feature, "assert_eq!(2", stringify!($SelfT), ".pow(5), 32);", $EndFeature, "
```"),
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
pub fn pow(self, mut exp: u32) -> Self {
@ -3459,6 +3611,8 @@ Basic usage:
assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
pub fn div_euclid(self, rhs: Self) -> Self {
@ -3483,6 +3637,8 @@ Basic usage:
assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type
```"),
#[unstable(feature = "euclidean_division", issue = "49048")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
#[rustc_inherit_overflow_checks]
pub fn rem_euclid(self, rhs: Self) -> Self {

View File

@ -58,10 +58,10 @@ impl<'a> FnKind<'a> {
}
}
pub fn header(&self) -> Option<FnHeader> {
pub fn header(&self) -> Option<&FnHeader> {
match *self {
FnKind::ItemFn(_, _, header, _, _) => Some(header),
FnKind::Method(_, sig, _, _) => Some(sig.header),
FnKind::ItemFn(_, _, ref header, _, _) => Some(header),
FnKind::Method(_, ref sig, _, _) => Some(&sig.header),
FnKind::Closure(_) => None,
}
}
@ -262,6 +262,9 @@ pub trait Visitor<'v> : Sized {
fn visit_pat(&mut self, p: &'v Pat) {
walk_pat(self, p)
}
fn visit_argument_source(&mut self, s: &'v ArgSource) {
walk_argument_source(self, s)
}
fn visit_anon_const(&mut self, c: &'v AnonConst) {
walk_anon_const(self, c)
}
@ -399,10 +402,17 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
for argument in &body.arguments {
visitor.visit_id(argument.hir_id);
visitor.visit_pat(&argument.pat);
visitor.visit_argument_source(&argument.source);
}
visitor.visit_expr(&body.value);
}
pub fn walk_argument_source<'v, V: Visitor<'v>>(visitor: &mut V, source: &'v ArgSource) {
if let ArgSource::AsyncFn(pat) = source {
visitor.visit_pat(pat);
}
}
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
// Intentionally visiting the expr first - the initialization expr
// dominates the local's definition.

View File

@ -448,10 +448,9 @@ impl<'a> LoweringContext<'a> {
impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
fn visit_pat(&mut self, p: &'lcx Pat) {
match p.node {
// Doesn't generate a Hir node
// Doesn't generate a HIR node
PatKind::Paren(..) => {},
_ => {
if let Some(owner) = self.hir_id_owner {
self.lctx.lower_node_id_with_owner(p.id, owner);
}
@ -461,6 +460,32 @@ impl<'a> LoweringContext<'a> {
visit::walk_pat(self, p)
}
fn visit_fn(&mut self, fk: visit::FnKind<'lcx>, fd: &'lcx FnDecl, s: Span, _: NodeId) {
if fk.header().map(|h| h.asyncness.node.is_async()).unwrap_or(false) {
// Don't visit the original pattern for async functions as it will be
// replaced.
for arg in &fd.inputs {
if let ArgSource::AsyncFn(pat) = &arg.source { self.visit_pat(pat); }
self.visit_ty(&arg.ty)
}
self.visit_fn_ret_ty(&fd.output);
match fk {
visit::FnKind::ItemFn(_, decl, _, body) => {
self.visit_fn_header(decl);
self.visit_block(body)
},
visit::FnKind::Method(_, sig, _, body) => {
self.visit_fn_header(&sig.header);
self.visit_block(body)
},
visit::FnKind::Closure(body) => self.visit_expr(body),
}
} else {
visit::walk_fn(self, fk, fd, s)
}
}
fn visit_item(&mut self, item: &'lcx Item) {
let hir_id = self.lctx.allocate_hir_id_counter(item.id).hir_id;
@ -784,12 +809,10 @@ impl<'a> LoweringContext<'a> {
})
}
fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>) -> hir::BodyId {
fn record_body(&mut self, value: hir::Expr, arguments: HirVec<hir::Arg>) -> hir::BodyId {
let body = hir::Body {
arguments: decl.map_or(hir_vec![], |decl| {
decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
}),
is_generator: self.is_generator,
arguments,
value,
};
let id = body.id();
@ -1112,11 +1135,10 @@ impl<'a> LoweringContext<'a> {
capture_clause: CaptureBy,
closure_node_id: NodeId,
ret_ty: Option<&Ty>,
span: Span,
body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
) -> hir::ExprKind {
let prev_is_generator = mem::replace(&mut self.is_generator, true);
let body_expr = body(self);
let span = body_expr.span;
let output = match ret_ty {
Some(ty) => FunctionRetTy::Ty(P(ty.clone())),
None => FunctionRetTy::Default(span),
@ -1126,7 +1148,11 @@ impl<'a> LoweringContext<'a> {
output,
c_variadic: false
};
let body_id = self.record_body(body_expr, Some(&decl));
// Lower the arguments before the body otherwise the body will call `lower_def` expecting
// the argument to have been assigned an id already.
let arguments = self.lower_args(Some(&decl));
let body_expr = body(self);
let body_id = self.record_body(body_expr, arguments);
self.is_generator = prev_is_generator;
let capture_clause = self.lower_capture_clause(capture_clause);
@ -1157,8 +1183,9 @@ impl<'a> LoweringContext<'a> {
F: FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
{
let prev = mem::replace(&mut self.is_generator, false);
let arguments = self.lower_args(decl);
let result = f(self);
let r = self.record_body(result, decl);
let r = self.record_body(result, arguments);
self.is_generator = prev;
return r;
}
@ -2224,10 +2251,17 @@ impl<'a> LoweringContext<'a> {
init: l.init.as_ref().map(|e| P(self.lower_expr(e))),
span: l.span,
attrs: l.attrs.clone(),
source: hir::LocalSource::Normal,
source: self.lower_local_source(l.source),
}, ids)
}
fn lower_local_source(&mut self, ls: LocalSource) -> hir::LocalSource {
match ls {
LocalSource::Normal => hir::LocalSource::Normal,
LocalSource::AsyncFn => hir::LocalSource::AsyncFn,
}
}
fn lower_mutability(&mut self, m: Mutability) -> hir::Mutability {
match m {
Mutability::Mutable => hir::MutMutable,
@ -2235,11 +2269,23 @@ impl<'a> LoweringContext<'a> {
}
}
fn lower_args(&mut self, decl: Option<&FnDecl>) -> HirVec<hir::Arg> {
decl.map_or(hir_vec![], |decl| decl.inputs.iter().map(|x| self.lower_arg(x)).collect())
}
fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(arg.id);
hir::Arg {
hir_id,
pat: self.lower_pat(&arg.pat),
source: self.lower_arg_source(&arg.source),
}
}
fn lower_arg_source(&mut self, source: &ArgSource) -> hir::ArgSource {
match source {
ArgSource::Normal => hir::ArgSource::Normal,
ArgSource::AsyncFn(pat) => hir::ArgSource::AsyncFn(self.lower_pat(pat)),
}
}
@ -2993,15 +3039,21 @@ impl<'a> LoweringContext<'a> {
fn lower_async_body(
&mut self,
decl: &FnDecl,
asyncness: IsAsync,
asyncness: &IsAsync,
body: &Block,
) -> hir::BodyId {
self.lower_body(Some(decl), |this| {
if let IsAsync::Async { closure_id, .. } = asyncness {
self.lower_body(Some(&decl), |this| {
if let IsAsync::Async { closure_id, ref arguments, .. } = asyncness {
let mut body = body.clone();
for a in arguments.iter().rev() {
body.stmts.insert(0, a.stmt.clone());
}
let async_expr = this.make_async_expr(
CaptureBy::Value, closure_id, None,
CaptureBy::Value, *closure_id, None, body.span,
|this| {
let body = this.lower_block(body, false);
let body = this.lower_block(&body, false);
this.expr_block(body, ThinVec::new())
});
this.expr(body.span, async_expr, ThinVec::new())
@ -3060,26 +3112,42 @@ impl<'a> LoweringContext<'a> {
value
)
}
ItemKind::Fn(ref decl, header, ref generics, ref body) => {
ItemKind::Fn(ref decl, ref header, ref generics, ref body) => {
let fn_def_id = self.resolver.definitions().local_def_id(id);
self.with_new_scopes(|this| {
// Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body
// only cares about the input argument patterns in the function
// declaration (decl), not the return types.
let body_id = this.lower_async_body(decl, header.asyncness.node, body);
let mut lower_fn = |decl: &FnDecl| {
// Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body
// only cares about the input argument patterns in the function
// declaration (decl), not the return types.
let body_id = this.lower_async_body(&decl, &header.asyncness.node, body);
let (generics, fn_decl) = this.add_in_band_defs(
generics,
fn_def_id,
AnonymousLifetimeMode::PassThrough,
|this, idty| this.lower_fn_decl(
decl,
Some((fn_def_id, idty)),
true,
header.asyncness.node.opt_return_id()
),
);
let (generics, fn_decl) = this.add_in_band_defs(
generics,
fn_def_id,
AnonymousLifetimeMode::PassThrough,
|this, idty| this.lower_fn_decl(
&decl,
Some((fn_def_id, idty)),
true,
header.asyncness.node.opt_return_id()
),
);
(body_id, generics, fn_decl)
};
let (body_id, generics, fn_decl) = if let IsAsync::Async {
arguments, ..
} = &header.asyncness.node {
let mut decl = decl.clone();
// Replace the arguments of this async function with the generated
// arguments that will be moved into the closure.
decl.inputs = arguments.clone().drain(..).map(|a| a.arg).collect();
lower_fn(&decl)
} else {
lower_fn(decl)
};
hir::ItemKind::Fn(
fn_decl,
@ -3558,15 +3626,33 @@ impl<'a> LoweringContext<'a> {
)
}
ImplItemKind::Method(ref sig, ref body) => {
let body_id = self.lower_async_body(&sig.decl, sig.header.asyncness.node, body);
let impl_trait_return_allow = !self.is_in_trait_impl;
let (generics, sig) = self.lower_method_sig(
&i.generics,
sig,
impl_item_def_id,
impl_trait_return_allow,
sig.header.asyncness.node.opt_return_id(),
);
let mut lower_method = |sig: &MethodSig| {
let body_id = self.lower_async_body(
&sig.decl, &sig.header.asyncness.node, body
);
let impl_trait_return_allow = !self.is_in_trait_impl;
let (generics, sig) = self.lower_method_sig(
&i.generics,
sig,
impl_item_def_id,
impl_trait_return_allow,
sig.header.asyncness.node.opt_return_id(),
);
(body_id, generics, sig)
};
let (body_id, generics, sig) = if let IsAsync::Async {
ref arguments, ..
} = sig.header.asyncness.node {
let mut sig = sig.clone();
// Replace the arguments of this async function with the generated
// arguments that will be moved into the closure.
sig.decl.inputs = arguments.clone().drain(..).map(|a| a.arg).collect();
lower_method(&sig)
} else {
lower_method(sig)
};
(generics, hir::ImplItemKind::Method(sig, body_id))
}
ImplItemKind::Type(ref ty) => (
@ -3760,7 +3846,7 @@ impl<'a> LoweringContext<'a> {
impl_trait_return_allow: bool,
is_async: Option<NodeId>,
) -> (hir::Generics, hir::MethodSig) {
let header = self.lower_fn_header(sig.header);
let header = self.lower_fn_header(&sig.header);
let (generics, decl) = self.add_in_band_defs(
generics,
fn_def_id,
@ -3782,10 +3868,10 @@ impl<'a> LoweringContext<'a> {
}
}
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
fn lower_fn_header(&mut self, h: &FnHeader) -> hir::FnHeader {
hir::FnHeader {
unsafety: self.lower_unsafety(h.unsafety),
asyncness: self.lower_asyncness(h.asyncness.node),
asyncness: self.lower_asyncness(&h.asyncness.node),
constness: self.lower_constness(h.constness),
abi: h.abi,
}
@ -3805,7 +3891,7 @@ impl<'a> LoweringContext<'a> {
}
}
fn lower_asyncness(&mut self, a: IsAsync) -> hir::IsAsync {
fn lower_asyncness(&mut self, a: &IsAsync) -> hir::IsAsync {
match a {
IsAsync::Async { .. } => hir::IsAsync::Async,
IsAsync::NotAsync => hir::IsAsync::NotAsync,
@ -4110,7 +4196,7 @@ impl<'a> LoweringContext<'a> {
hir::MatchSource::Normal,
),
ExprKind::Async(capture_clause, closure_node_id, ref block) => {
self.make_async_expr(capture_clause, closure_node_id, None, |this| {
self.make_async_expr(capture_clause, closure_node_id, None, block.span, |this| {
this.with_new_scopes(|this| {
let block = this.lower_block(block, false);
this.expr_block(block, ThinVec::new())
@ -4118,7 +4204,7 @@ impl<'a> LoweringContext<'a> {
})
}
ExprKind::Closure(
capture_clause, asyncness, movability, ref decl, ref body, fn_decl_span
capture_clause, ref asyncness, movability, ref decl, ref body, fn_decl_span
) => {
if let IsAsync::Async { closure_id, .. } = asyncness {
let outer_decl = FnDecl {
@ -4156,7 +4242,7 @@ impl<'a> LoweringContext<'a> {
Some(&**ty)
} else { None };
let async_body = this.make_async_expr(
capture_clause, closure_id, async_ret_ty,
capture_clause, *closure_id, async_ret_ty, body.span,
|this| {
this.with_new_scopes(|this| this.lower_expr(body))
});

View File

@ -68,16 +68,17 @@ impl<'a> DefCollector<'a> {
id: NodeId,
name: Name,
span: Span,
header: &FnHeader,
header: &'a FnHeader,
generics: &'a Generics,
decl: &'a FnDecl,
body: &'a Block,
) {
let (closure_id, return_impl_trait_id) = match header.asyncness.node {
let (closure_id, return_impl_trait_id, arguments) = match &header.asyncness.node {
IsAsync::Async {
closure_id,
return_impl_trait_id,
} => (closure_id, return_impl_trait_id),
arguments,
} => (closure_id, return_impl_trait_id, arguments),
_ => unreachable!(),
};
@ -86,17 +87,31 @@ impl<'a> DefCollector<'a> {
let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
let fn_def = self.create_def(id, fn_def_data, ITEM_LIKE_SPACE, span);
return self.with_parent(fn_def, |this| {
this.create_def(return_impl_trait_id, DefPathData::ImplTrait, REGULAR_SPACE, span);
this.create_def(*return_impl_trait_id, DefPathData::ImplTrait, REGULAR_SPACE, span);
visit::walk_generics(this, generics);
visit::walk_fn_decl(this, decl);
let closure_def = this.create_def(closure_id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
span);
// Walk the generated arguments for the `async fn`.
for a in arguments {
use visit::Visitor;
this.visit_ty(&a.arg.ty);
}
// We do not invoke `walk_fn_decl` as this will walk the arguments that are being
// replaced.
visit::walk_fn_ret_ty(this, &decl.output);
let closure_def = this.create_def(
*closure_id, DefPathData::ClosureExpr, REGULAR_SPACE, span,
);
this.with_parent(closure_def, |this| {
visit::walk_block(this, body);
for a in arguments {
use visit::Visitor;
// Walk each of the generated statements before the regular block body.
this.visit_stmt(&a.stmt);
}
visit::walk_block(this, &body);
})
})
}
@ -290,7 +305,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
match expr.node {
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
ExprKind::Closure(_, asyncness, ..) => {
ExprKind::Closure(_, ref asyncness, ..) => {
let closure_def = self.create_def(expr.id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
@ -300,7 +315,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
// Async closures desugar to closures inside of closures, so
// we must create two defs.
if let IsAsync::Async { closure_id, .. } = asyncness {
let async_def = self.create_def(closure_id,
let async_def = self.create_def(*closure_id,
DefPathData::ClosureExpr,
REGULAR_SPACE,
expr.span);

View File

@ -1583,6 +1583,17 @@ pub enum LocalSource {
Normal,
/// A desugared `for _ in _ { .. }` loop.
ForLoopDesugar,
/// When lowering async functions, we create locals within the `async move` so that
/// all arguments are dropped after the future is polled.
///
/// ```ignore (pseudo-Rust)
/// async fn foo(<pattern> @ x: Type) {
/// async move {
/// let <pattern> = x;
/// }
/// }
/// ```
AsyncFn,
}
/// Hints at the original code for a `match _ { .. }`.
@ -1883,6 +1894,26 @@ pub struct InlineAsm {
pub struct Arg {
pub pat: P<Pat>,
pub hir_id: HirId,
pub source: ArgSource,
}
impl Arg {
/// Returns the pattern representing the original binding for this argument.
pub fn original_pat(&self) -> &P<Pat> {
match &self.source {
ArgSource::Normal => &self.pat,
ArgSource::AsyncFn(pat) => &pat,
}
}
}
/// Represents the source of an argument in a function header.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ArgSource {
/// Argument as specified by the user.
Normal,
/// Generated argument from `async fn` lowering, contains the original binding pattern.
AsyncFn(P<Pat>),
}
/// Represents the header (not the body) of a function declaration.

View File

@ -86,19 +86,16 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
let sub_is_ret_type =
self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
let span_label_var1 = if let Some(simple_ident) = anon_arg_sup.pat.simple_ident() {
format!(" from `{}`", simple_ident)
} else {
String::new()
let span_label_var1 = match anon_arg_sup.original_pat().simple_ident() {
Some(simple_ident) => format!(" from `{}`", simple_ident),
None => String::new(),
};
let span_label_var2 = if let Some(simple_ident) = anon_arg_sub.pat.simple_ident() {
format!(" into `{}`", simple_ident)
} else {
String::new()
let span_label_var2 = match anon_arg_sub.original_pat().simple_ident() {
Some(simple_ident) => format!(" into `{}`", simple_ident),
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 {

View File

@ -95,13 +95,12 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
}
}
let (error_var, span_label_var) = if let Some(simple_ident) = arg.pat.simple_ident() {
(
let (error_var, span_label_var) = match arg.original_pat().simple_ident() {
Some(simple_ident) => (
format!("the type of `{}`", simple_ident),
format!("the type of `{}`", simple_ident),
)
} else {
("parameter type".to_owned(), "type".to_owned())
),
None => ("parameter type".to_owned(), "type".to_owned()),
};
let mut diag = struct_span_err!(

View File

@ -111,31 +111,31 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
/// and for error reporting logic to read arbitrary node types.
pub in_progress_tables: Option<&'a RefCell<ty::TypeckTables<'tcx>>>,
// Cache for projections. This cache is snapshotted along with the
// infcx.
//
// Public so that `traits::project` can use it.
/// Cache for projections. This cache is snapshotted along with the
/// infcx.
///
/// Public so that `traits::project` can use it.
pub projection_cache: RefCell<traits::ProjectionCache<'tcx>>,
// We instantiate UnificationTable with bounds<Ty> because the
// types that might instantiate a general type variable have an
// order, represented by its upper and lower bounds.
/// We instantiate `UnificationTable` with `bounds<Ty>` because the
/// types that might instantiate a general type variable have an
/// order, represented by its upper and lower bounds.
pub type_variables: RefCell<type_variable::TypeVariableTable<'tcx>>,
// Map from integral variable to the kind of integer it represents
/// Map from integral variable to the kind of integer it represents
int_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::IntVid>>>,
// Map from floating variable to the kind of float it represents
/// Map from floating variable to the kind of float it represents
float_unification_table: RefCell<ut::UnificationTable<ut::InPlace<ty::FloatVid>>>,
// Tracks the set of region variables and the constraints between
// them. This is initially `Some(_)` but when
// `resolve_regions_and_report_errors` is invoked, this gets set
// to `None` -- further attempts to perform unification etc may
// fail if new region constraints would've been added.
/// Tracks the set of region variables and the constraints between
/// them. This is initially `Some(_)` but when
/// `resolve_regions_and_report_errors` is invoked, this gets set
/// to `None` -- further attempts to perform unification etc may
/// fail if new region constraints would've been added.
region_constraints: RefCell<Option<RegionConstraintCollector<'tcx>>>,
// Once region inference is done, the values for each variable.
/// Once region inference is done, the values for each variable.
lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
/// Caches the results of trait selection. This cache is used
@ -145,65 +145,65 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
/// Caches the results of trait evaluation.
pub evaluation_cache: traits::EvaluationCache<'tcx>,
// the set of predicates on which errors have been reported, to
// avoid reporting the same error twice.
/// the set of predicates on which errors have been reported, to
/// avoid reporting the same error twice.
pub reported_trait_errors: RefCell<FxHashMap<Span, Vec<ty::Predicate<'tcx>>>>,
// When an error occurs, we want to avoid reporting "derived"
// errors that are due to this original failure. Normally, we
// handle this with the `err_count_on_creation` count, which
// basically just tracks how many errors were reported when we
// started type-checking a fn and checks to see if any new errors
// have been reported since then. Not great, but it works.
//
// However, when errors originated in other passes -- notably
// resolve -- this heuristic breaks down. Therefore, we have this
// auxiliary flag that one can set whenever one creates a
// type-error that is due to an error in a prior pass.
//
// Don't read this flag directly, call `is_tainted_by_errors()`
// and `set_tainted_by_errors()`.
/// When an error occurs, we want to avoid reporting "derived"
/// errors that are due to this original failure. Normally, we
/// handle this with the `err_count_on_creation` count, which
/// basically just tracks how many errors were reported when we
/// started type-checking a fn and checks to see if any new errors
/// have been reported since then. Not great, but it works.
///
/// However, when errors originated in other passes -- notably
/// resolve -- this heuristic breaks down. Therefore, we have this
/// auxiliary flag that one can set whenever one creates a
/// type-error that is due to an error in a prior pass.
///
/// Don't read this flag directly, call `is_tainted_by_errors()`
/// and `set_tainted_by_errors()`.
tainted_by_errors_flag: Cell<bool>,
// Track how many errors were reported when this infcx is created.
// If the number of errors increases, that's also a sign (line
// `tained_by_errors`) to avoid reporting certain kinds of errors.
/// Track how many errors were reported when this infcx is created.
/// If the number of errors increases, that's also a sign (line
/// `tained_by_errors`) to avoid reporting certain kinds of errors.
err_count_on_creation: usize,
// This flag is true while there is an active snapshot.
/// This flag is true while there is an active snapshot.
in_snapshot: Cell<bool>,
// A set of constraints that regionck must validate. Each
// constraint has the form `T:'a`, meaning "some type `T` must
// outlive the lifetime 'a". These constraints derive from
// instantiated type parameters. So if you had a struct defined
// like
//
// struct Foo<T:'static> { ... }
//
// then in some expression `let x = Foo { ... }` it will
// instantiate the type parameter `T` with a fresh type `$0`. At
// the same time, it will record a region obligation of
// `$0:'static`. This will get checked later by regionck. (We
// can't generally check these things right away because we have
// to wait until types are resolved.)
//
// These are stored in a map keyed to the id of the innermost
// enclosing fn body / static initializer expression. This is
// because the location where the obligation was incurred can be
// relevant with respect to which sublifetime assumptions are in
// place. The reason that we store under the fn-id, and not
// something more fine-grained, is so that it is easier for
// regionck to be sure that it has found *all* the region
// obligations (otherwise, it's easy to fail to walk to a
// particular node-id).
//
// Before running `resolve_regions_and_report_errors`, the creator
// of the inference context is expected to invoke
// `process_region_obligations` (defined in `self::region_obligations`)
// for each body-id in this map, which will process the
// obligations within. This is expected to be done 'late enough'
// that all type inference variables have been bound and so forth.
/// A set of constraints that regionck must validate. Each
/// constraint has the form `T:'a`, meaning "some type `T` must
/// outlive the lifetime 'a". These constraints derive from
/// instantiated type parameters. So if you had a struct defined
/// like
///
/// struct Foo<T:'static> { ... }
///
/// then in some expression `let x = Foo { ... }` it will
/// instantiate the type parameter `T` with a fresh type `$0`. At
/// the same time, it will record a region obligation of
/// `$0:'static`. This will get checked later by regionck. (We
/// can't generally check these things right away because we have
/// to wait until types are resolved.)
///
/// These are stored in a map keyed to the id of the innermost
/// enclosing fn body / static initializer expression. This is
/// because the location where the obligation was incurred can be
/// relevant with respect to which sublifetime assumptions are in
/// place. The reason that we store under the fn-id, and not
/// something more fine-grained, is so that it is easier for
/// regionck to be sure that it has found *all* the region
/// obligations (otherwise, it's easy to fail to walk to a
/// particular node-id).
///
/// Before running `resolve_regions_and_report_errors`, the creator
/// of the inference context is expected to invoke
/// `process_region_obligations` (defined in `self::region_obligations`)
/// for each body-id in this map, which will process the
/// obligations within. This is expected to be done 'late enough'
/// that all type inference variables have been bound and so forth.
pub region_obligations: RefCell<Vec<(hir::HirId, RegionObligation<'tcx>)>>,
/// What is the innermost universe we have created? Starts out as
@ -247,85 +247,85 @@ pub struct TypeTrace<'tcx> {
/// See `error_reporting` module for more details
#[derive(Clone, Debug)]
pub enum SubregionOrigin<'tcx> {
// Arose from a subtyping relation
/// Arose from a subtyping relation
Subtype(TypeTrace<'tcx>),
// Stack-allocated closures cannot outlive innermost loop
// or function so as to ensure we only require finite stack
/// Stack-allocated closures cannot outlive innermost loop
/// or function so as to ensure we only require finite stack
InfStackClosure(Span),
// Invocation of closure must be within its lifetime
/// Invocation of closure must be within its lifetime
InvokeClosure(Span),
// Dereference of reference must be within its lifetime
/// Dereference of reference must be within its lifetime
DerefPointer(Span),
// Closure bound must not outlive captured free variables
/// Closure bound must not outlive captured free variables
FreeVariable(Span, ast::NodeId),
// Index into slice must be within its lifetime
/// Index into slice must be within its lifetime
IndexSlice(Span),
// When casting `&'a T` to an `&'b Trait` object,
// relating `'a` to `'b`
/// When casting `&'a T` to an `&'b Trait` object,
/// relating `'a` to `'b`
RelateObjectBound(Span),
// Some type parameter was instantiated with the given type,
// and that type must outlive some region.
/// Some type parameter was instantiated with the given type,
/// and that type must outlive some region.
RelateParamBound(Span, Ty<'tcx>),
// The given region parameter was instantiated with a region
// that must outlive some other region.
/// The given region parameter was instantiated with a region
/// that must outlive some other region.
RelateRegionParamBound(Span),
// A bound placed on type parameters that states that must outlive
// the moment of their instantiation.
/// A bound placed on type parameters that states that must outlive
/// the moment of their instantiation.
RelateDefaultParamBound(Span, Ty<'tcx>),
// Creating a pointer `b` to contents of another reference
/// Creating a pointer `b` to contents of another reference
Reborrow(Span),
// Creating a pointer `b` to contents of an upvar
/// Creating a pointer `b` to contents of an upvar
ReborrowUpvar(Span, ty::UpvarId),
// Data with type `Ty<'tcx>` was borrowed
/// Data with type `Ty<'tcx>` was borrowed
DataBorrowed(Ty<'tcx>, Span),
// (&'a &'b T) where a >= b
/// (&'a &'b T) where a >= b
ReferenceOutlivesReferent(Ty<'tcx>, Span),
// Type or region parameters must be in scope.
/// Type or region parameters must be in scope.
ParameterInScope(ParameterOrigin, Span),
// The type T of an expression E must outlive the lifetime for E.
/// The type T of an expression E must outlive the lifetime for E.
ExprTypeIsNotInScope(Ty<'tcx>, Span),
// A `ref b` whose region does not enclose the decl site
/// A `ref b` whose region does not enclose the decl site
BindingTypeIsNotValidAtDecl(Span),
// Regions appearing in a method receiver must outlive method call
/// Regions appearing in a method receiver must outlive method call
CallRcvr(Span),
// Regions appearing in a function argument must outlive func call
/// Regions appearing in a function argument must outlive func call
CallArg(Span),
// Region in return type of invoked fn must enclose call
/// Region in return type of invoked fn must enclose call
CallReturn(Span),
// Operands must be in scope
/// Operands must be in scope
Operand(Span),
// Region resulting from a `&` expr must enclose the `&` expr
/// Region resulting from a `&` expr must enclose the `&` expr
AddrOf(Span),
// An auto-borrow that does not enclose the expr where it occurs
/// An auto-borrow that does not enclose the expr where it occurs
AutoBorrow(Span),
// Region constraint arriving from destructor safety
/// Region constraint arriving from destructor safety
SafeDestructor(Span),
// Comparing the signature and requirements of an impl method against
// the containing trait.
/// Comparing the signature and requirements of an impl method against
/// the containing trait.
CompareImplMethodObligation {
span: Span,
item_name: ast::Name,
@ -361,35 +361,35 @@ pub enum LateBoundRegionConversionTime {
/// See `error_reporting` module for more details
#[derive(Copy, Clone, Debug)]
pub enum RegionVariableOrigin {
// Region variables created for ill-categorized reasons,
// mostly indicates places in need of refactoring
/// Region variables created for ill-categorized reasons,
/// mostly indicates places in need of refactoring
MiscVariable(Span),
// Regions created by a `&P` or `[...]` pattern
/// Regions created by a `&P` or `[...]` pattern
PatternRegion(Span),
// Regions created by `&` operator
/// Regions created by `&` operator
AddrOfRegion(Span),
// Regions created as part of an autoref of a method receiver
/// Regions created as part of an autoref of a method receiver
Autoref(Span),
// Regions created as part of an automatic coercion
/// Regions created as part of an automatic coercion
Coercion(Span),
// Region variables created as the values for early-bound regions
/// Region variables created as the values for early-bound regions
EarlyBoundRegion(Span, InternedString),
// Region variables created for bound regions
// in a function or method that is called
/// Region variables created for bound regions
/// in a function or method that is called
LateBoundRegion(Span, ty::BoundRegion, LateBoundRegionConversionTime),
UpvarRegion(ty::UpvarId, Span),
BoundRegionInCoherence(ast::Name),
// This origin is used for the inference variables that we create
// during NLL region processing.
/// This origin is used for the inference variables that we create
/// during NLL region processing.
NLL(NLLRegionVariableOrigin),
}
@ -686,22 +686,22 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}
// Clear the "currently in a snapshot" flag, invoke the closure,
// then restore the flag to its original value. This flag is a
// debugging measure designed to detect cases where we start a
// snapshot, create type variables, and register obligations
// which may involve those type variables in the fulfillment cx,
// potentially leaving "dangling type variables" behind.
// In such cases, an assertion will fail when attempting to
// register obligations, within a snapshot. Very useful, much
// better than grovelling through megabytes of RUST_LOG output.
//
// HOWEVER, in some cases the flag is unhelpful. In particular, we
// sometimes create a "mini-fulfilment-cx" in which we enroll
// obligations. As long as this fulfillment cx is fully drained
// before we return, this is not a problem, as there won't be any
// escaping obligations in the main cx. In those cases, you can
// use this function.
/// Clear the "currently in a snapshot" flag, invoke the closure,
/// then restore the flag to its original value. This flag is a
/// debugging measure designed to detect cases where we start a
/// snapshot, create type variables, and register obligations
/// which may involve those type variables in the fulfillment cx,
/// potentially leaving "dangling type variables" behind.
/// In such cases, an assertion will fail when attempting to
/// register obligations, within a snapshot. Very useful, much
/// better than grovelling through megabytes of `RUST_LOG` output.
///
/// HOWEVER, in some cases the flag is unhelpful. In particular, we
/// sometimes create a "mini-fulfilment-cx" in which we enroll
/// obligations. As long as this fulfillment cx is fully drained
/// before we return, this is not a problem, as there won't be any
/// escaping obligations in the main cx. In those cases, you can
/// use this function.
pub fn save_and_restore_in_snapshot_flag<F, R>(&self, func: F) -> R
where
F: FnOnce(&Self) -> R,
@ -828,7 +828,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
r
}
// Execute `f` in a snapshot, and commit the bindings it creates
/// Execute `f` in a snapshot, and commit the bindings it creates.
pub fn in_snapshot<T, F>(&self, f: F) -> T
where
F: FnOnce(&CombinedSnapshot<'a, 'tcx>) -> T,
@ -854,9 +854,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Scan the constraints produced since `snapshot` began and returns:
///
/// - None -- if none of them involve "region outlives" constraints
/// - Some(true) -- if there are `'a: 'b` constraints where `'a` or `'b` is a placehodler
/// - Some(false) -- if there are `'a: 'b` constraints but none involve placeholders
/// - `None` -- if none of them involve "region outlives" constraints
/// - `Some(true)` -- if there are `'a: 'b` constraints where `'a` or `'b` is a placeholder
/// - `Some(false)` -- if there are `'a: 'b` constraints but none involve placeholders
pub fn region_constraints_added_in_snapshot(
&self,
snapshot: &CombinedSnapshot<'a, 'tcx>,
@ -1292,19 +1292,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.type_variables.borrow_mut().root_var(var)
}
/// Where possible, replaces type/int/float variables in
/// `value` with their final value. Note that region variables
/// are unaffected. If a type variable has not been unified, it
/// is left as is. This is an idempotent operation that does
/// not affect inference state in any way and so you can do it
/// at will.
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
where
T: TypeFoldable<'tcx>,
{
/*!
* Where possible, replaces type/int/float variables in
* `value` with their final value. Note that region variables
* are unaffected. If a type variable has not been unified, it
* is left as is. This is an idempotent operation that does
* not affect inference state in any way and so you can do it
* at will.
*/
if !value.needs_infer() {
return value.clone(); // avoid duplicated subst-folding
}

View File

@ -1326,6 +1326,25 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
run_early_pass!(self, check_mac, mac);
}
fn visit_fn_header(&mut self, header: &'a ast::FnHeader) {
// Unlike in HIR lowering and name resolution, the `AsyncArgument` statements are not added
// to the function body and the arguments do not replace those in the declaration. They are
// still visited manually here so that buffered lints can be emitted.
if let ast::IsAsync::Async { ref arguments, .. } = header.asyncness.node {
for a in arguments {
// Visit the argument..
self.visit_pat(&a.arg.pat);
if let ast::ArgSource::AsyncFn(pat) = &a.arg.source {
self.visit_pat(pat);
}
self.visit_ty(&a.arg.ty);
// ..and the statement.
self.visit_stmt(&a.stmt);
}
}
}
}
struct LateLintPassObjects<'a> {

View File

@ -2421,7 +2421,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let help_name = if let Some(body) = parent {
let arg = &self.tcx.hir().body(body).arguments[index];
format!("`{}`", self.tcx.hir().hir_to_pretty_string(arg.pat.hir_id))
format!("`{}`", self.tcx.hir().hir_to_pretty_string(arg.original_pat().hir_id))
} else {
format!("argument {}", index + 1)
};

View File

@ -438,12 +438,12 @@ bitflags! {
// FIXME: Rename this to the actual property since it's used for generators too
const HAS_TY_CLOSURE = 1 << 9;
// `true` if there are "names" of types and regions and so forth
// that are local to a particular fn
/// `true` if there are "names" of types and regions and so forth
/// that are local to a particular fn
const HAS_FREE_LOCAL_NAMES = 1 << 10;
// Present if the type belongs in a local type context.
// Only set for Infer other than Fresh.
/// Present if the type belongs in a local type context.
/// Only set for Infer other than Fresh.
const KEEP_IN_LOCAL_TCX = 1 << 11;
// Is there a projection that does not involve a bound region?
@ -462,9 +462,9 @@ bitflags! {
TypeFlags::HAS_SELF.bits |
TypeFlags::HAS_RE_EARLY_BOUND.bits;
// Flags representing the nominal content of a type,
// computed by FlagsComputation. If you add a new nominal
// flag, it should be added here too.
/// Flags representing the nominal content of a type,
/// computed by FlagsComputation. If you add a new nominal
/// flag, it should be added here too.
const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits |
TypeFlags::HAS_SELF.bits |
TypeFlags::HAS_TY_INFER.bits |

View File

@ -439,16 +439,16 @@ struct SubstFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
substs: &'a [Kind<'tcx>],
// The location for which the substitution is performed, if available.
/// The location for which the substitution is performed, if available.
span: Option<Span>,
// The root type that is being substituted, if available.
/// The root type that is being substituted, if available.
root_ty: Option<Ty<'tcx>>,
// Depth of type stack
/// Depth of type stack
ty_stack_depth: usize,
// Number of region binders we have passed through while doing the substitution
/// Number of region binders we have passed through while doing the substitution
binders_passed: u32,
}

View File

@ -145,6 +145,7 @@ const X86_WHITELIST: &[(&str, Option<&str>)] = &[
("bmi1", None),
("bmi2", None),
("cmpxchg16b", Some("cmpxchg16b_target_feature")),
("f16c", Some("f16c_target_feature")),
("fma", None),
("fxsr", None),
("lzcnt", None),

View File

@ -76,6 +76,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
self.check_irrefutable(&loc.pat, match loc.source {
hir::LocalSource::Normal => "local binding",
hir::LocalSource::ForLoopDesugar => "`for` loop binding",
hir::LocalSource::AsyncFn => "async fn binding",
});
// Check legality of move bindings and `@` patterns.

View File

@ -222,7 +222,7 @@ impl<'a> AstValidator<'a> {
}
}
fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) {
fn check_trait_fn_not_async(&self, span: Span, asyncness: &IsAsync) {
if asyncness.is_async() {
struct_span_err!(self.session, span, E0706,
"trait fns cannot be declared `async`").emit()
@ -570,7 +570,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.invalid_visibility(&impl_item.vis, None);
if let ImplItemKind::Method(ref sig, _) = impl_item.node {
self.check_trait_fn_not_const(sig.header.constness);
self.check_trait_fn_not_async(impl_item.span, sig.header.asyncness.node);
self.check_trait_fn_not_async(impl_item.span, &sig.header.asyncness.node);
}
}
}
@ -642,7 +642,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.no_questions_in_bounds(bounds, "supertraits", true);
for trait_item in trait_items {
if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
self.check_trait_fn_not_async(trait_item.span, sig.header.asyncness.node);
self.check_trait_fn_not_async(trait_item.span, &sig.header.asyncness.node);
self.check_trait_fn_not_const(sig.header.constness);
if block.is_none() {
self.check_decl_no_pat(&sig.decl, |span, mut_ident| {

View File

@ -948,6 +948,16 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
intravisit::walk_pat(self, pat);
}
fn visit_argument_source(&mut self, s: &'tcx hir::ArgSource) {
match s {
// Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has
// a `NodeId` w/out a type, as it is only used for getting the name of the original
// pattern for diagnostics where only an `hir::Arg` is present.
hir::ArgSource::AsyncFn(..) => {},
_ => intravisit::walk_argument_source(self, s),
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////
@ -1133,6 +1143,16 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
intravisit::walk_pat(self, pattern);
}
fn visit_argument_source(&mut self, s: &'tcx hir::ArgSource) {
match s {
// Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has
// a `NodeId` w/out a type, as it is only used for getting the name of the original
// pattern for diagnostics where only an `hir::Arg` is present.
hir::ArgSource::AsyncFn(..) => {},
_ => intravisit::walk_argument_source(self, s),
}
}
fn visit_local(&mut self, local: &'tcx hir::Local) {
if let Some(ref init) = local.init {
if self.check_expr_pat_type(init.hir_id, init.span) {

View File

@ -817,13 +817,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
debug!("(resolving function) entering function");
let (rib_kind, asyncness) = match function_kind {
FnKind::ItemFn(_, ref header, ..) =>
(FnItemRibKind, header.asyncness.node),
(FnItemRibKind, &header.asyncness.node),
FnKind::Method(_, ref sig, _, _) =>
(TraitOrImplItemRibKind, sig.header.asyncness.node),
(TraitOrImplItemRibKind, &sig.header.asyncness.node),
FnKind::Closure(_) =>
// Async closures aren't resolved through `visit_fn`-- they're
// processed separately
(ClosureRibKind(node_id), IsAsync::NotAsync),
(ClosureRibKind(node_id), &IsAsync::NotAsync),
};
// Create a value rib for the function.
@ -834,26 +834,42 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
// Add each argument to the rib.
let mut bindings_list = FxHashMap::default();
for argument in &declaration.inputs {
let mut add_argument = |argument: &ast::Arg| {
self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
self.visit_ty(&argument.ty);
debug!("(resolving function) recorded argument");
};
// Walk the generated async arguments if this is an `async fn`, otherwise walk the
// normal arguments.
if let IsAsync::Async { ref arguments, .. } = asyncness {
for a in arguments { add_argument(&a.arg); }
} else {
for a in &declaration.inputs { add_argument(a); }
}
visit::walk_fn_ret_ty(self, &declaration.output);
// Resolve the function body, potentially inside the body of an async closure
if let IsAsync::Async { closure_id, .. } = asyncness {
let rib_kind = ClosureRibKind(closure_id);
let rib_kind = ClosureRibKind(*closure_id);
self.ribs[ValueNS].push(Rib::new(rib_kind));
self.label_ribs.push(Rib::new(rib_kind));
}
match function_kind {
FnKind::ItemFn(.., body) |
FnKind::Method(.., body) => {
self.visit_block(body);
FnKind::ItemFn(.., body) | FnKind::Method(.., body) => {
if let IsAsync::Async { ref arguments, .. } = asyncness {
let mut body = body.clone();
// Insert the generated statements into the body before attempting to
// resolve names.
for a in arguments {
body.stmts.insert(0, a.stmt.clone());
}
self.visit_block(&body);
} else {
self.visit_block(body);
}
}
FnKind::Closure(body) => {
self.visit_expr(body);

View File

@ -374,7 +374,7 @@ impl Sig for ast::Item {
Ok(extend_sig(ty, text, defs, vec![]))
}
ast::ItemKind::Fn(ref decl, header, ref generics, _) => {
ast::ItemKind::Fn(ref decl, ref header, ref generics, _) => {
let mut text = String::new();
if header.constness.node == ast::Constness::Const {
text.push_str("const ");

View File

@ -1005,6 +1005,16 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for GatherLocalsVisitor<'a, 'gcx, 'tcx> {
// Don't descend into the bodies of nested closures
fn visit_fn(&mut self, _: intravisit::FnKind<'gcx>, _: &'gcx hir::FnDecl,
_: hir::BodyId, _: Span, _: hir::HirId) { }
fn visit_argument_source(&mut self, s: &'gcx hir::ArgSource) {
match s {
// Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has
// a `NodeId` w/out a type, as it is only used for getting the name of the original
// pattern for diagnostics where only an `hir::Arg` is present.
hir::ArgSource::AsyncFn(..) => {},
_ => intravisit::walk_argument_source(self, s),
}
}
}
/// When `check_fn` is invoked on a generator (i.e., a body that

View File

@ -297,6 +297,16 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
let ty = self.resolve(&ty, &hir_ty.span);
self.write_ty_to_tables(hir_ty.hir_id, ty);
}
fn visit_argument_source(&mut self, s: &'gcx hir::ArgSource) {
match s {
// Don't visit the pattern in `ArgSource::AsyncFn`, it contains a pattern which has
// a `NodeId` w/out a type, as it is only used for getting the name of the original
// pattern for diagnostics where only an `hir::Arg` is present.
hir::ArgSource::AsyncFn(..) => {},
_ => intravisit::walk_argument_source(self, s),
}
}
}
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {

View File

@ -2017,7 +2017,7 @@ impl<'a> Clean<Arguments> for (&'a [hir::Ty], hir::BodyId) {
Arguments {
values: self.0.iter().enumerate().map(|(i, ty)| {
Argument {
name: name_from_pat(&body.arguments[i].pat),
name: name_from_pat(&body.arguments[i].original_pat()),
type_: ty.clean(cx),
}
}).collect()

View File

@ -930,13 +930,13 @@ themePicker.onblur = handleThemeButtonsBlur;
static_files::source_serif_pro::BOLD)?;
write(cx.dst.join("SourceSerifPro-It.ttf.woff"),
static_files::source_serif_pro::ITALIC)?;
write(cx.dst.join("SourceSerifPro-LICENSE.txt"),
write(cx.dst.join("SourceSerifPro-LICENSE.md"),
static_files::source_serif_pro::LICENSE)?;
write(cx.dst.join("SourceCodePro-Regular.woff"),
static_files::source_code_pro::REGULAR)?;
write(cx.dst.join("SourceCodePro-Semibold.woff"),
static_files::source_code_pro::SEMIBOLD)?;
write(cx.dst.join("SourceCodePro-LICENSE.txt"),
write(cx.dst.join("SourceCodePro-LICENSE.md"),
static_files::source_code_pro::LICENSE)?;
write(cx.dst.join("LICENSE-MIT.txt"),
static_files::LICENSE_MIT)?;

View File

@ -1,10 +1,5 @@
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
with Reserved Font Name Fira Sans.
Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
with Reserved Font Name Fira Mono.
Copyright (c) 2014, Telefonica S.A.
Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
with Reserved Font Name < Fira >,
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
@ -24,7 +19,7 @@ with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The

View File

@ -18,7 +18,7 @@ with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The

View File

@ -1,4 +1,4 @@
Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
Copyright 2014-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.

View File

@ -91,7 +91,7 @@ pub mod source_serif_pro {
pub static ITALIC: &'static [u8] = include_bytes!("static/SourceSerifPro-It.ttf.woff");
/// The file `SourceSerifPro-LICENSE.txt`, the license text for the Source Serif Pro font.
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceSerifPro-LICENSE.txt");
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceSerifPro-LICENSE.md");
}
/// Files related to the Source Code Pro font.
@ -103,7 +103,7 @@ pub mod source_code_pro {
pub static SEMIBOLD: &'static [u8] = include_bytes!("static/SourceCodePro-Semibold.woff");
/// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceCodePro-LICENSE.md");
}
/// Files related to the sidebar in rustdoc sources.

View File

@ -888,6 +888,17 @@ pub struct Local {
pub id: NodeId,
pub span: Span,
pub attrs: ThinVec<Attribute>,
/// Origin of this local variable.
pub source: LocalSource,
}
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
pub enum LocalSource {
/// Local was parsed from source.
Normal,
/// Within `ast::IsAsync::Async`, a local is generated that will contain the moved arguments
/// of an `async fn`.
AsyncFn,
}
/// An arm of a 'match'.
@ -1725,6 +1736,16 @@ pub struct Arg {
pub ty: P<Ty>,
pub pat: P<Pat>,
pub id: NodeId,
pub source: ArgSource,
}
/// The source of an argument in a function header.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum ArgSource {
/// Argument as written by the user.
Normal,
/// Argument from `async fn` lowering, contains the original binding pattern.
AsyncFn(P<Pat>),
}
/// Alternative representation for `Arg`s describing `self` parameter of methods.
@ -1784,6 +1805,7 @@ impl Arg {
}),
ty,
id: DUMMY_NODE_ID,
source: ArgSource::Normal,
};
match eself.node {
SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
@ -1838,18 +1860,35 @@ pub enum Unsafety {
Normal,
}
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct AsyncArgument {
/// `__arg0`
pub ident: Ident,
/// `__arg0: <ty>` argument to replace existing function argument `<pat>: <ty>`.
pub arg: Arg,
/// `let <pat>: <ty> = __arg0;` statement to be inserted at the start of the block.
pub stmt: Stmt,
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum IsAsync {
Async {
closure_id: NodeId,
return_impl_trait_id: NodeId,
/// This field stores the arguments and statements that are used in HIR lowering to
/// ensure that `async fn` arguments are dropped at the correct time.
///
/// The argument and statements here are generated at parse time as they are required in
/// both the hir lowering, def collection and name resolution and this stops them needing
/// to be created in each place.
arguments: Vec<AsyncArgument>,
},
NotAsync,
}
impl IsAsync {
pub fn is_async(self) -> bool {
if let IsAsync::Async { .. } = self {
pub fn is_async(&self) -> bool {
if let IsAsync::Async { .. } = *self {
true
} else {
false
@ -1857,12 +1896,12 @@ impl IsAsync {
}
/// In ths case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
pub fn opt_return_id(self) -> Option<NodeId> {
pub fn opt_return_id(&self) -> Option<NodeId> {
match self {
IsAsync::Async {
return_impl_trait_id,
..
} => Some(return_impl_trait_id),
} => Some(*return_impl_trait_id),
IsAsync::NotAsync => None,
}
}
@ -2202,7 +2241,7 @@ impl Item {
///
/// All the information between the visibility and the name of the function is
/// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`).
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct FnHeader {
pub unsafety: Unsafety,
pub asyncness: Spanned<IsAsync>,

View File

@ -526,6 +526,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
id: ast::DUMMY_NODE_ID,
span: sp,
attrs: ThinVec::new(),
source: ast::LocalSource::Normal,
});
ast::Stmt {
id: ast::DUMMY_NODE_ID,
@ -554,6 +555,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
id: ast::DUMMY_NODE_ID,
span: sp,
attrs: ThinVec::new(),
source: ast::LocalSource::Normal,
});
ast::Stmt {
id: ast::DUMMY_NODE_ID,
@ -571,6 +573,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
id: ast::DUMMY_NODE_ID,
span,
attrs: ThinVec::new(),
source: ast::LocalSource::Normal,
});
ast::Stmt {
id: ast::DUMMY_NODE_ID,
@ -976,7 +979,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ast::Arg {
ty,
pat: arg_pat,
id: ast::DUMMY_NODE_ID
id: ast::DUMMY_NODE_ID,
source: ast::ArgSource::Normal,
}
}

View File

@ -102,6 +102,13 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
fn remove(&mut self, id: ast::NodeId) -> AstFragment {
self.expanded_fragments.remove(&id).unwrap()
}
fn next_id(&mut self, id: &mut ast::NodeId) {
if self.monotonic {
assert_eq!(*id, ast::DUMMY_NODE_ID);
*id = self.cx.resolver.next_node_id()
}
}
}
impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
@ -183,9 +190,16 @@ impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
noop_visit_block(block, self);
for stmt in block.stmts.iter_mut() {
if self.monotonic {
assert_eq!(stmt.id, ast::DUMMY_NODE_ID);
stmt.id = self.cx.resolver.next_node_id();
self.next_id(&mut stmt.id);
}
}
fn visit_asyncness(&mut self, a: &mut ast::IsAsync) {
noop_visit_asyncness(a, self);
if let ast::IsAsync::Async { ref mut arguments, .. } = a {
for argument in arguments.iter_mut() {
self.next_id(&mut argument.stmt.id);
}
}
}

View File

@ -208,6 +208,10 @@ pub trait MutVisitor: Sized {
noop_visit_local(l, self);
}
fn visit_local_source(&mut self, l: &mut LocalSource) {
noop_visit_local_source(l, self);
}
fn visit_mac(&mut self, _mac: &mut Mac) {
panic!("visit_mac disabled by default");
// N.B., see note about macros above. If you really want a visitor that
@ -231,6 +235,10 @@ pub trait MutVisitor: Sized {
noop_visit_arg(a, self);
}
fn visit_arg_source(&mut self, a: &mut ArgSource) {
noop_visit_arg_source(a, self);
}
fn visit_generics(&mut self, generics: &mut Generics) {
noop_visit_generics(generics, self);
}
@ -511,13 +519,17 @@ pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(args: &mut Parenth
}
pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
let Local { id, pat, ty, init, span, attrs } = local.deref_mut();
let Local { id, pat, ty, init, span, attrs, source } = local.deref_mut();
vis.visit_id(id);
vis.visit_pat(pat);
visit_opt(ty, |ty| vis.visit_ty(ty));
visit_opt(init, |init| vis.visit_expr(init));
vis.visit_span(span);
visit_thin_attrs(attrs, vis);
vis.visit_local_source(source);
}
pub fn noop_visit_local_source<T: MutVisitor>(_local_source: &mut LocalSource, _vis: &mut T) {
}
pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
@ -556,10 +568,18 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
vis.visit_span(span);
}
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty }: &mut Arg, vis: &mut T) {
pub fn noop_visit_arg<T: MutVisitor>(Arg { id, pat, ty, source }: &mut Arg, vis: &mut T) {
vis.visit_id(id);
vis.visit_pat(pat);
vis.visit_ty(ty);
vis.visit_arg_source(source);
}
pub fn noop_visit_arg_source<T: MutVisitor>(source: &mut ArgSource, vis: &mut T) {
match source {
ArgSource::Normal => {},
ArgSource::AsyncFn(pat) => vis.visit_pat(pat),
}
}
pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
@ -671,9 +691,17 @@ pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis:
pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T) {
match asyncness {
IsAsync::Async { closure_id, return_impl_trait_id } => {
IsAsync::Async { closure_id, return_impl_trait_id, ref mut arguments } => {
vis.visit_id(closure_id);
vis.visit_id(return_impl_trait_id);
for AsyncArgument { ident, arg, stmt } in arguments.iter_mut() {
vis.visit_ident(ident);
vis.visit_arg(arg);
visit_clobber(stmt, |stmt| {
vis.flat_map_stmt(stmt)
.expect_one("expected visitor to produce exactly one item")
});
}
}
IsAsync::NotAsync => {}
}

View File

@ -1,7 +1,7 @@
use crate::ast::{AngleBracketedArgs, ParenthesizedArgs, AttrStyle, BareFnTy};
use crate::ast::{AngleBracketedArgs, AsyncArgument, ParenthesizedArgs, AttrStyle, BareFnTy};
use crate::ast::{GenericBound, TraitBoundModifier};
use crate::ast::Unsafety;
use crate::ast::{Mod, AnonConst, Arg, Arm, Guard, Attribute, BindingMode, TraitItemKind};
use crate::ast::{Mod, AnonConst, Arg, ArgSource, Arm, Guard, Attribute, BindingMode, TraitItemKind};
use crate::ast::Block;
use crate::ast::{BlockCheckMode, CaptureBy, Movability};
use crate::ast::{Constness, Crate};
@ -14,7 +14,7 @@ use crate::ast::{GenericParam, GenericParamKind};
use crate::ast::GenericArg;
use crate::ast::{Ident, ImplItem, IsAsync, IsAuto, Item, ItemKind};
use crate::ast::{Label, Lifetime, Lit, LitKind};
use crate::ast::Local;
use crate::ast::{Local, LocalSource};
use crate::ast::MacStmtStyle;
use crate::ast::{Mac, Mac_, MacDelimiter};
use crate::ast::{MutTy, Mutability};
@ -550,7 +550,7 @@ fn dummy_arg(span: Span) -> Arg {
span,
id: ast::DUMMY_NODE_ID
};
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID }
Arg { ty: P(ty), pat: pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal }
}
#[derive(Copy, Clone, Debug)]
@ -1517,6 +1517,7 @@ impl<'a> Parser<'a> {
IsAsync::Async {
closure_id: ast::DUMMY_NODE_ID,
return_impl_trait_id: ast::DUMMY_NODE_ID,
arguments: Vec::new(),
}
} else {
IsAsync::NotAsync
@ -1575,7 +1576,7 @@ impl<'a> Parser<'a> {
// trait item macro.
(keywords::Invalid.ident(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
} else {
let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?;
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
@ -1589,6 +1590,7 @@ impl<'a> Parser<'a> {
p.parse_arg_general(p.span.rust_2018(), true, false)
})?;
generics.where_clause = self.parse_where_clause()?;
self.construct_async_arguments(&mut asyncness, &d);
let sig = ast::MethodSig {
header: FnHeader {
@ -2124,7 +2126,7 @@ impl<'a> Parser<'a> {
}
};
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID })
Ok(Arg { ty, pat, id: ast::DUMMY_NODE_ID, source: ast::ArgSource::Normal })
}
/// Parses a single function argument.
@ -2147,7 +2149,8 @@ impl<'a> Parser<'a> {
Ok(Arg {
ty: t,
pat,
id: ast::DUMMY_NODE_ID
id: ast::DUMMY_NODE_ID,
source: ast::ArgSource::Normal,
})
}
@ -5029,6 +5032,7 @@ impl<'a> Parser<'a> {
id: ast::DUMMY_NODE_ID,
span: lo.to(hi),
attrs,
source: LocalSource::Normal,
}))
}
@ -6566,7 +6570,7 @@ impl<'a> Parser<'a> {
/// Parses an item-position function declaration.
fn parse_item_fn(&mut self,
unsafety: Unsafety,
asyncness: Spanned<IsAsync>,
mut asyncness: Spanned<IsAsync>,
constness: Spanned<Constness>,
abi: Abi)
-> PResult<'a, ItemInfo> {
@ -6575,6 +6579,7 @@ impl<'a> Parser<'a> {
let decl = self.parse_fn_decl(allow_c_variadic)?;
generics.where_clause = self.parse_where_clause()?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
self.construct_async_arguments(&mut asyncness, &decl);
let header = FnHeader { unsafety, asyncness, constness, abi };
Ok((ident, ItemKind::Fn(decl, header, generics, body), Some(inner_attrs)))
}
@ -6755,11 +6760,12 @@ impl<'a> Parser<'a> {
Ok((keywords::Invalid.ident(), vec![], ast::Generics::default(),
ast::ImplItemKind::Macro(mac)))
} else {
let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
let (constness, unsafety, mut asyncness, abi) = self.parse_fn_front_matter()?;
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
let decl = self.parse_fn_decl_with_self(|p| p.parse_arg())?;
generics.where_clause = self.parse_where_clause()?;
self.construct_async_arguments(&mut asyncness, &decl);
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
let header = ast::FnHeader { abi, unsafety, constness, asyncness };
@ -8181,6 +8187,7 @@ impl<'a> Parser<'a> {
respan(async_span, IsAsync::Async {
closure_id: ast::DUMMY_NODE_ID,
return_impl_trait_id: ast::DUMMY_NODE_ID,
arguments: Vec::new(),
}),
respan(fn_span, Constness::NotConst),
Abi::Rust)?;
@ -8826,6 +8833,68 @@ impl<'a> Parser<'a> {
}
}
}
/// When lowering a `async fn` to the HIR, we need to move all of the arguments of the function
/// into the generated closure so that they are dropped when the future is polled and not when
/// it is created.
///
/// The arguments of the function are replaced in HIR lowering with the arguments created by
/// this function and the statements created here are inserted at the top of the closure body.
fn construct_async_arguments(&mut self, asyncness: &mut Spanned<IsAsync>, decl: &FnDecl) {
if let IsAsync::Async { ref mut arguments, .. } = asyncness.node {
for (index, input) in decl.inputs.iter().enumerate() {
let id = ast::DUMMY_NODE_ID;
let span = input.pat.span;
// Construct a name for our temporary argument.
let name = format!("__arg{}", index);
let ident = Ident::from_str(&name);
// Construct an argument representing `__argN: <ty>` to replace the argument of the
// async function.
let arg = Arg {
ty: input.ty.clone(),
id,
pat: P(Pat {
id,
node: PatKind::Ident(
BindingMode::ByValue(Mutability::Immutable), ident, None,
),
span,
}),
source: ArgSource::AsyncFn(input.pat.clone()),
};
// Construct a `let <pat> = __argN;` statement to insert at the top of the
// async closure.
let local = P(Local {
pat: input.pat.clone(),
// We explicitly do not specify the type for this statement. When the user's
// argument type is `impl Trait` then this would require the
// `impl_trait_in_bindings` feature to also be present for that same type to
// be valid in this binding. At the time of writing (13 Mar 19),
// `impl_trait_in_bindings` is not stable.
ty: None,
init: Some(P(Expr {
id,
node: ExprKind::Path(None, ast::Path {
span,
segments: vec![PathSegment { ident, id, args: None }],
}),
span,
attrs: ThinVec::new(),
})),
id,
span,
attrs: ThinVec::new(),
source: LocalSource::AsyncFn,
});
let stmt = Stmt { id, node: StmtKind::Local(local), span, };
arguments.push(AsyncArgument { ident, arg, stmt });
}
}
}
}
pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {

View File

@ -372,7 +372,7 @@ pub fn vis_to_string(v: &ast::Visibility) -> String {
}
pub fn fun_to_string(decl: &ast::FnDecl,
header: ast::FnHeader,
header: &ast::FnHeader,
name: ast::Ident,
generics: &ast::Generics)
-> String {
@ -1133,7 +1133,7 @@ impl<'a> State<'a> {
match item.node {
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
self.head("")?;
self.print_fn(decl, ast::FnHeader::default(),
self.print_fn(decl, &ast::FnHeader::default(),
Some(item.ident),
generics, &item.vis)?;
self.end()?; // end head-ibox
@ -1263,7 +1263,7 @@ impl<'a> State<'a> {
self.s.word(";")?;
self.end()?; // end the outer cbox
}
ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => {
ast::ItemKind::Fn(ref decl, ref header, ref param_names, ref body) => {
self.head("")?;
self.print_fn(
decl,
@ -1615,7 +1615,7 @@ impl<'a> State<'a> {
vis: &ast::Visibility)
-> io::Result<()> {
self.print_fn(&m.decl,
m.header,
&m.header,
Some(ident),
&generics,
vis)
@ -2213,7 +2213,7 @@ impl<'a> State<'a> {
self.bclose_(expr.span, INDENT_UNIT)?;
}
ast::ExprKind::Closure(
capture_clause, asyncness, movability, ref decl, ref body, _) => {
capture_clause, ref asyncness, movability, ref decl, ref body, _) => {
self.print_movability(movability)?;
self.print_asyncness(asyncness)?;
self.print_capture_clause(capture_clause)?;
@ -2798,7 +2798,7 @@ impl<'a> State<'a> {
pub fn print_fn(&mut self,
decl: &ast::FnDecl,
header: ast::FnHeader,
header: &ast::FnHeader,
name: Option<ast::Ident>,
generics: &ast::Generics,
vis: &ast::Visibility) -> io::Result<()> {
@ -2853,8 +2853,7 @@ impl<'a> State<'a> {
}
}
pub fn print_asyncness(&mut self, asyncness: ast::IsAsync)
-> io::Result<()> {
pub fn print_asyncness(&mut self, asyncness: &ast::IsAsync) -> io::Result<()> {
if asyncness.is_async() {
self.word_nbsp("async")?;
}
@ -3126,7 +3125,7 @@ impl<'a> State<'a> {
span: syntax_pos::DUMMY_SP,
};
self.print_fn(decl,
ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
&ast::FnHeader { unsafety, abi, ..ast::FnHeader::default() },
name,
&generics,
&source_map::dummy_spanned(ast::VisibilityKind::Inherited))?;
@ -3189,7 +3188,7 @@ impl<'a> State<'a> {
}
pub fn print_fn_header_info(&mut self,
header: ast::FnHeader,
header: &ast::FnHeader,
vis: &ast::Visibility) -> io::Result<()> {
self.s.word(visibility_qualified(vis, ""))?;
@ -3198,7 +3197,7 @@ impl<'a> State<'a> {
ast::Constness::Const => self.word_nbsp("const")?
}
self.print_asyncness(header.asyncness.node)?;
self.print_asyncness(&header.asyncness.node)?;
self.print_unsafety(header.unsafety)?;
if header.abi != Abi::Rust {
@ -3247,7 +3246,7 @@ mod tests {
assert_eq!(
fun_to_string(
&decl,
ast::FnHeader {
&ast::FnHeader {
unsafety: ast::Unsafety::Normal,
constness: source_map::dummy_spanned(ast::Constness::NotConst),
asyncness: source_map::dummy_spanned(ast::IsAsync::NotAsync),

View File

@ -544,6 +544,9 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR
pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
for argument in &function_declaration.inputs {
visitor.visit_pat(&argument.pat);
if let ArgSource::AsyncFn(pat) = &argument.source {
visitor.visit_pat(pat);
}
visitor.visit_ty(&argument.ty)
}
visitor.visit_fn_ret_ty(&function_declaration.output)

View File

@ -128,6 +128,7 @@ fn stmt_let_undescore(cx: &mut ExtCtxt<'_>, sp: Span, expr: P<ast::Expr>) -> ast
id: ast::DUMMY_NODE_ID,
span: sp,
attrs: ThinVec::new(),
source: ast::LocalSource::Normal,
});
ast::Stmt {
id: ast::DUMMY_NODE_ID,

View File

@ -24,11 +24,11 @@ struct SyntaxContextData {
outer_mark: Mark,
transparency: Transparency,
prev_ctxt: SyntaxContext,
// This context, but with all transparent and semi-transparent marks filtered away.
/// This context, but with all transparent and semi-transparent marks filtered away.
opaque: SyntaxContext,
// This context, but with all transparent marks filtered away.
/// This context, but with all transparent marks filtered away.
opaque_and_semitransparent: SyntaxContext,
// Name of the crate to which `$crate` with this context would resolve.
/// Name of the crate to which `$crate` with this context would resolve.
dollar_crate_name: Symbol,
}

View File

@ -3,7 +3,6 @@
// ignoring this test until MIR codegen has taken over completely
// ignore-test
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,5 +1,4 @@
// compile-flags:-Zprint-mono-items=eager
// ignore-tidy-linelength
#![feature(start)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=lazy
#![deny(dead_code)]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=lazy
// N.B., we do not expect *any* monomorphization to be generated here.

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=eager
#![crate_type="lib"]

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// We specify -Z incremental here because we want to test the partitioning for
// incremental compilation
// compile-flags:-Zprint-mono-items=lazy -Zincremental=tmp/partitioning-tests/statics

View File

@ -1,5 +1,4 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
#![crate_type = "lib"]

View File

@ -2,7 +2,6 @@
// before 7.0, then backported to the Rust LLVM fork. It tests that
// optimized enum debug info accurately reflects the enum layout.
// ignore-tidy-linelength
// ignore-windows
// min-system-llvm-version 8.0

View File

@ -2,7 +2,6 @@
// before 7.0, then backported to the Rust LLVM fork. It tests that
// debug info for tagged (ordinary) enums is properly emitted.
// ignore-tidy-linelength
// ignore-windows
// min-system-llvm-version 8.0

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// ignore-windows
// compile-flags: -g -C no-prepopulate-passes

View File

@ -1,7 +1,6 @@
// This test depends on a patch that was committed to upstream LLVM
// before 4.0, formerly backported to the Rust LLVM fork.
// ignore-tidy-linelength
// ignore-windows
// ignore-macos

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// ignore-windows
// ignore-macos

View File

@ -1,5 +1,4 @@
// compile-flags: -g -C no-prepopulate-passes
// ignore-tidy-linelength
#![crate_type = "lib"]

View File

@ -1,5 +1,4 @@
// compile-flags: -g -C no-prepopulate-passes
// ignore-tidy-linelength
#![crate_type = "lib"]

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// This test is for *-windows-msvc only.
// ignore-android
// ignore-bitrig

View File

@ -1,5 +1,4 @@
// compile-flags: -C no-prepopulate-passes
// ignore-tidy-linelength
#![crate_type = "lib"]

View File

@ -1,5 +1,4 @@
// ignore-windows
// ignore-tidy-linelength
// compile-flags: -g -C metadata=foo -C no-prepopulate-passes
// aux-build:xcrate-generic.rs

View File

@ -1,7 +1,6 @@
// This test depends on a patch that was committed to upstream LLVM
// after 5.0, then backported to the Rust LLVM fork.
// ignore-tidy-linelength
// ignore-windows
// ignore-macos

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
// min-system-llvm-version: 8.0
// min-gdb-version: 8.2

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// ignore-lldb: FIXME(#27089)
// min-lldb-version: 310

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// ignore-lldb
// Require LLVM with DW_TAG_variant_part and a gdb that can read it.

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// Require LLVM with DW_TAG_variant_part and a gdb and lldb that can
// read it.
// min-system-llvm-version: 8.0

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
//[rpass1] compile-flags: -g
//[rpass2] compile-flags: -g
//[rpass3] compile-flags: -g --remap-path-prefix={{src-base}}=/the/src

View File

@ -5,8 +5,6 @@
// so subtle breakage in them can leave a quite hard-to-find trail of
// destruction.
// ignore-tidy-linelength
fn main() {
let nodrop_x = false;
let nodrop_y;

View File

@ -20,7 +20,7 @@ fn foo<T: Copy>(_t: T, q: &i32) -> i32 {
// ...
// bb0: {
// ...
// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 29 }];
// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 31 }];
// ...
// _4 = &_3;
// ...

View File

@ -16,7 +16,7 @@ fn foo<T: Copy>(_t: T, q: i32) -> i32 {
// ...
// bb0: {
// ...
// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 13 }];
// _3 = [closure@HirId { owner: DefIndex(0:4), local_id: 15 }];
// ...
// _4 = &_3;
// ...

View File

@ -5,7 +5,6 @@
// compile-flags:-Zborrowck=mir -Zverbose
// ^^^^^^^^^ force compiler to dump more region information
// ignore-tidy-linelength
#![allow(warnings)]

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
fn main() {
let a = 0;
{

View File

@ -12,7 +12,7 @@ fn expect_free_supply_free<'x>(x: &'x u32) {
x.push(22_u32);
// ...since we now know the type of `y` and can resolve the method call.
y.wrapping_add(1);
let _ = y.wrapping_add(1);
});
}

View File

@ -0,0 +1,184 @@
// aux-build:arc_wake.rs
// edition:2018
// run-pass
#![allow(unused_variables)]
#![feature(async_await, await_macro, futures_api)]
extern crate arc_wake;
use arc_wake::ArcWake;
use std::cell::RefCell;
use std::future::Future;
use std::marker::PhantomData;
use std::sync::Arc;
use std::rc::Rc;
use std::task::Context;
struct EmptyWaker;
impl ArcWake for EmptyWaker {
fn wake(self: Arc<Self>) {}
}
#[derive(Debug, Eq, PartialEq)]
enum DropOrder {
Function,
Val(&'static str),
}
type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
struct D(&'static str, DropOrderListPtr);
impl Drop for D {
fn drop(&mut self) {
self.1.borrow_mut().push(DropOrder::Val(self.0));
}
}
/// Check that unused bindings are dropped after the function is polled.
async fn foo(x: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore patterns are dropped after the function is polled.
async fn bar(x: D, _: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore patterns within more complex patterns are dropped after the function
/// is polled.
async fn baz((x, _): (D, D)) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore and unused bindings within and outwith more complex patterns are dropped
/// after the function is polled.
async fn foobar(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
struct Foo;
impl Foo {
/// Check that unused bindings are dropped after the method is polled.
async fn foo(x: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore patterns are dropped after the method is polled.
async fn bar(x: D, _: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore patterns within more complex patterns are dropped after the method
/// is polled.
async fn baz((x, _): (D, D)) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore and unused bindings within and outwith more complex patterns are
/// dropped after the method is polled.
async fn foobar(x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
}
struct Bar<'a>(PhantomData<&'a ()>);
impl<'a> Bar<'a> {
/// Check that unused bindings are dropped after the method with self is polled.
async fn foo(&'a self, x: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore patterns are dropped after the method with self is polled.
async fn bar(&'a self, x: D, _: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore patterns within more complex patterns are dropped after the method
/// with self is polled.
async fn baz(&'a self, (x, _): (D, D)) {
x.1.borrow_mut().push(DropOrder::Function);
}
/// Check that underscore and unused bindings within and outwith more complex patterns are
/// dropped after the method with self is polled.
async fn foobar(&'a self, x: D, (a, _, _c): (D, D, D), _: D, _y: D) {
x.1.borrow_mut().push(DropOrder::Function);
}
}
fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
f: impl FnOnce(DropOrderListPtr) -> Fut,
expected_order: &[DropOrder],
) {
let empty = Arc::new(EmptyWaker);
let waker = ArcWake::into_waker(empty);
let mut cx = Context::from_waker(&waker);
let actual_order = Rc::new(RefCell::new(Vec::new()));
let mut fut = Box::pin(f(actual_order.clone()));
let _ = fut.as_mut().poll(&mut cx);
assert_eq!(*actual_order.borrow(), expected_order);
}
fn main() {
use DropOrder::*;
// At time of writing (23/04/19), the `bar` and `foobar` tests do not output the same order as
// the equivalent non-async functions. This is because the drop order of captured variables
// doesn't match the drop order of arguments in a function.
// Free functions (see doc comment on function for what it tests).
assert_drop_order_after_poll(|l| foo(D("x", l.clone()), D("_y", l.clone())),
&[Function, Val("_y"), Val("x")]);
assert_drop_order_after_poll(|l| bar(D("x", l.clone()), D("_", l.clone())),
&[Function, Val("x"), Val("_")]);
assert_drop_order_after_poll(|l| baz((D("x", l.clone()), D("_", l.clone()))),
&[Function, Val("x"), Val("_")]);
assert_drop_order_after_poll(|l| {
foobar(
D("x", l.clone()),
(D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
D("_", l.clone()),
D("_y", l.clone()),
)
}, &[Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_")]);
// Methods w/out self (see doc comment on function for what it tests).
assert_drop_order_after_poll(|l| Foo::foo(D("x", l.clone()), D("_y", l.clone())),
&[Function, Val("_y"), Val("x")]);
assert_drop_order_after_poll(|l| Foo::bar(D("x", l.clone()), D("_", l.clone())),
&[Function, Val("x"), Val("_")]);
assert_drop_order_after_poll(|l| Foo::baz((D("x", l.clone()), D("_", l.clone()))),
&[Function, Val("x"), Val("_")]);
assert_drop_order_after_poll(|l| {
Foo::foobar(
D("x", l.clone()),
(D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
D("_", l.clone()),
D("_y", l.clone()),
)
}, &[Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_")]);
// Methods (see doc comment on function for what it tests).
let b = Bar(Default::default());
assert_drop_order_after_poll(|l| b.foo(D("x", l.clone()), D("_y", l.clone())),
&[Function, Val("_y"), Val("x")]);
assert_drop_order_after_poll(|l| b.bar(D("x", l.clone()), D("_", l.clone())),
&[Function, Val("x"), Val("_")]);
assert_drop_order_after_poll(|l| b.baz((D("x", l.clone()), D("_", l.clone()))),
&[Function, Val("x"), Val("_")]);
assert_drop_order_after_poll(|l| {
b.foobar(
D("x", l.clone()),
(D("a", l.clone()), D("_", l.clone()), D("_c", l.clone())),
D("_", l.clone()),
D("_y", l.clone()),
)
}, &[Function, Val("_y"), Val("_c"), Val("a"), Val("x"), Val("_"), Val("_")]);
}

View File

@ -3,8 +3,8 @@
// this file has some special \r\n endings (use xxd to see them)
fn main() {assert_eq!(b"", b"\
fn main() {assert_eq!(b"", b"\
");
assert_eq!(b"\n", b"
assert_eq!(b"\n", b"
");
}

View File

@ -1,5 +1,3 @@
// ignore-tidy-end-whitespace
#![deny(intra_doc_link_resolution_failure)]
// An error in calculating spans while reporting intra-doc link resolution errors caused rustdoc to

View File

@ -1,11 +1,11 @@
error: `[i]` cannot be resolved, ignoring it...
--> $DIR/intra-link-span-ice-55723.rs:11:10
--> $DIR/intra-link-span-ice-55723.rs:9:10
|
LL | /// arr[i]
| ^ cannot be resolved, ignoring
|
note: lint level defined here
--> $DIR/intra-link-span-ice-55723.rs:3:9
--> $DIR/intra-link-span-ice-55723.rs:1:9
|
LL | #![deny(intra_doc_link_resolution_failure)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags: --document-private-items
// @has 'empty_mod_private/index.html' '//a[@href="foo/index.html"]' 'foo'

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// compile-flags:-Z unstable-options --extern-html-root-url core=https://example.com/core/0.1.0
// @has extern_html_root_url/index.html

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
#![crate_name = "foo"]
// @has foo/struct.Foo.html

View File

@ -1,4 +1,3 @@
// ignore-tidy-linelength
// compile-flags: --document-private-items
#![crate_name = "foo"]

View File

@ -1,5 +1,5 @@
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-activation-sharing-interference.rs:32:15
--> $DIR/two-phase-activation-sharing-interference.rs:30:15
|
LL | let y = &mut x;
| ------ mutable borrow occurs here
@ -10,7 +10,7 @@ LL | *y += 1;
| ------- mutable borrow later used here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-activation-sharing-interference.rs:40:13
--> $DIR/two-phase-activation-sharing-interference.rs:38:13
|
LL | let y = &mut x;
| ------ mutable borrow occurs here
@ -21,7 +21,7 @@ LL | *y += 1;
| ------- mutable borrow later used here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-activation-sharing-interference.rs:51:13
--> $DIR/two-phase-activation-sharing-interference.rs:49:13
|
LL | let y = &mut x;
| ------ mutable borrow occurs here
@ -32,7 +32,7 @@ LL | *y += 1;
| ------- mutable borrow later used here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/two-phase-activation-sharing-interference.rs:62:14
--> $DIR/two-phase-activation-sharing-interference.rs:60:14
|
LL | let y = &mut x;
| ------ mutable borrow occurs here

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// revisions: nll_target
// The following revisions are disabled due to missing support from two-phase beyond autorefs

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
#![feature(const_indexing)]
const FOO: [usize; 3] = [1, 2, 3];

View File

@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed
--> $DIR/const-array-oob.rs:8:19
--> $DIR/const-array-oob.rs:6:19
|
LL | const BLUB: [u32; FOO[4]] = [5, 6];
| ^^^^^^ index out of bounds: the len is 3 but the index is 4

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// run-pass
#![deny(deprecated_in_future)]

Some files were not shown because too many files have changed in this diff Show More