@@ -162,7 +162,7 @@ impl Layout {
162162     /// Returns an error if the combination of `self.size()` and the given 
163163     /// `align` violates the conditions listed in 
164164     /// [`Layout::from_size_align`](#method.from_size_align). 
165-      #[ unstable ( feature = "alloc_layout_extra " ,  issue  = "55724 " ) ]  
165+      #[ stable ( feature = "alloc_layout_manipulation " ,  since  = "1.44.0 " ) ]  
166166    #[ inline]  
167167    pub  fn  align_to ( & self ,  align :  usize )  -> Result < Self ,  LayoutErr >  { 
168168        Layout :: from_size_align ( self . size ( ) ,  cmp:: max ( self . align ( ) ,  align) ) 
@@ -218,7 +218,7 @@ impl Layout {
218218     /// 
219219     /// This is equivalent to adding the result of `padding_needed_for` 
220220     /// to the layout's current size. 
221-      #[ unstable ( feature = "alloc_layout_extra " ,  issue  = "55724 " ) ]  
221+      #[ stable ( feature = "alloc_layout_manipulation " ,  since  = "1.44.0 " ) ]  
222222    #[ inline]  
223223    pub  fn  pad_to_align ( & self )  -> Layout  { 
224224        let  pad = self . padding_needed_for ( self . align ( ) ) ; 
@@ -258,19 +258,50 @@ impl Layout {
258258
259259    /// Creates a layout describing the record for `self` followed by 
260260     /// `next`, including any necessary padding to ensure that `next` 
261-      /// will be properly aligned. Note that the resulting layout will 
262-      /// satisfy the alignment properties of both `self` and `next`. 
261+      /// will be properly aligned, but *no trailing padding*. 
263262     /// 
264-      /// The resulting layout will be the same as that of a C struct containing 
265-      /// two fields with the layouts of `self` and `next`, in that order. 
263+      /// In order to match C representation layout `repr(C)`, you should 
264+      /// call `pad_to_align` after extending the layout with all fields. 
265+      /// (There is no way to match the default Rust representation 
266+      /// layout `repr(Rust)`, as it is unspecified.) 
266267     /// 
267-      /// Returns `Some((k, offset))`, where `k` is layout of the concatenated 
268+      /// Note that the alignment of the resulting layout will be the maximum of 
269+      /// those of `self` and `next`, in order to ensure alignment of both parts. 
270+      /// 
271+      /// Returns `Ok((k, offset))`, where `k` is layout of the concatenated 
268272     /// record and `offset` is the relative location, in bytes, of the 
269273     /// start of the `next` embedded within the concatenated record 
270274     /// (assuming that the record itself starts at offset 0). 
271275     /// 
272276     /// On arithmetic overflow, returns `LayoutErr`. 
273-      #[ unstable( feature = "alloc_layout_extra" ,  issue = "55724" ) ]  
277+      /// 
278+      /// # Examples 
279+      /// 
280+      /// To calculate the layout of a `#[repr(C)]` structure and the offsets of 
281+      /// the fields from its fields' layouts: 
282+      /// 
283+      /// ```rust 
284+      /// # use std::alloc::{Layout, LayoutErr}; 
285+      /// pub fn repr_c(fields: &[Layout]) -> Result<(Layout, Vec<usize>), LayoutErr> { 
286+      ///     let mut offsets = Vec::new(); 
287+      ///     let mut layout = Layout::from_size_align(0, 1)?; 
288+      ///     for &field in fields { 
289+      ///         let (new_layout, offset) = layout.extend(field)?; 
290+      ///         layout = new_layout; 
291+      ///         offsets.push(offset); 
292+      ///     } 
293+      ///     // Remember to finalize with `pad_to_align`! 
294+      ///     Ok((layout.pad_to_align(), offsets)) 
295+      /// } 
296+      /// # // test that it works 
297+      /// # #[repr(C)] struct S { a: u64, b: u32, c: u16, d: u32 } 
298+      /// # let s = Layout::new::<S>(); 
299+      /// # let u16 = Layout::new::<u16>(); 
300+      /// # let u32 = Layout::new::<u32>(); 
301+      /// # let u64 = Layout::new::<u64>(); 
302+      /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16]))); 
303+      /// ``` 
304+      #[ stable( feature = "alloc_layout_manipulation" ,  since = "1.44.0" ) ]  
274305    #[ inline]  
275306    pub  fn  extend ( & self ,  next :  Self )  -> Result < ( Self ,  usize ) ,  LayoutErr >  { 
276307        let  new_align = cmp:: max ( self . align ( ) ,  next. align ( ) ) ; 
@@ -318,13 +349,12 @@ impl Layout {
318349    /// Creates a layout describing the record for a `[T; n]`. 
319350     /// 
320351     /// On arithmetic overflow, returns `LayoutErr`. 
321-      #[ unstable ( feature = "alloc_layout_extra " ,  issue  = "55724 " ) ]  
352+      #[ stable ( feature = "alloc_layout_manipulation " ,  since  = "1.44.0 " ) ]  
322353    #[ inline]  
323354    pub  fn  array < T > ( n :  usize )  -> Result < Self ,  LayoutErr >  { 
324-         Layout :: new :: < T > ( ) . repeat ( n) . map ( |( k,  offs) | { 
325-             debug_assert ! ( offs == mem:: size_of:: <T >( ) ) ; 
326-             k
327-         } ) 
355+         let  ( layout,  offset)  = Layout :: new :: < T > ( ) . repeat ( n) ?; 
356+         debug_assert_eq ! ( offset,  mem:: size_of:: <T >( ) ) ; 
357+         Ok ( layout. pad_to_align ( ) ) 
328358    } 
329359} 
330360
0 commit comments