@@ -8,7 +8,9 @@ use rustc_middle::ty::layout::{
88 IntegerExt , LayoutCx , LayoutError , LayoutOf , TyAndLayout , MAX_SIMD_LANES ,
99} ;
1010use rustc_middle:: ty:: print:: with_no_trimmed_paths;
11- use rustc_middle:: ty:: { self , AdtDef , EarlyBinder , GenericArgsRef , Ty , TyCtxt , TypeVisitableExt } ;
11+ use rustc_middle:: ty:: {
12+ self , AdtDef , EarlyBinder , FieldDef , GenericArgsRef , Ty , TyCtxt , TypeVisitableExt ,
13+ } ;
1214use rustc_session:: { DataTypeKind , FieldInfo , FieldKind , SizeKind , VariantInfo } ;
1315use rustc_span:: sym;
1416use rustc_span:: symbol:: Symbol ;
@@ -506,6 +508,33 @@ fn layout_of_uncached<'tcx>(
506508 ) ) ;
507509 }
508510
511+ let is_unsized_field = |field : & FieldDef | {
512+ let field_ty = tcx. type_of ( field. did ) ;
513+ tcx. try_instantiate_and_normalize_erasing_regions ( args, cx. param_env , field_ty)
514+ . map ( |f| !f. is_sized ( tcx, cx. param_env ) )
515+ . map_err ( |e| {
516+ error (
517+ cx,
518+ LayoutError :: NormalizationFailure ( field_ty. instantiate_identity ( ) , e) ,
519+ )
520+ } )
521+ } ;
522+
523+ if def. is_struct ( )
524+ && let Some ( ( _, fields_except_last) ) =
525+ def. non_enum_variant ( ) . fields . raw . split_last ( )
526+ {
527+ for f in fields_except_last {
528+ if is_unsized_field ( f) ? {
529+ cx. tcx . dcx ( ) . span_delayed_bug (
530+ tcx. def_span ( def. did ( ) ) ,
531+ "only the last field of a struct can be unsized" ,
532+ ) ;
533+ return Err ( error ( cx, LayoutError :: Unknown ( ty) ) ) ;
534+ }
535+ }
536+ }
537+
509538 let get_discriminant_type =
510539 |min, max| Integer :: repr_discr ( tcx, ty, & def. repr ( ) , min, max) ;
511540
0 commit comments