@@ -916,6 +916,32 @@ impl<'a> InferenceTable<'a> {
916
916
917
917
/// Check if given type is `Sized` or not
918
918
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
+
919
945
// Early return for some obvious types
920
946
if matches ! (
921
947
ty. kind( Interner ) ,
@@ -930,16 +956,6 @@ impl<'a> InferenceTable<'a> {
930
956
return true ;
931
957
}
932
958
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
- }
943
959
let Some ( sized) = self
944
960
. db
945
961
. lang_item ( self . trait_env . krate , LangItem :: Sized )
0 commit comments