@@ -1310,27 +1310,33 @@ macro_rules! __init_internal {
13101310 // return when an error/panic occurs.
13111311 // We also use the `data` to require the correct trait (`Init` or `PinInit`) for `$field`.
13121312 unsafe { $data. $field( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) , init) ? } ;
1313- // NOTE: the field accessor ensures that the initialized field is properly aligned.
1313+ // NOTE: this ensures that the initialized field is properly aligned.
13141314 // Unaligned fields will cause the compiler to emit E0793. We do not support
13151315 // unaligned fields since `Init::__init` requires an aligned pointer; the call to
13161316 // `ptr::write` below has the same requirement.
1317- // SAFETY:
1318- // - the project function does the correct field projection,
1319- // - the field has been initialized,
1320- // - the reference is only valid until the end of the initializer.
1321- #[ allow( unused_variables) ]
1322- let $field = $crate:: macros:: paste!( unsafe { $data. [ < __project_ $field >] ( & mut ( * $slot) . $field) } ) ;
1317+ // SAFETY: the field has been initialized.
1318+ let _ = unsafe { & mut ( * $slot) . $field } ;
13231319
13241320 // Create the drop guard:
13251321 //
13261322 // We rely on macro hygiene to make it impossible for users to access this local variable.
13271323 // We use `paste!` to create new hygiene for `$field`.
13281324 $crate:: macros:: paste! {
1329- // SAFETY: We forget the guard later when initialization has succeeded.
1330- let [ < __ $field _guard >] = unsafe {
1325+ // SAFETY:
1326+ // - `addr_of_mut!((*$slot).$field)` is valid.
1327+ // - `(*$slot).$field` has been initialized above.
1328+ // - We only need the ownership to the pointee back when initialization has
1329+ // succeeded, where we `forget` the guard.
1330+ let mut [ < __ $field _guard >] = unsafe {
13311331 $crate:: __internal:: DropGuard :: new( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) )
13321332 } ;
13331333
1334+ // NOTE: The reference is derived from the guard so that it only lives as long as
1335+ // the guard does and cannot escape the scope.
1336+ #[ allow( unused_variables) ]
1337+ // SAFETY: the project function does the correct field projection.
1338+ let $field = unsafe { $data. [ < __project_ $field >] ( [ < __ $field _guard >] . let_binding( ) ) } ;
1339+
13341340 $crate:: __init_internal!( init_slot( $use_data) :
13351341 @data( $data) ,
13361342 @slot( $slot) ,
@@ -1353,27 +1359,30 @@ macro_rules! __init_internal {
13531359 // return when an error/panic occurs.
13541360 unsafe { $crate:: Init :: __init( init, :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) ) ? } ;
13551361
1356- // NOTE: the field accessor ensures that the initialized field is properly aligned.
1362+ // NOTE: this ensures that the initialized field is properly aligned.
13571363 // Unaligned fields will cause the compiler to emit E0793. We do not support
13581364 // unaligned fields since `Init::__init` requires an aligned pointer; the call to
13591365 // `ptr::write` below has the same requirement.
1360- // SAFETY:
1361- // - the field is not structurally pinned, since the line above must compile,
1362- // - the field has been initialized,
1363- // - the reference is only valid until the end of the initializer.
1364- #[ allow( unused_variables) ]
1365- let $field = unsafe { & mut ( * $slot) . $field } ;
1366+ // SAFETY: the field has been initialized.
1367+ let _ = unsafe { & mut ( * $slot) . $field } ;
13661368
13671369 // Create the drop guard:
13681370 //
13691371 // We rely on macro hygiene to make it impossible for users to access this local variable.
13701372 // We use `paste!` to create new hygiene for `$field`.
13711373 $crate:: macros:: paste! {
1372- // SAFETY: We forget the guard later when initialization has succeeded.
1373- let [ < __ $field _guard >] = unsafe {
1374+ // SAFETY:
1375+ // - `addr_of_mut!((*$slot).$field)` is valid.
1376+ // - `(*$slot).$field` has been initialized above.
1377+ // - We only need the ownership to the pointee back when initialization has
1378+ // succeeded, where we `forget` the guard.
1379+ let mut [ < __ $field _guard >] = unsafe {
13741380 $crate:: __internal:: DropGuard :: new( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) )
13751381 } ;
13761382
1383+ #[ allow( unused_variables) ]
1384+ let $field = [ < __ $field _guard >] . let_binding( ) ;
1385+
13771386 $crate:: __init_internal!( init_slot( ) :
13781387 @data( $data) ,
13791388 @slot( $slot) ,
@@ -1397,28 +1406,30 @@ macro_rules! __init_internal {
13971406 unsafe { :: core:: ptr:: write( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) , $field) } ;
13981407 }
13991408
1400- // NOTE: the field accessor ensures that the initialized field is properly aligned.
1409+ // NOTE: this ensures that the initialized field is properly aligned.
14011410 // Unaligned fields will cause the compiler to emit E0793. We do not support
14021411 // unaligned fields since `Init::__init` requires an aligned pointer; the call to
14031412 // `ptr::write` below has the same requirement.
1404- #[ allow( unused_variables) ]
1405- // SAFETY:
1406- // - the field is not structurally pinned, since no `use_data` was required to create this
1407- // initializer,
1408- // - the field has been initialized,
1409- // - the reference is only valid until the end of the initializer.
1410- let $field = unsafe { & mut ( * $slot) . $field } ;
1413+ // SAFETY: the field has been initialized.
1414+ let _ = unsafe { & mut ( * $slot) . $field } ;
14111415
14121416 // Create the drop guard:
14131417 //
14141418 // We rely on macro hygiene to make it impossible for users to access this local variable.
14151419 // We use `paste!` to create new hygiene for `$field`.
14161420 $crate:: macros:: paste! {
1417- // SAFETY: We forget the guard later when initialization has succeeded.
1418- let [ < __ $field _guard >] = unsafe {
1421+ // SAFETY:
1422+ // - `addr_of_mut!((*$slot).$field)` is valid.
1423+ // - `(*$slot).$field` has been initialized above.
1424+ // - We only need the ownership to the pointee back when initialization has
1425+ // succeeded, where we `forget` the guard.
1426+ let mut [ < __ $field _guard >] = unsafe {
14191427 $crate:: __internal:: DropGuard :: new( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) )
14201428 } ;
14211429
1430+ #[ allow( unused_variables) ]
1431+ let $field = [ < __ $field _guard >] . let_binding( ) ;
1432+
14221433 $crate:: __init_internal!( init_slot( ) :
14231434 @data( $data) ,
14241435 @slot( $slot) ,
@@ -1441,27 +1452,33 @@ macro_rules! __init_internal {
14411452 // SAFETY: The memory at `slot` is uninitialized.
14421453 unsafe { :: core:: ptr:: write( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) , $field) } ;
14431454 }
1444- // NOTE: the field accessor ensures that the initialized field is properly aligned.
1455+ // NOTE: this ensures that the initialized field is properly aligned.
14451456 // Unaligned fields will cause the compiler to emit E0793. We do not support
14461457 // unaligned fields since `Init::__init` requires an aligned pointer; the call to
14471458 // `ptr::write` below has the same requirement.
1448- // SAFETY:
1449- // - the project function does the correct field projection,
1450- // - the field has been initialized,
1451- // - the reference is only valid until the end of the initializer.
1452- #[ allow( unused_variables) ]
1453- let $field = $crate:: macros:: paste!( unsafe { $data. [ < __project_ $field >] ( & mut ( * $slot) . $field) } ) ;
1459+ // SAFETY: the field has been initialized.
1460+ let _ = unsafe { & mut ( * $slot) . $field } ;
14541461
14551462 // Create the drop guard:
14561463 //
14571464 // We rely on macro hygiene to make it impossible for users to access this local variable.
14581465 // We use `paste!` to create new hygiene for `$field`.
14591466 $crate:: macros:: paste! {
1460- // SAFETY: We forget the guard later when initialization has succeeded.
1461- let [ < __ $field _guard >] = unsafe {
1467+ // SAFETY:
1468+ // - `addr_of_mut!((*$slot).$field)` is valid.
1469+ // - `(*$slot).$field` has been initialized above.
1470+ // - We only need the ownership to the pointee back when initialization has
1471+ // succeeded, where we `forget` the guard.
1472+ let mut [ < __ $field _guard >] = unsafe {
14621473 $crate:: __internal:: DropGuard :: new( :: core:: ptr:: addr_of_mut!( ( * $slot) . $field) )
14631474 } ;
14641475
1476+ // NOTE: The reference is derived from the guard so that it only lives as long as
1477+ // the guard does and cannot escape the scope.
1478+ #[ allow( unused_variables) ]
1479+ // SAFETY: the project function does the correct field projection.
1480+ let $field = unsafe { $data. [ < __project_ $field >] ( [ < __ $field _guard >] . let_binding( ) ) } ;
1481+
14651482 $crate:: __init_internal!( init_slot( $use_data) :
14661483 @data( $data) ,
14671484 @slot( $slot) ,
0 commit comments