@@ -1696,42 +1696,48 @@ static int equiv_field_types(jl_value_t *old, jl_value_t *ft)
16961696// inline it. The only way fields can reference this type (due to 
16971697// syntax-enforced restrictions) is via being passed as a type parameter. Thus 
16981698// we can conservatively check this by examining only the parameters of the 
1699- // dependent types. 
1700- // affects_layout is a hack introduced by #35275 to workaround a problem 
1701- // introduced by #34223: it checks whether we will potentially need to 
1702- // compute the layout of the object before we have fully computed the types of 
1703- // the fields during recursion over the allocation of the parameters for the 
1704- // field types (of the concrete subtypes) 
1705- static  int  references_name (jl_value_t  * p , jl_typename_t  * name , int  affects_layout ) JL_NOTSAFEPOINT 
1706- {
1707-     if  (jl_is_uniontype (p ))
1708-         return  references_name (((jl_uniontype_t * )p )-> a , name , affects_layout ) || 
1709-                references_name (((jl_uniontype_t * )p )-> b , name , affects_layout );
1710-     if  (jl_is_vararg (p )) {
1711-         jl_value_t  * T  =  ((jl_vararg_t * )p )-> T ;
1712-         jl_value_t  * N  =  ((jl_vararg_t * )p )-> N ;
1713-         return  (T  &&  references_name (T , name , affects_layout )) || 
1714-                (N  &&  references_name (N , name , affects_layout ));
1715-     }
1716-     if  (jl_is_unionall (p ))
1717-         return  references_name ((jl_value_t * )((jl_unionall_t * )p )-> var -> lb , name , 0 ) || 
1718-                references_name ((jl_value_t * )((jl_unionall_t * )p )-> var -> ub , name , 0 ) || 
1719-                references_name (((jl_unionall_t * )p )-> body , name , affects_layout );
1699+ // dependent types. Additionally, a field might have already observed this 
1700+ // object for layout purposes before we got around to deciding if inlining 
1701+ // would be possible, so we cannot change the layout now if so. 
1702+ // affects_layout is a (conservative) analysis of layout_uses_free_typevars 
1703+ // freevars is a (conservative) analysis of what calling jl_has_bound_typevars from name->wrapper gives (TODO: just call this instead?) 
1704+ static  int  references_name (jl_value_t  * p , jl_typename_t  * name , int  affects_layout , int  freevars ) JL_NOTSAFEPOINT 
1705+ {
1706+     if  (freevars  &&  !jl_has_free_typevars (p ))
1707+         freevars  =  0 ;
1708+     while  (jl_is_unionall (p )) {
1709+         if  (references_name ((jl_value_t * )((jl_unionall_t * )p )-> var -> lb , name , 0 , freevars ) || 
1710+             references_name ((jl_value_t * )((jl_unionall_t * )p )-> var -> ub , name , 0 , freevars ))
1711+             return  1 ;
1712+        p  =  ((jl_unionall_t * )p )-> body ;
1713+     }
1714+     if  (jl_is_uniontype (p )) {
1715+         return  references_name (((jl_uniontype_t * )p )-> a , name , affects_layout , freevars ) || 
1716+                references_name (((jl_uniontype_t * )p )-> b , name , affects_layout , freevars );
1717+     }
17201718    if  (jl_is_typevar (p ))
17211719        return  0 ; // already checked by unionall, if applicable 
17221720    if  (jl_is_datatype (p )) {
17231721        jl_datatype_t  * dp  =  (jl_datatype_t * )p ;
17241722        if  (affects_layout  &&  dp -> name  ==  name )
17251723            return  1 ;
1726-         // affects_layout checks whether we will need to attempt to layout this 
1727-         // type (based on whether all copies of it have the same layout) in 
1728-         // that case, we still need to check the recursive parameters for 
1729-         // layout recursion happening also, but we know it won't itself cause 
1730-         // problems for the layout computation 
17311724        affects_layout  =  ((jl_datatype_t * )jl_unwrap_unionall (dp -> name -> wrapper ))-> layout  ==  NULL ;
1725+         // and even if it has a layout, the fields themselves might trigger layouts if they use tparam i 
1726+         // rather than checking this for each field, we just assume it applies 
1727+         if  (!affects_layout  &&  freevars  &&  jl_field_names (dp ) !=  jl_emptysvec ) {
1728+             jl_svec_t  * types  =  ((jl_datatype_t * )jl_unwrap_unionall (dp -> name -> wrapper ))-> types ;
1729+             size_t  i , l  =  jl_svec_len (types );
1730+             for  (i  =  0 ; i  <  l ; i ++ ) {
1731+                 jl_value_t  * ft  =  jl_svecref (types , i );
1732+                 if  (!jl_is_typevar (ft ) &&  jl_has_free_typevars (ft )) {
1733+                     affects_layout  =  1 ;
1734+                     break ;
1735+                 }
1736+             }
1737+         }
17321738        size_t  i , l  =  jl_nparams (p );
17331739        for  (i  =  0 ; i  <  l ; i ++ ) {
1734-             if  (references_name (jl_tparam (p , i ), name , affects_layout ))
1740+             if  (references_name (jl_tparam (p , i ), name , affects_layout ,  freevars ))
17351741                return  1 ;
17361742        }
17371743    }
@@ -1767,12 +1773,12 @@ JL_CALLABLE(jl_f__typebody)
17671773            // able to compute the layout of the object before needing to 
17681774            // publish it, so we must assume it cannot be inlined, if that 
17691775            // check passes, then we also still need to check the fields too. 
1770-             if  (!dt -> name -> mutabl  &&  (nf  ==  0  ||  !references_name ((jl_value_t * )dt -> super , dt -> name , 1 ))) {
1776+             if  (!dt -> name -> mutabl  &&  (nf  ==  0  ||  !references_name ((jl_value_t * )dt -> super , dt -> name , 0 ,  1 ))) {
17711777                int  mayinlinealloc  =  1 ;
17721778                size_t  i ;
17731779                for  (i  =  0 ; i  <  nf ; i ++ ) {
17741780                    jl_value_t  * fld  =  jl_svecref (ft , i );
1775-                     if  (references_name (fld , dt -> name , 1 )) {
1781+                     if  (references_name (fld , dt -> name , 1 ,  1 )) {
17761782                        mayinlinealloc  =  0 ;
17771783                        break ;
17781784                    }
0 commit comments