Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,8 @@ macro_rules! stack_try_pin_init {
/// the following modifications is expected:
/// - Fields that you want to initialize in-place have to use `<-` instead of `:`.
/// - You can use `_: { /* run any user-code here */ },` anywhere where you can place fields in
/// order to run arbitrary code.
/// order to run arbitrary code. Bindings present here will be visible to field initializers that
/// follow.
/// - In front of the initializer you can write `&this in` to have access to a [`NonNull<Self>`]
/// pointer named `this` inside of the initializer.
/// - Using struct update syntax one can place `..Zeroable::init_zeroed()` at the very end of the
Expand Down
2 changes: 1 addition & 1 deletion src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,7 +1290,7 @@ macro_rules! __init_internal {
// arbitrary code block
@munch_fields(_: { $($code:tt)* }, $($rest:tt)*),
) => {
{ $($code)* }
$($code)*;
$crate::__init_internal!(init_slot($($use_data)?):
@data($data),
@slot($slot),
Expand Down
14 changes: 11 additions & 3 deletions tests/ui/compile-fail/init/invalid_init.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ error[E0277]: the trait bound `impl pin_init::PinInit<Bar>: Init<Bar>` is not sa
| |______the trait `Init<Bar>` is not implemented for `impl pin_init::PinInit<Bar>`
| required by a bound introduced by this call
|
= help: the following other types implement trait `Init<T, E>`:
ChainInit<I, F, T, E>
Result<T, E>
help: the following other types implement trait `Init<T, E>`
--> src/lib.rs
|
| / unsafe impl<T: ?Sized, E, I, F> Init<T, E> for ChainInit<I, F, T, E>
| | where
| | I: Init<T, E>,
| | F: FnOnce(&mut T) -> Result<(), E>,
| |_______________________________________^ `ChainInit<I, F, T, E>`
...
| unsafe impl<T, E> Init<T, E> for Result<T, E> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Result<T, E>`
= 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)
10 changes: 5 additions & 5 deletions tests/ui/compile-fail/init/wrong_generics2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ error: struct literal body without path
|
= 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)
help: you might have forgotten to add the struct literal inside the block
--> src/macros.rs
|
~ ::core::ptr::write($slot, $t { SomeStruct {
|2 $($acc)*
~ } });
--> $DIR/src/macros.rs
|
~ ::core::ptr::write($slot, $t { SomeStruct {
| $($acc)*
~ } });
|

error: expected one of `)`, `,`, `.`, `?`, or an operator, found `{`
--> tests/ui/compile-fail/init/wrong_generics2.rs:7:13
Expand Down
8 changes: 6 additions & 2 deletions tests/ui/compile-fail/pin_data/missing_pin.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ error[E0277]: the trait bound `impl PinInit<usize>: Init<usize, _>` is not satis
13 | | })
| |__________^ the trait `Init<usize, _>` is not implemented for `impl PinInit<usize>`
|
= help: the trait `Init<usize, _>` is not implemented for `impl PinInit<usize>`
but trait `Init<impl PinInit<usize>, Infallible>` is implemented for it
help: the trait `Init<usize, _>` is not implemented for `impl PinInit<usize>`
but trait `Init<impl PinInit<usize>, Infallible>` is implemented for it
--> src/lib.rs
|
| unsafe impl<T> Init<T> for T {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: for that trait implementation, expected `impl PinInit<usize>`, found `usize`
note: required by a bound in `__ThePinData::a`
--> tests/ui/compile-fail/pin_data/missing_pin.rs:4:1
Expand Down
109 changes: 100 additions & 9 deletions tests/underscore.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,91 @@
use pin_init::{try_init, Init};
#![cfg_attr(not(RUSTC_LINT_REASONS_IS_STABLE), feature(lint_reasons))]
use core::cell::Cell;
use pin_init::*;

pub struct Foo {
x: u64,
#[derive(Debug)]
struct Error;

#[pin_data]
#[derive(Debug)]
struct Foo {
a: usize,
b: usize,
}

struct Bar;

impl Bar {
fn new() -> Result<Self, Error> {
Ok(Self)
}
fn make_a(&self) -> usize {
10
}
fn make_b(&self) -> usize {
20
}
}

fn error(_bar: &Bar) -> Result<(), Error> {
Err(Error)
}

fn ok(_bar: &Bar) -> Result<(), Error> {
Ok(())
}

#[test]
fn delay() {
let state = &Cell::new(3);
let init = pin_init!(Foo {
_: {
let x = state.get();
let y = x + 1;
},
a: x,
b: y,
});
state.set(42);
stack_pin_init!(let foo = init);
assert_eq!(foo.a, 42);
assert_eq!(foo.b, 43);
}

#[test]
fn error_user() {
let bar = Bar;
stack_try_pin_init!(let foo = try_pin_init!(Foo {
_: { error(&bar)? },
a: 1,
b: 2,
}? Error));

assert!(foo.is_err());
}

#[test]
fn ok_user() {
let bar = Bar;
stack_try_pin_init!(let foo = try_pin_init!(Foo {
_: { ok(&bar)? },
a: 1,
b: 2,
}? Error));

assert_eq!(foo.unwrap().a, 1);
}

#[test]
fn split() {
stack_try_pin_init!(let foo = try_pin_init!(Foo {
_: { let bar = Bar::new()? },
a: bar.make_a(),
b: bar.make_b(),
}? Error));

let foo = foo.unwrap();
assert_eq!(foo.a, 10);
assert_eq!(foo.b, 20);
}

fn foo() -> bool {
Expand All @@ -13,19 +97,26 @@ fn bar() -> bool {
}

impl Foo {
pub fn new() -> impl Init<Self, ()> {
pub fn late_error_new() -> impl Init<Self, Error> {
try_init!(Self {
_: {
if foo() {
return Err(());
return Err(Error);
}
},
x: 0,
a: 0,
_: {
if bar() {
return Err(());
return Err(Error);
}
}
}? ())
},
b: 0,
}? Error)
}
}

#[test]
fn late_error() {
stack_try_pin_init!(let foo = Foo::late_error_new());
assert!(foo.is_err());
}
Loading