@@ -916,6 +916,32 @@ impl<'a> InferenceTable<'a> {
916916
917917 /// Check if given type is `Sized` or not
918918 pub ( crate ) fn is_sized ( & mut self , ty : & Ty ) -> bool {
919+ let mut ty = ty. clone ( ) ;
920+ {
921+ let mut structs = SmallVec :: < [ _ ; 8 ] > :: new ( ) ;
922+ // Must use a loop here and not recursion because otherwise users will conduct completely
923+ // artificial examples of structs that have themselves as the tail field and complain r-a crashes.
924+ while let Some ( ( AdtId :: StructId ( id) , subst) ) = ty. as_adt ( ) {
925+ let struct_data = self . db . struct_data ( id) ;
926+ if let Some ( ( last_field, _) ) = struct_data. variant_data . fields ( ) . iter ( ) . next_back ( )
927+ {
928+ let last_field_ty = self . db . field_types ( id. into ( ) ) [ last_field]
929+ . clone ( )
930+ . substitute ( Interner , subst) ;
931+ if structs. contains ( & ty) {
932+ // A struct recursively contains itself as a tail field somewhere.
933+ return true ; // Don't overload the users with too many errors.
934+ }
935+ structs. push ( ty) ;
936+ // Structs can have DST as its last field and such cases are not handled
937+ // as unsized by the chalk, so we do this manually.
938+ ty = last_field_ty;
939+ } else {
940+ break ;
941+ } ;
942+ }
943+ }
944+
919945 // Early return for some obvious types
920946 if matches ! (
921947 ty. kind( Interner ) ,
@@ -930,16 +956,6 @@ impl<'a> InferenceTable<'a> {
930956 return true ;
931957 }
932958
933- if let Some ( ( AdtId :: StructId ( id) , subst) ) = ty. as_adt ( ) {
934- let struct_data = self . db . struct_data ( id) ;
935- if let Some ( ( last_field, _) ) = struct_data. variant_data . fields ( ) . iter ( ) . last ( ) {
936- let last_field_ty =
937- self . db . field_types ( id. into ( ) ) [ last_field] . clone ( ) . substitute ( Interner , subst) ;
938- // Structs can have DST as its last field and such cases are not handled
939- // as unsized by the chalk, so we do this manually
940- return self . is_sized ( & last_field_ty) ;
941- }
942- }
943959 let Some ( sized) = self
944960 . db
945961 . lang_item ( self . trait_env . krate , LangItem :: Sized )
0 commit comments