@@ -330,7 +330,7 @@ pub(crate) mod rustc {
330330 . fold ( Tree :: unit ( ) , |tree, elt| tree. then ( elt) ) )
331331 }
332332
333- ty:: Adt ( adt_def, _args_ref ) if !ty. is_box ( ) => {
333+ ty:: Adt ( adt_def, args_ref ) if !ty. is_box ( ) => {
334334 let ( lo, hi) = cx. tcx ( ) . layout_scalar_valid_range ( adt_def. did ( ) ) ;
335335
336336 use core:: ops:: Bound :: * ;
@@ -339,13 +339,35 @@ pub(crate) mod rustc {
339339 ( AdtKind :: Struct , Unbounded , Unbounded ) => {
340340 Self :: from_struct ( ( ty, layout) , * adt_def, cx)
341341 }
342- ( AdtKind :: Struct , Included ( 1 ) , Included ( _hi) ) if is_transparent => {
343- // FIXME(@joshlf): Support `NonZero` types:
344- // - Check to make sure that the first field is
345- // numerical
346- // - Check to make sure that the upper bound is the
347- // maximum value for the field's type
348- // - Construct `Self::nonzero`
342+ ( AdtKind :: Struct , Included ( 1 ) , hi_val) if is_transparent => {
343+ let variant = adt_def. non_enum_variant ( ) ;
344+ // For now, only support `repr(transparent)` types
345+ // with a single field. Technically
346+ // `repr(transparent)` also works with types with
347+ // any number of zero-sized fields (in addition to
348+ // their single non-zero-sized field), but no such
349+ // types exist in the standard library which also
350+ // use
351+ // `#[rustc_layout_scalar_valid_range_(start|end)]`.
352+ if let [ field] = & variant. fields . as_slice ( ) . raw {
353+ let field_ty = field. ty ( cx. tcx ( ) , args_ref) ;
354+
355+ let field_layout = layout_of ( cx, field_ty) ?;
356+ let field_size = field_layout. size ;
357+
358+ let max_value = ( 1u128 << field_size. bits ( ) ) - 1 ;
359+ let hi_val = match hi_val {
360+ Included ( hi_val) => hi_val,
361+ Unbounded => max_value,
362+ Excluded ( _) => return Err ( Err :: NotYetSupported ) ,
363+ } ;
364+
365+ if hi_val == max_value
366+ && let ty:: Uint ( _) = * field_ty. kind ( )
367+ {
368+ return Ok ( Self :: nonzero ( field_size. bytes ( ) ) ) ;
369+ }
370+ }
349371 Err ( Err :: NotYetSupported )
350372 }
351373 ( AdtKind :: Enum , Unbounded , Unbounded ) => {
0 commit comments