2
2
//!
3
3
//! [`PointerCoercion::Unsize`]: `rustc_middle::ty::adjustment::PointerCoercion::Unsize`
4
4
5
+ use rustc_middle:: ty:: print:: { with_no_trimmed_paths, with_no_visible_paths} ;
6
+
7
+ use crate :: base:: codegen_panic_nounwind;
5
8
use crate :: prelude:: * ;
6
9
7
10
// Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/base.rs#L159-L307
@@ -187,27 +190,62 @@ pub(crate) fn coerce_dyn_star<'tcx>(
187
190
188
191
// Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs
189
192
190
- pub ( crate ) fn size_and_align_of_dst < ' tcx > (
193
+ pub ( crate ) fn size_and_align_of < ' tcx > (
191
194
fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
192
195
layout : TyAndLayout < ' tcx > ,
193
- info : Value ,
196
+ info : Option < Value > ,
194
197
) -> ( Value , Value ) {
195
- assert ! ( layout. is_unsized( ) || layout. abi == Abi :: Uninhabited ) ;
196
- match layout. ty . kind ( ) {
198
+ if layout. is_sized ( ) {
199
+ return (
200
+ fx. bcx . ins ( ) . iconst ( fx. pointer_type , layout. size . bytes ( ) as i64 ) ,
201
+ fx. bcx . ins ( ) . iconst ( fx. pointer_type , layout. align . abi . bytes ( ) as i64 ) ,
202
+ ) ;
203
+ }
204
+
205
+ let ty = layout. ty ;
206
+ match ty. kind ( ) {
197
207
ty:: Dynamic ( ..) => {
198
208
// load size/align from vtable
199
- ( crate :: vtable:: size_of_obj ( fx, info) , crate :: vtable:: min_align_of_obj ( fx, info) )
209
+ (
210
+ crate :: vtable:: size_of_obj ( fx, info. unwrap ( ) ) ,
211
+ crate :: vtable:: min_align_of_obj ( fx, info. unwrap ( ) ) ,
212
+ )
200
213
}
201
214
ty:: Slice ( _) | ty:: Str => {
202
215
let unit = layout. field ( fx, 0 ) ;
203
216
// The info in this case is the length of the str, so the size is that
204
217
// times the unit size.
205
218
(
206
- fx. bcx . ins ( ) . imul_imm ( info, unit. size . bytes ( ) as i64 ) ,
219
+ fx. bcx . ins ( ) . imul_imm ( info. unwrap ( ) , unit. size . bytes ( ) as i64 ) ,
207
220
fx. bcx . ins ( ) . iconst ( fx. pointer_type , unit. align . abi . bytes ( ) as i64 ) ,
208
221
)
209
222
}
210
- _ => {
223
+ ty:: Foreign ( _) => {
224
+ let trap_block = fx. bcx . create_block ( ) ;
225
+ let true_ = fx. bcx . ins ( ) . iconst ( types:: I8 , 1 ) ;
226
+ let next_block = fx. bcx . create_block ( ) ;
227
+ fx. bcx . ins ( ) . brif ( true_, trap_block, & [ ] , next_block, & [ ] ) ;
228
+ fx. bcx . seal_block ( trap_block) ;
229
+ fx. bcx . seal_block ( next_block) ;
230
+ fx. bcx . switch_to_block ( trap_block) ;
231
+
232
+ // `extern` type. We cannot compute the size, so panic.
233
+ let msg_str = with_no_visible_paths ! ( {
234
+ with_no_trimmed_paths!( {
235
+ format!( "attempted to compute the size or alignment of extern type `{ty}`" )
236
+ } )
237
+ } ) ;
238
+
239
+ codegen_panic_nounwind ( fx, & msg_str, None ) ;
240
+
241
+ fx. bcx . switch_to_block ( next_block) ;
242
+
243
+ // This function does not return so we can now return whatever we want.
244
+ let size = fx. bcx . ins ( ) . iconst ( fx. pointer_type , 42 ) ;
245
+ let align = fx. bcx . ins ( ) . iconst ( fx. pointer_type , 42 ) ;
246
+ ( size, align)
247
+ }
248
+ ty:: Adt ( ..) | ty:: Tuple ( ..) => {
211
249
// First get the size of all statically known fields.
212
250
// Don't use size_of because it also rounds up to alignment, which we
213
251
// want to avoid, as the unsized field's alignment could be smaller.
@@ -221,7 +259,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
221
259
// Recurse to get the size of the dynamically sized field (must be
222
260
// the last field).
223
261
let field_layout = layout. field ( fx, i) ;
224
- let ( unsized_size, mut unsized_align) = size_and_align_of_dst ( fx, field_layout, info) ;
262
+ let ( unsized_size, mut unsized_align) = size_and_align_of ( fx, field_layout, info) ;
225
263
226
264
// FIXME (#26403, #27023): We should be adding padding
227
265
// to `sized_size` (to accommodate the `unsized_align`
@@ -262,5 +300,6 @@ pub(crate) fn size_and_align_of_dst<'tcx>(
262
300
263
301
( size, align)
264
302
}
303
+ _ => bug ! ( "size_and_align_of_dst: {ty} not supported" ) ,
265
304
}
266
305
}
0 commit comments