diff --git a/Cargo.toml b/Cargo.toml index 3d003ea..b46acae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,3 +28,6 @@ trybuild = { version = "1.0", features = ["diff"] } macrotest = "1.0" # needed for macrotest, have to enable verbatim feature to be able to format `&raw` expressions. prettyplease = { version = "0.2", features = ["verbatim"] } + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(NO_UI_TESTS)', 'cfg(NO_ALLOC_FAIL_TESTS)'] } diff --git a/README.md b/README.md index c931474..f3fdc12 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ This library allows you to do in-place initialization safely. This library requires unstable features when the `alloc` or `std` features are enabled and thus can only be used with a nightly compiler. The internally used features are: - `allocator_api` -- `new_uninit` - `get_mut_unchecked` When enabling the `alloc` or `std` feature, the user will be required to activate these features: diff --git a/examples/big_struct_in_place.rs b/examples/big_struct_in_place.rs index b8861f1..3024de6 100644 --- a/examples/big_struct_in_place.rs +++ b/examples/big_struct_in_place.rs @@ -1,7 +1,3 @@ -#![feature(allocator_api)] - -use std::convert::Infallible; - use pinned_init::*; // Struct with size over 1GiB diff --git a/examples/error.rs b/examples/error.rs index 08e9ddc..174e405 100644 --- a/examples/error.rs +++ b/examples/error.rs @@ -1,17 +1,20 @@ -#![feature(allocator_api)] +#![cfg_attr(feature = "alloc", feature(allocator_api))] use core::convert::Infallible; + +#[cfg(feature = "alloc")] use std::alloc::AllocError; #[derive(Debug)] pub struct Error; impl From for Error { - fn from(_: Infallible) -> Self { - Self + fn from(e: Infallible) -> Self { + match e {} } } +#[cfg(feature = "alloc")] impl From for Error { fn from(_: AllocError) -> Self { Self diff --git a/src/__internal.rs b/src/__internal.rs index e63228d..b65c64e 100644 --- a/src/__internal.rs +++ b/src/__internal.rs @@ -261,3 +261,32 @@ impl OnlyCallFromDrop { Self(()) } } + +/// Initializer that always fails. +/// +/// Used by [`assert_pinned!`]. +/// +/// [`assert_pinned!`]: crate::assert_pinned +pub struct AlwaysFail { + _t: PhantomData, +} + +impl AlwaysFail { + /// Creates a new initializer that always fails. + pub fn new() -> Self { + Self { _t: PhantomData } + } +} + +impl Default for AlwaysFail { + fn default() -> Self { + Self::new() + } +} + +// SAFETY: `__pinned_init` always fails, which is always okay. +unsafe impl PinInit for AlwaysFail { + unsafe fn __pinned_init(self, _slot: *mut T) -> Result<(), ()> { + Err(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 3dc2c6b..5a823b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,6 @@ //! This library requires unstable features when the `alloc` or `std` features are enabled and thus //! can only be used with a nightly compiler. The internally used features are: //! - `allocator_api` -//! - `new_uninit` //! - `get_mut_unchecked` //! //! When enabling the `alloc` or `std` feature, the user will be required to activate these features: @@ -237,7 +236,6 @@ #![forbid(missing_docs, unsafe_op_in_unsafe_fn)] #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "alloc", feature(allocator_api))] -#![cfg_attr(feature = "alloc", feature(new_uninit))] #![cfg_attr(feature = "alloc", feature(get_mut_unchecked))] #[cfg(feature = "alloc")] @@ -747,6 +745,75 @@ macro_rules! try_init { }; } +/// Asserts that a field on a struct using `#[pin_data]` is marked with `#[pin]` ie. that it is +/// structurally pinned. +/// +/// # Example +/// +/// This will succeed: +/// ``` +/// use pinned_init::*; +/// #[pin_data] +/// struct MyStruct { +/// #[pin] +/// some_field: u64, +/// } +/// +/// assert_pinned!(MyStruct, some_field, u64); +/// ``` +/// +/// This will fail: +// TODO: replace with `compile_fail` when supported. +/// ```ignore +/// # use pinned_init::*; +/// #[pin_data] +/// struct MyStruct { +/// some_field: u64, +/// } +/// +/// assert_pinned!(MyStruct, some_field, u64); +/// ``` +/// +/// Some uses of the macro may trigger the `can't use generic parameters from outer item` error. To +/// work around this, you may pass the `inline` parameter to the macro. The `inline` parameter can +/// only be used when the macro is invoked from a function body. +/// ``` +/// # use pinned_init::*; +/// # use core::pin::Pin; +/// #[pin_data] +/// struct Foo { +/// #[pin] +/// elem: T, +/// } +/// +/// impl Foo { +/// fn project(self: Pin<&mut Self>) -> Pin<&mut T> { +/// assert_pinned!(Foo, elem, T, inline); +/// +/// // SAFETY: The field is structurally pinned. +/// unsafe { self.map_unchecked_mut(|me| &mut me.elem) } +/// } +/// } +/// ``` +#[macro_export] +macro_rules! assert_pinned { + ($ty:ty, $field:ident, $field_ty:ty, inline) => { + let _ = move |ptr: *mut $field_ty| { + // SAFETY: This code is unreachable. + let data = unsafe { <$ty as $crate::__internal::HasPinData>::__pin_data() }; + let init = $crate::__internal::AlwaysFail::<$field_ty>::new(); + // SAFETY: This code is unreachable. + unsafe { data.$field(ptr, init) }.ok(); + }; + }; + + ($ty:ty, $field:ident, $field_ty:ty) => { + const _: () = { + $crate::assert_pinned!($ty, $field, $field_ty, inline); + }; + }; +} + /// A pin-initializer for the type `T`. /// /// To use this initializer, you will need a suitable memory location that can hold a `T`. This can @@ -826,11 +893,8 @@ where let val = unsafe { &mut *slot }; // SAFETY: `slot` is considered pinned. let val = unsafe { Pin::new_unchecked(val) }; - (self.1)(val).map_err(|e| { - // SAFETY: `slot` was initialized above. - unsafe { core::ptr::drop_in_place(slot) }; - e - }) + // SAFETY: `slot` was initialized above. + (self.1)(val).inspect_err(|_| unsafe { core::ptr::drop_in_place(slot) }) } } @@ -924,11 +988,9 @@ where // SAFETY: All requirements fulfilled since this function is `__init`. unsafe { self.0.__pinned_init(slot)? }; // SAFETY: The above call initialized `slot` and we still have unique access. - (self.1)(unsafe { &mut *slot }).map_err(|e| { + (self.1)(unsafe { &mut *slot }).inspect_err(|_| // SAFETY: `slot` was initialized above. - unsafe { core::ptr::drop_in_place(slot) }; - e - }) + unsafe { core::ptr::drop_in_place(slot) }) } } @@ -1144,13 +1206,7 @@ impl InPlaceInit for Box { where E: From, { - let mut this = Box::try_new_uninit()?; - let slot = this.as_mut_ptr(); - // SAFETY: When init errors/panics, slot will get deallocated but not dropped, - // slot is valid and will not be moved, because we pin it later. - unsafe { init.__pinned_init(slot)? }; - // SAFETY: All fields have been initialized. - Ok(unsafe { this.assume_init() }.into()) + Box::try_new_uninit()?.write_pin_init(init) } #[inline] @@ -1158,13 +1214,7 @@ impl InPlaceInit for Box { where E: From, { - let mut this = Box::try_new_uninit()?; - let slot = this.as_mut_ptr(); - // SAFETY: When init errors/panics, slot will get deallocated but not dropped, - // slot is valid. - unsafe { init.__init(slot)? }; - // SAFETY: All fields have been initialized. - Ok(unsafe { this.assume_init() }) + Box::try_new_uninit()?.write_init(init) } } @@ -1175,14 +1225,7 @@ impl InPlaceInit for Arc { where E: From, { - let mut this = Arc::try_new_uninit()?; - let slot = unsafe { Arc::get_mut_unchecked(&mut this) }; - let slot = slot.as_mut_ptr(); - // SAFETY: When init errors/panics, slot will get deallocated but not dropped, - // slot is valid and will not be moved, because we pin it later. - unsafe { init.__pinned_init(slot)? }; - // SAFETY: All fields have been initialized and this is the only `Arc` to that data. - Ok(unsafe { Pin::new_unchecked(this.assume_init()) }) + Arc::try_new_uninit()?.write_pin_init(init) } #[inline] @@ -1190,14 +1233,71 @@ impl InPlaceInit for Arc { where E: From, { - let mut this = Arc::try_new_uninit()?; - let slot = unsafe { Arc::get_mut_unchecked(&mut this) }; + Arc::try_new_uninit()?.write_init(init) + } +} + +/// Smart pointer containing uninitialized memory and that can write a value. +pub trait InPlaceWrite { + /// The type `Self` turns into when the contents are initialized. + type Initialized; + + /// Use the given initializer to write a value into `self`. + /// + /// Does not drop the current value and considers it as uninitialized memory. + fn write_init(self, init: impl Init) -> Result; + + /// Use the given pin-initializer to write a value into `self`. + /// + /// Does not drop the current value and considers it as uninitialized memory. + fn write_pin_init(self, init: impl PinInit) -> Result, E>; +} + +#[cfg(feature = "alloc")] +impl InPlaceWrite for Box> { + type Initialized = Box; + + fn write_init(mut self, init: impl Init) -> Result { + let slot = self.as_mut_ptr(); + // SAFETY: When init errors/panics, slot will get deallocated but not dropped, + // slot is valid. + unsafe { init.__init(slot)? }; + // SAFETY: All fields have been initialized. + Ok(unsafe { self.assume_init() }) + } + + fn write_pin_init(mut self, init: impl PinInit) -> Result, E> { + let slot = self.as_mut_ptr(); + // SAFETY: When init errors/panics, slot will get deallocated but not dropped, + // slot is valid and will not be moved, because we pin it later. + unsafe { init.__pinned_init(slot)? }; + // SAFETY: All fields have been initialized. + Ok(unsafe { self.assume_init() }.into()) + } +} + +#[cfg(feature = "alloc")] +impl InPlaceWrite for Arc> { + type Initialized = Arc; + + fn write_init(mut self, init: impl Init) -> Result { + let slot = unsafe { Arc::get_mut_unchecked(&mut self) }; let slot = slot.as_mut_ptr(); // SAFETY: When init errors/panics, slot will get deallocated but not dropped, // slot is valid. unsafe { init.__init(slot)? }; // SAFETY: All fields have been initialized. - Ok(unsafe { this.assume_init() }) + Ok(unsafe { self.assume_init() }) + } + + fn write_pin_init(mut self, init: impl PinInit) -> Result, E> { + let slot = unsafe { Arc::get_mut_unchecked(&mut self) }; + let slot = slot.as_mut_ptr(); + // SAFETY: When init errors/panics, slot will get deallocated but not dropped, + // slot is valid and will not be moved, because we pin it later. + unsafe { init.__pinned_init(slot)? }; + // SAFETY: All fields have been initialized and this is the only `Arc` to that data. + Ok(unsafe { Pin::new_unchecked(self.assume_init()) }) } } diff --git a/src/macros.rs b/src/macros.rs index fbd66b5..04d4048 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -145,7 +145,7 @@ //! } //! } //! // Implement the internal `PinData` trait that marks the pin-data struct as a pin-data -//! // struct. This is important to ensure that no user can implement a rouge `__pin_data` +//! // struct. This is important to ensure that no user can implement a rogue `__pin_data` //! // function without using `unsafe`. //! unsafe impl ::pinned_init::__internal::PinData for __ThePinData { //! type Datee = Bar; @@ -156,7 +156,7 @@ //! // case no such fields exist, hence this is almost empty. The two phantomdata fields exist //! // for two reasons: //! // - `__phantom`: every generic must be used, since we cannot really know which generics -//! // are used, we declere all and then use everything here once. +//! // are used, we declare all and then use everything here once. //! // - `__phantom_pin`: uses the `'__pin` lifetime and ensures that this struct is invariant //! // over it. The lifetime is needed to work around the limitation that trait bounds must //! // not be trivial, e.g. the user has a `#[pin] PhantomPinned` field -- this is @@ -250,7 +250,7 @@ //! // error type is `Infallible`) we will need to drop this field if there //! // is an error later. This `DropGuard` will drop the field when it gets //! // dropped and has not yet been forgotten. -//! let t = unsafe { +//! let __t_guard = unsafe { //! ::pinned_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).t)) //! }; //! // Expansion of `x: 0,`: @@ -261,14 +261,14 @@ //! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).x), x) }; //! } //! // We again create a `DropGuard`. -//! let x = unsafe { +//! let __x_guard = unsafe { //! ::pinned_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).x)) //! }; //! // Since initialization has successfully completed, we can now forget //! // the guards. This is not `mem::forget`, since we only have //! // `&DropGuard`. -//! ::core::mem::forget(x); -//! ::core::mem::forget(t); +//! ::core::mem::forget(__x_guard); +//! ::core::mem::forget(__t_guard); //! // Here we use the type checker to ensure that every field has been //! // initialized exactly once, since this is `if false` it will never get //! // executed, but still type-checked. @@ -461,16 +461,16 @@ //! { //! unsafe { ::core::ptr::write(::core::addr_of_mut!((*slot).a), a) }; //! } -//! let a = unsafe { +//! let __a_guard = unsafe { //! ::pinned_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).a)) //! }; //! let init = Bar::new(36); //! unsafe { data.b(::core::addr_of_mut!((*slot).b), b)? }; -//! let b = unsafe { +//! let __b_guard = unsafe { //! ::pinned_init::__internal::DropGuard::new(::core::addr_of_mut!((*slot).b)) //! }; -//! ::core::mem::forget(b); -//! ::core::mem::forget(a); +//! ::core::mem::forget(__b_guard); +//! ::core::mem::forget(__a_guard); //! #[allow(unreachable_code, clippy::diverging_sub_expression)] //! let _ = || { //! unsafe { @@ -1209,14 +1209,14 @@ macro_rules! __init_internal { // We use `paste!` to create new hygiene for `$field`. $crate::macros::paste! { // SAFETY: We forget the guard later when initialization has succeeded. - let [<$field>] = unsafe { + let [< __ $field _guard >] = unsafe { $crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) }; $crate::__init_internal!(init_slot($use_data): @data($data), @slot($slot), - @guards([<$field>], $($guards,)*), + @guards([< __ $field _guard >], $($guards,)*), @munch_fields($($rest)*), ); } @@ -1240,14 +1240,14 @@ macro_rules! __init_internal { // We use `paste!` to create new hygiene for `$field`. $crate::macros::paste! { // SAFETY: We forget the guard later when initialization has succeeded. - let [<$field>] = unsafe { + let [< __ $field _guard >] = unsafe { $crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) }; $crate::__init_internal!(init_slot(): @data($data), @slot($slot), - @guards([<$field>], $($guards,)*), + @guards([< __ $field _guard >], $($guards,)*), @munch_fields($($rest)*), ); } @@ -1272,14 +1272,14 @@ macro_rules! __init_internal { // We use `paste!` to create new hygiene for `$field`. $crate::macros::paste! { // SAFETY: We forget the guard later when initialization has succeeded. - let [<$field>] = unsafe { + let [< __ $field _guard >] = unsafe { $crate::__internal::DropGuard::new(::core::ptr::addr_of_mut!((*$slot).$field)) }; $crate::__init_internal!(init_slot($($use_data)?): @data($data), @slot($slot), - @guards([<$field>], $($guards,)*), + @guards([< __ $field _guard >], $($guards,)*), @munch_fields($($rest)*), ); } diff --git a/tests/const-generic-default.rs b/tests/const-generic-default.rs index 6f99654..3585274 100644 --- a/tests/const-generic-default.rs +++ b/tests/const-generic-default.rs @@ -1,5 +1,3 @@ -use std::convert::Infallible; - use pinned_init::*; #[pin_data] diff --git a/tests/ring_buf.rs b/tests/ring_buf.rs index d6b7d7e..8837d15 100644 --- a/tests/ring_buf.rs +++ b/tests/ring_buf.rs @@ -1,6 +1,6 @@ -#![feature(allocator_api)] +#![cfg_attr(feature = "alloc", feature(allocator_api))] + use core::{ - alloc::AllocError, convert::Infallible, marker::PhantomPinned, mem::MaybeUninit, @@ -14,6 +14,10 @@ use std::sync::Arc; mod mutex; use mutex::*; +#[path = "../examples/error.rs"] +mod error; +use error::Error; + #[pin_data(PinnedDrop)] pub struct RingBuffer { buffer: [MaybeUninit; SIZE], @@ -152,15 +156,15 @@ pub struct EvenU64 { } impl EvenU64 { - pub fn new2(value: u64) -> impl Init { + pub fn new2(value: u64) -> impl Init { try_init!(Self { info: "Hello world!".to_owned(), data: if value % 2 == 0 { value } else { - return Err(AllocError); + return Err(Error); }, - }? AllocError) + }? Error) } pub fn new(value: u64) -> impl Init { try_init!(Self { @@ -190,16 +194,10 @@ fn even_stack() { #[test] fn even_failing() { - assert!(matches!( - Box::try_pin_init(EvenU64::new2(3)), - Err(AllocError) - )); - assert!(matches!( - Arc::try_pin_init(EvenU64::new2(5)), - Err(AllocError) - )); - assert!(matches!(Box::try_init(EvenU64::new2(3)), Err(AllocError))); - assert!(matches!(Arc::try_init(EvenU64::new2(5)), Err(AllocError))); + assert!(matches!(Box::try_pin_init(EvenU64::new2(3)), Err(Error))); + assert!(matches!(Arc::try_pin_init(EvenU64::new2(5)), Err(Error))); + assert!(matches!(Box::try_init(EvenU64::new2(3)), Err(Error))); + assert!(matches!(Arc::try_init(EvenU64::new2(5)), Err(Error))); } #[test] diff --git a/tests/ui/compile-fail/init/missing_comma.stderr b/tests/ui/compile-fail/init/missing_comma.stderr index 8a3c63e..9e4c25d 100644 --- a/tests/ui/compile-fail/init/missing_comma.stderr +++ b/tests/ui/compile-fail/init/missing_comma.stderr @@ -1,4 +1,4 @@ -error: no rules expected the token `c` +error: no rules expected `c` --> tests/ui/compile-fail/init/missing_comma.rs:16:9 | 16 | c: Bar, @@ -10,7 +10,7 @@ note: while trying to match `,` | @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), | ^ -error: no rules expected the token `c` +error: no rules expected `c` --> tests/ui/compile-fail/init/missing_comma.rs:16:9 | 16 | c: Bar, diff --git a/tests/ui/compile-fail/init/missing_comma_with_zeroable.stderr b/tests/ui/compile-fail/init/missing_comma_with_zeroable.stderr index 245de12..4ffb89c 100644 --- a/tests/ui/compile-fail/init/missing_comma_with_zeroable.stderr +++ b/tests/ui/compile-fail/init/missing_comma_with_zeroable.stderr @@ -1,20 +1,14 @@ -error[E0782]: trait objects must include the `dyn` keyword +error[E0782]: expected a type, found a trait --> tests/ui/compile-fail/init/missing_comma_with_zeroable.rs:12:15 | 12 | a: 0..Zeroable::zeroed() | ^^^^^^^^ | -help: add `dyn` keyword before this trait +help: you can add the `dyn` keyword if you want a trait object | 12 | a: 0..::zeroed() | ++++ + -error[E0599]: no function or associated item named `zeroed` found for trait `pinned_init::Zeroable` - --> tests/ui/compile-fail/init/missing_comma_with_zeroable.rs:12:25 - | -12 | a: 0..Zeroable::zeroed() - | ^^^^^^ function or associated item not found in `Zeroable` - error[E0308]: mismatched types --> tests/ui/compile-fail/init/missing_comma_with_zeroable.rs:11:13 | diff --git a/tests/ui/compile-fail/init/no_error_coercion.stderr b/tests/ui/compile-fail/init/no_error_coercion.stderr index 3feba12..832f13e 100644 --- a/tests/ui/compile-fail/init/no_error_coercion.stderr +++ b/tests/ui/compile-fail/init/no_error_coercion.stderr @@ -5,7 +5,7 @@ error[E0277]: `?` couldn't convert the error to `std::alloc::AllocError` 17 | | a: Box::new(42), 18 | | bar <- init!(Bar { b: 42 }), 19 | | }? AllocError) - | |______________________^ the trait `From` is not implemented for `std::alloc::AllocError`, which is required by `Result: FromResidual>` + | |______________________^ the trait `From` is not implemented for `std::alloc::AllocError` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the trait `FromResidual>` is implemented for `Result` diff --git a/tests/ui/compile-fail/init/wrong_generics.stderr b/tests/ui/compile-fail/init/wrong_generics.stderr index e70f0c0..cb1b1ef 100644 --- a/tests/ui/compile-fail/init/wrong_generics.stderr +++ b/tests/ui/compile-fail/init/wrong_generics.stderr @@ -1,4 +1,4 @@ -error: no rules expected the token `<` +error: no rules expected `<` --> tests/ui/compile-fail/init/wrong_generics.rs:7:22 | 7 | let _ = init!(Foo<()> { diff --git a/tests/ui/compile-fail/pin_data/missing_pin.stderr b/tests/ui/compile-fail/pin_data/missing_pin.stderr index e8f0307..5d98a04 100644 --- a/tests/ui/compile-fail/pin_data/missing_pin.stderr +++ b/tests/ui/compile-fail/pin_data/missing_pin.stderr @@ -7,7 +7,8 @@ error[E0277]: the trait bound `impl PinInit: Init` is not satis 13 | | }) | |__________^ the trait `Init` is not implemented for `impl PinInit` | - = help: the trait `Init, _>` is implemented for `impl PinInit` + = help: the trait `Init` is not implemented for `impl PinInit` + but trait `Init, _>` is implemented for it = help: for that trait implementation, expected `impl PinInit`, found `usize` note: required by a bound in `__ThePinData::a` --> tests/ui/compile-fail/pin_data/missing_pin.rs:4:1 diff --git a/tests/ui/compile-fail/pin_data/unexpected_item.stderr b/tests/ui/compile-fail/pin_data/unexpected_item.stderr index 0548653..1772f22 100644 --- a/tests/ui/compile-fail/pin_data/unexpected_item.stderr +++ b/tests/ui/compile-fail/pin_data/unexpected_item.stderr @@ -1,10 +1,10 @@ -error: no rules expected the token `fn` +error: no rules expected keyword `fn` --> tests/ui/compile-fail/pin_data/unexpected_item.rs:4:1 | 4 | fn foo() {} | ^^ no rules expected this token in macro call | -note: while trying to match `struct` +note: while trying to match keyword `struct` --> src/macros.rs | | $vis:vis struct $name:ident diff --git a/tests/ui/compile-fail/pinned_drop/no_fn.stderr b/tests/ui/compile-fail/pinned_drop/no_fn.stderr index 913bfa1..f2520ad 100644 --- a/tests/ui/compile-fail/pinned_drop/no_fn.stderr +++ b/tests/ui/compile-fail/pinned_drop/no_fn.stderr @@ -1,10 +1,10 @@ -error: no rules expected the token `)` +error: no rules expected `)` --> tests/ui/compile-fail/pinned_drop/no_fn.rs:6:1 | 6 | #[pinned_drop] | ^^^^^^^^^^^^^^ no rules expected this token in macro call | -note: while trying to match `fn` +note: while trying to match keyword `fn` --> src/macros.rs | | fn drop($($sig:tt)*) { diff --git a/tests/ui/compile-fail/pinned_drop/unexpected_additional_item.stderr b/tests/ui/compile-fail/pinned_drop/unexpected_additional_item.stderr index 3438aa2..5a1ad50 100644 --- a/tests/ui/compile-fail/pinned_drop/unexpected_additional_item.stderr +++ b/tests/ui/compile-fail/pinned_drop/unexpected_additional_item.stderr @@ -1,4 +1,4 @@ -error: no rules expected the token `const` +error: no rules expected keyword `const` --> tests/ui/compile-fail/pinned_drop/unexpected_additional_item.rs:10:5 | 10 | const BAZ: usize = 0; diff --git a/tests/ui/compile-fail/pinned_drop/unexpected_item.stderr b/tests/ui/compile-fail/pinned_drop/unexpected_item.stderr index 4c9c2c4..5b8fbb7 100644 --- a/tests/ui/compile-fail/pinned_drop/unexpected_item.stderr +++ b/tests/ui/compile-fail/pinned_drop/unexpected_item.stderr @@ -1,10 +1,10 @@ -error: no rules expected the token `const` +error: no rules expected keyword `const` --> tests/ui/compile-fail/pinned_drop/unexpected_item.rs:8:5 | 8 | const BAZ: usize = 0; | ^^^^^ no rules expected this token in macro call | -note: while trying to match `fn` +note: while trying to match keyword `fn` --> src/macros.rs | | fn drop($($sig:tt)*) { diff --git a/tests/ui/compile-fail/zeroable/with_comma.stderr b/tests/ui/compile-fail/zeroable/with_comma.stderr index 986006d..df6263a 100644 --- a/tests/ui/compile-fail/zeroable/with_comma.stderr +++ b/tests/ui/compile-fail/zeroable/with_comma.stderr @@ -1,4 +1,4 @@ -error: no rules expected the token `,` +error: no rules expected `,` --> tests/ui/compile-fail/zeroable/with_comma.rs:11:13 | 11 | let _ = init!(Foo { @@ -15,7 +15,7 @@ note: while trying to match `)` | ^ = note: this error originates in the macro `$crate::__init_internal` which comes from the expansion of the macro `init` (in Nightly builds, run with -Z macro-backtrace for more info) -error: no rules expected the token `,` +error: no rules expected `,` --> tests/ui/compile-fail/zeroable/with_comma.rs:11:13 | 11 | let _ = init!(Foo {