Skip to content

Commit 03e0a0d

Browse files
authored
Merge pull request #62 from Rust-for-Linux/dev/result
- change blanket impls of `Init` and `PinInit` from `impl<T, E> [Pin]Init<T, E> for E` to `impl<T> [Pin]Init<T> for T` - add `impl<T, E> [Pin]Init<T, E> for Result<T, E>`, so results are now (pin-)initializers
2 parents f2451d9 + 5861251 commit 03e0a0d

File tree

4 files changed

+39
-10
lines changed

4 files changed

+39
-10
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- `MaybeZeroable` derive macro to try to derive `Zeroable`, but not error if not all fields
1414
implement it.
1515
- `unsafe fn cast_[pin_]init()` functions to unsafely change the initialized type of an initializer
16+
- `impl<T, E> [Pin]Init<T, E> for Result<T, E>`, so results are now (pin-)initializers
1617

1718
### Changed
1819

1920
- `InPlaceInit` now only exists when the `alloc` or `std` features are enabled
2021
- added support for visibility in `Zeroable` derive macro
2122
- added support for `union`s in `Zeroable` derive macro
2223
- renamed the crate from `pinned-init` to `pin-init` and `pinned-init-macro` to `pin-init-internal`
24+
- blanket impls of `Init` and `PinInit` from `impl<T, E> [Pin]Init<T, E> for T` to
25+
`impl<T> [Pin]Init<T> for T`
2326

2427
### Fixed
2528

src/lib.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,20 +1390,44 @@ where
13901390
unsafe { pin_init_from_closure(init) }
13911391
}
13921392

1393-
// SAFETY: Every type can be initialized by-value.
1394-
unsafe impl<T, E> Init<T, E> for T {
1395-
unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
1396-
// SAFETY: TODO.
1393+
// SAFETY: the `__init` function always returns `Ok(())` and initializes every field of `slot`.
1394+
unsafe impl<T> Init<T> for T {
1395+
unsafe fn __init(self, slot: *mut T) -> Result<(), Infallible> {
1396+
// SAFETY: `slot` is valid for writes by the safety requirements of this function.
13971397
unsafe { slot.write(self) };
13981398
Ok(())
13991399
}
14001400
}
14011401

1402-
// SAFETY: Every type can be initialized by-value. `__pinned_init` calls `__init`.
1403-
unsafe impl<T, E> PinInit<T, E> for T {
1402+
// SAFETY: the `__pinned_init` function always returns `Ok(())` and initializes every field of
1403+
// `slot`. Additionally, all pinning invariants of `T` are upheld.
1404+
unsafe impl<T> PinInit<T> for T {
1405+
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible> {
1406+
// SAFETY: `slot` is valid for writes by the safety requirements of this function.
1407+
unsafe { slot.write(self) };
1408+
Ok(())
1409+
}
1410+
}
1411+
1412+
// SAFETY: when the `__init` function returns with
1413+
// - `Ok(())`, `slot` was initialized and all pinned invariants of `T` are upheld.
1414+
// - `Err(err)`, slot was not written to.
1415+
unsafe impl<T, E> Init<T, E> for Result<T, E> {
1416+
unsafe fn __init(self, slot: *mut T) -> Result<(), E> {
1417+
// SAFETY: `slot` is valid for writes by the safety requirements of this function.
1418+
unsafe { slot.write(self?) };
1419+
Ok(())
1420+
}
1421+
}
1422+
1423+
// SAFETY: when the `__pinned_init` function returns with
1424+
// - `Ok(())`, `slot` was initialized and all pinned invariants of `T` are upheld.
1425+
// - `Err(err)`, slot was not written to.
1426+
unsafe impl<T, E> PinInit<T, E> for Result<T, E> {
14041427
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> {
1405-
// SAFETY: TODO.
1406-
unsafe { self.__init(slot) }
1428+
// SAFETY: `slot` is valid for writes by the safety requirements of this function.
1429+
unsafe { slot.write(self?) };
1430+
Ok(())
14071431
}
14081432
}
14091433

tests/ui/compile-fail/init/invalid_init.stderr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ error[E0277]: the trait bound `impl pin_init::PinInit<Bar>: Init<Bar>` is not sa
1010
| |______the trait `Init<Bar>` is not implemented for `impl pin_init::PinInit<Bar>`
1111
| required by a bound introduced by this call
1212
|
13-
= help: the trait `Init<T, E>` is implemented for `ChainInit<I, F, T, E>`
13+
= help: the following other types implement trait `Init<T, E>`:
14+
ChainInit<I, F, T, E>
15+
Result<T, E>
1416
= 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)

tests/ui/compile-fail/pin_data/missing_pin.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ error[E0277]: the trait bound `impl PinInit<usize>: Init<usize, _>` is not satis
88
| |__________^ the trait `Init<usize, _>` is not implemented for `impl PinInit<usize>`
99
|
1010
= help: the trait `Init<usize, _>` is not implemented for `impl PinInit<usize>`
11-
but trait `Init<impl PinInit<usize>, _>` is implemented for it
11+
but trait `Init<impl PinInit<usize>, Infallible>` is implemented for it
1212
= help: for that trait implementation, expected `impl PinInit<usize>`, found `usize`
1313
note: required by a bound in `__ThePinData::a`
1414
--> tests/ui/compile-fail/pin_data/missing_pin.rs:4:1

0 commit comments

Comments
 (0)