1- //!
2- //
3- // Code relating to drop glue.
1+ //! Computing the size and alignment of a value.
42
3+ use crate :: common;
54use crate :: common:: IntPredicate ;
65use crate :: meth;
76use crate :: traits:: * ;
7+ use rustc_hir:: LangItem ;
8+ use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
89use rustc_middle:: ty:: { self , Ty } ;
910use rustc_target:: abi:: WrappingRange ;
1011
@@ -14,7 +15,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
1415 info : Option < Bx :: Value > ,
1516) -> ( Bx :: Value , Bx :: Value ) {
1617 let layout = bx. layout_of ( t) ;
17- debug ! ( "size_and_align_of_dst(ty={}, info={:?}): layout: {:?}" , t, info, layout) ;
18+ trace ! ( "size_and_align_of_dst(ty={}, info={:?}): layout: {:?}" , t, info, layout) ;
1819 if layout. is_sized ( ) {
1920 let size = bx. const_usize ( layout. size . bytes ( ) ) ;
2021 let align = bx. const_usize ( layout. align . abi . bytes ( ) ) ;
@@ -51,7 +52,31 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
5152 bx. const_usize ( unit. align . abi . bytes ( ) ) ,
5253 )
5354 }
54- _ => {
55+ ty:: Foreign ( _) => {
56+ // `extern` type. We cannot compute the size, so panic.
57+ let msg_str = with_no_visible_paths ! ( {
58+ with_no_trimmed_paths!( {
59+ format!( "attempted to compute the size or alignment of extern type `{t}`" )
60+ } )
61+ } ) ;
62+ let msg = bx. const_str ( & msg_str) ;
63+
64+ // Obtain the panic entry point.
65+ let ( fn_abi, llfn) = common:: build_langcall ( bx, None , LangItem :: PanicNounwind ) ;
66+
67+ // Generate the call.
68+ // Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.
69+ // (But we are in good company, this code is duplicated plenty of times.)
70+ let fn_ty = bx. fn_decl_backend_type ( fn_abi) ;
71+
72+ bx. call ( fn_ty, /* fn_attrs */ None , Some ( fn_abi) , llfn, & [ msg. 0 , msg. 1 ] , None ) ;
73+
74+ // This function does not return so we can now return whatever we want.
75+ let size = bx. const_usize ( layout. size . bytes ( ) ) ;
76+ let align = bx. const_usize ( layout. align . abi . bytes ( ) ) ;
77+ ( size, align)
78+ }
79+ ty:: Adt ( ..) | ty:: Tuple ( ..) => {
5580 // First get the size of all statically known fields.
5681 // Don't use size_of because it also rounds up to alignment, which we
5782 // want to avoid, as the unsized field's alignment could be smaller.
@@ -122,5 +147,6 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
122147
123148 ( size, align)
124149 }
150+ _ => bug ! ( "size_and_align_of_dst: {t} not supported" ) ,
125151 }
126152}
0 commit comments