@@ -1101,6 +1101,11 @@ pub struct Pin<Ptr> {
11011101    #[ unstable( feature = "unsafe_pin_internals" ,  issue = "none" ) ]  
11021102    #[ doc( hidden) ]  
11031103    pub  __pointer :  Ptr , 
1104+ 
1105+     /// See the docs of [`lifetime_extension`] for more info. 
1106+      #[ unstable( feature = "unsafe_pin_internals" ,  issue = "none" ) ]  
1107+     #[ doc( hidden) ]  
1108+     pub  __phantom :  crate :: marker:: PhantomData < Ptr > , 
11041109} 
11051110
11061111// The following implementations aren't derived in order to avoid soundness 
@@ -1355,7 +1360,7 @@ impl<Ptr: Deref> Pin<Ptr> {
13551360    #[ rustc_const_stable( feature = "const_pin" ,  since = "1.84.0" ) ]  
13561361    #[ stable( feature = "pin" ,  since = "1.33.0" ) ]  
13571362    pub  const  unsafe  fn  new_unchecked ( pointer :  Ptr )  -> Pin < Ptr >  { 
1358-         Pin  {  __pointer :  pointer } 
1363+         Pin  {  __pointer :  pointer,   __phantom :   crate :: marker :: PhantomData  } 
13591364    } 
13601365
13611366    /// Gets a shared reference to the pinned value this [`Pin`] points to. 
@@ -1575,7 +1580,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
15751580    #[ rustc_const_stable( feature = "const_pin" ,  since = "1.84.0" ) ]  
15761581    #[ stable( feature = "pin" ,  since = "1.33.0" ) ]  
15771582    pub  const  fn  into_ref ( self )  -> Pin < & ' a  T >  { 
1578-         Pin  {  __pointer :  self . __pointer  } 
1583+         Pin  {  __pointer :  self . __pointer ,   __phantom :   crate :: marker :: PhantomData  } 
15791584    } 
15801585
15811586    /// Gets a mutable reference to the data inside of this `Pin`. 
@@ -2014,5 +2019,145 @@ pub macro pin($value:expr $(,)?) {
20142019    // 
20152020    // See https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension 
20162021    // for more info. 
2017-     $crate:: pin:: Pin :: < & mut  _ >  {  __pointer :  & mut  {  $value }  } 
2022+     $crate:: pin:: Pin :: < & mut  _ >  { 
2023+         __pointer :  & mut  $crate:: pin:: __Pinned  { 
2024+             value_expression_preserving_lifespan_extension_of_temporaries :  $value, 
2025+         }  as  & mut  _ , 
2026+         // ^^^^^^^^ 
2027+         // DerefMut coërcion, because of --+ 
2028+         __phantom :  {  // <------------------+ 
2029+             let  pin = $crate:: marker:: PhantomData ; 
2030+             if  false  { 
2031+                 loop  { } 
2032+                 // We use dead code to disable move semantics (and borrowck) to allow us to refer to 
2033+                 // `$value` again even when `$value` happens to consume non-`Copy` stuff or whatnot. 
2034+                 #[ allow( unreachable_code) ]   { 
2035+                     $crate:: pin:: __phantomdata_set_typeof_pointee ( pin,  $value) ; 
2036+                 } 
2037+             } 
2038+             pin
2039+         } , 
2040+     } 
2041+ } 
2042+ 
2043+ /// Since the 2024 edition, the rules for lifespan-of-temporaries extension have changed, 
2044+ /// and `{ $value }` no longer cuts it for all the scenarios where it did in the 2021 edition and 
2045+ /// before. 
2046+ /// 
2047+ ///   - aside: throughout this documentation the expression "lifespan extension" shall be preferred 
2048+ ///     to that of "lifetime extension", so as to clarify we are firstly talking of the lifespan of 
2049+ ///     a temporary, which, when extended, results in the lifetime of a borrow to it to be allowed 
2050+ ///     to be bigger. This nit seems more in line with the idea that lifetimes themselves are just 
2051+ ///     descriptive, not prescriptive, so it does not make that much sense to talk of extending one 
2052+ ///     _directly_. We would not need to lift this ambiguity had Rust chosen a term other than 
2053+ ///     "lifetime" to talk of the duration of borrows. 
2054+ /// 
2055+ /// Indeed, things such as the following regressed: 
2056+ /// 
2057+ /// ```rust 
2058+ /// // Regression test for #138596 
2059+ /// 
2060+ /// fn main() { 
2061+ ///     match core::pin::pin!(foo(&mut 0)) { 
2062+ ///         _f => {} 
2063+ ///     } 
2064+ /// } 
2065+ /// 
2066+ /// async fn foo(_s: &mut usize) {} 
2067+ /// ``` 
2068+ /// 
2069+ /// The reason for that is that we'd end up with `{ foo(&mut temporary(0)) }` among the expansion 
2070+ /// of `pin!`, and since this happens in `match`-scrutinee position, temporaries get not to outlive 
2071+ /// their encompassing braced block(s), so `temporary(0)` dies before that `}`, and the resulting 
2072+ /// `Pin { … }` is born dangling. 
2073+ /// 
2074+ /// But we do need a _value expression_ behind our `Pin { __pointer: &mut`, lest Rust treat it as a 
2075+ /// _place expression_, and allow things such as `$value = *&mut non_unpin`, which would break 
2076+ /// the soundness requirement of `Pin` (see 
2077+ /// https://github.com/rust-lang/rust/issues/138596#issuecomment-2729894350). 
2078+ /// 
2079+ /// This naïvely leaves us with things such as `identity($value)` or `($value, ).0` as 
2080+ /// plausible alternatives. 
2081+ /// 
2082+ /// But, alas, this now breaks the lifespan-of-temps extension happening _inside of `$value`_, which 
2083+ /// has been an accidental, but stabilized and quite convenient, property of `pin!`. 
2084+ /// For instance, the following code would break: 
2085+ /// 
2086+ /// ```rust 
2087+ /// fn temporary() {} 
2088+ /// 
2089+ /// let p = core::pin::pin!(&mut temporary()); 
2090+ /// let _some_usage_of_p = (&p, ); 
2091+ /// ``` 
2092+ /// 
2093+ /// And there are several occurrences of `pin!(&mut …)` in the wild, and whilst most of them are 
2094+ /// inlined/short usages of `Pin<&mut _>`, there is at least one instance of such code actually 
2095+ /// being multi-statement lived, and thus relying on the lifespan-of-temps extension property of 
2096+ /// `pin!()`. 
2097+ /// 
2098+ /// So, unless/until we get `pin!()` —or a helper inner macro thereof— to be using edition 2021 
2099+ /// rules for its `{ $value }` expression, the only 2024-edition-compatible workaround found so far 
2100+ /// hinges on the following observation: 
2101+ /// 
2102+ /// > `&mut Wrapper { field: $value }` happens to preserve the lifespan-of-temps-extending 
2103+ /// > rules of 2021 edition `&mut $value`, and also funnels `$value` through a value expression. 
2104+ /// 
2105+ /// But we get a `&mut Wrapper<typeof<$value>>` rather than a `&mut typeof<$value>`. 
2106+ /// So now the challenge is to get `DerefMut` to take place here, and we are good! 
2107+ /// 
2108+ /// Only…, so far, lifespan-extension rules get broken by _explicit_ `Deref{,Mut}` such as `*`, 
2109+ /// `&*`, or, in our case, `&mut *`!! 😩 
2110+ /// 
2111+ /// But…, it does not get broken by _implicit_ `Deref{,Mut}`, such as the one triggered by a deref 
2112+ /// coërcion! 
2113+ /// 
2114+ /// That is, `&mut Wrapper { field: $value } as &mut typeof<$value>` does preserve lifespan-of-temps 
2115+ /// extension! 
2116+ /// 
2117+ /// So, our final challenge now is to express `&mut typeof<$value>` when `typeof` is not available. 
2118+ /// 
2119+ /// The usual approach is 
2120+ /// `if false { /* unreachable code to infer type */ } else { /* real code */ }`, but we cannot 
2121+ /// do that either since the braced blocks here are the "same" as our originally problematic 
2122+ /// `{ $value }` to begin with! 
2123+ /// 
2124+ /// So the only remaining tool available to our disposable are the very fields of `Pin { … }`: we 
2125+ /// can have an extra `PhantomData` field, which "redundantly" uses the `Ptr` type, thereby 
2126+ /// introducing a type equality constraint between the two fields similar to that of an `if … else`, 
2127+ /// and which is where we shall be able to insert our `/* unreachable code to infer type */`. 
2128+ #[ doc( hidden) ]  
2129+ #[ unstable( feature = "unsafe_pin_internals" ,  issue = "none" ) ]  
2130+ mod  lifetime_extension { 
2131+     use  crate :: marker:: PhantomData ; 
2132+     use  crate :: ops:: { Deref ,  DerefMut } ; 
2133+ 
2134+     /// Used in an `unreachable_code` branch to guide type inference. 
2135+      #[ doc( hidden) ]  
2136+     pub  fn  __phantomdata_set_typeof_pointee < T > ( _:  PhantomData < & mut  T > ,  _:  T )  { } 
2137+ 
2138+     /// Our `DerefMut` helper wrapper. 
2139+      #[ doc( hidden) ]  
2140+     #[ unstable( feature = "unsafe_pin_internals" ,  issue = "none" ) ]  
2141+     #[ allow( missing_debug_implementations) ]  
2142+     pub  struct  __Pinned < T >  { 
2143+         pub  value_expression_preserving_lifespan_extension_of_temporaries :  T , 
2144+     } 
2145+ 
2146+     impl < T >  Deref  for  __Pinned < T >  { 
2147+         type  Target  = T ; 
2148+ 
2149+         fn  deref ( & self )  -> & T  { 
2150+             unimplemented ! ( "never to be called" ) ; 
2151+         } 
2152+     } 
2153+ 
2154+     impl < T >  DerefMut  for  __Pinned < T >  { 
2155+         #[ inline]  
2156+         fn  deref_mut ( & mut  self )  -> & mut  T  { 
2157+             & mut  self . value_expression_preserving_lifespan_extension_of_temporaries 
2158+         } 
2159+     } 
20182160} 
2161+ 
2162+ #[ unstable( feature = "unsafe_pin_internals" ,  issue = "none" ) ]  
2163+ pub  use  lifetime_extension:: { __Pinned,  __phantomdata_set_typeof_pointee} ; 
0 commit comments