@@ -74,7 +74,13 @@ typedef struct jl_varbinding_t {
7474 // 1 - var.ub = ub; return var
7575 // 2 - either (var.ub = ub; return var), or return ub
7676 int8_t constraintkind ;
77- int8_t intvalued ; // must be integer-valued; i.e. occurs as N in Vararg{_,N}
77+ // intvalued: must be integer-valued; i.e. occurs as N in Vararg{_,N}
78+ // 0: No restriction
79+ // 1: must be unbounded/ or fixed to a `Int`/typevar
80+ // 2: This var has been commandeered once.
81+ // 3: This var has been commandeered more than once.
82+ // 4: This var has been commandeered more than once, and it has no fixed ub/lb.
83+ int8_t intvalued ;
7884 int8_t limited ;
7985 int16_t depth0 ; // # of invariant constructors nested around the UnionAll type for this var
8086 // when this variable's integer value is compared to that of another,
@@ -2194,13 +2200,23 @@ static jl_value_t *bound_var_below(jl_tvar_t *tv, jl_varbinding_t *bb, jl_stenv_
21942200 return jl_bottom_type ;
21952201 record_var_occurrence (bb , e , 2 );
21962202 if (jl_is_long (bb -> lb )) {
2203+ if (jl_unbox_long (bb -> lb ) < bb -> offset || jl_unbox_long (bb -> lb ) < 0 )
2204+ return jl_bottom_type ;
21972205 // Here we always return the shorter `Vararg`'s length.
21982206 if (bb -> offset <= 0 )
21992207 return bb -> lb ;
2200- if (jl_unbox_long (bb -> lb ) < bb -> offset )
2201- return jl_bottom_type ;
22022208 return jl_box_long (jl_unbox_long (bb -> lb ) - bb -> offset );
22032209 }
2210+ if (bb -> intvalued == 1 && bb -> offset > 0 )
2211+ // We really should return `tv` here, but some subtype tests need it.
2212+ // As a temparay fix, increase `intvalued` to 2.
2213+ bb -> intvalued = 2 ;
2214+ else if (bb -> intvalued == 2 )
2215+ // If bb has been commandeered, we should always increase `intvalued`.
2216+ bb -> intvalued = 3 ;
2217+ else if (bb -> intvalued == 4 && bb -> offset > 0 )
2218+ // bb has no fixed bounds, return `NULL` if `tv` is not correct.
2219+ return NULL ;
22042220 return (jl_value_t * )tv ;
22052221}
22062222
@@ -2452,6 +2468,13 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind
24522468 }
24532469 }
24542470
2471+ // This typevar has been commandeered by the other side once. Which is allowed if it's unbounded.
2472+ if (vb -> intvalued == 2 && vb -> lb == jl_bottom_type && vb -> ub == (jl_value_t * )jl_any_type )
2473+ vb -> intvalued = 1 ;
2474+ // This typevar has been commandeered more than once. Set it to 4 if its not fixed.
2475+ if (vb -> intvalued == 3 && !(varval && jl_is_long (varval )))
2476+ vb -> intvalued = 4 ;
2477+
24552478 // TODO: this can prevent us from matching typevar identities later
24562479 if (!varval && (vb -> lb != vb -> var -> lb || vb -> ub != vb -> var -> ub ))
24572480 newvar = jl_new_typevar (vb -> var -> name , vb -> lb , vb -> ub );
@@ -2644,7 +2667,7 @@ static jl_value_t *intersect_unionall(jl_value_t *t, jl_unionall_t *u, jl_stenv_
26442667 e -> vars -> limited = 1 ;
26452668 }
26462669 else if (res != jl_bottom_type ) {
2647- if (vb .concrete || vb .occurs_inv > 1 || u -> var -> lb != jl_bottom_type || (vb .occurs_inv && vb .occurs_cov )) {
2670+ if (vb .concrete || vb .occurs_inv > 1 || vb . intvalued > 1 || u -> var -> lb != jl_bottom_type || (vb .occurs_inv && vb .occurs_cov )) {
26482671 restore_env (e , NULL , & se );
26492672 vb .occurs_cov = vb .occurs_inv = 0 ;
26502673 vb .constraintkind = vb .concrete ? 1 : 2 ;
@@ -2701,7 +2724,7 @@ static jl_value_t *intersect_varargs(jl_vararg_t *vmx, jl_vararg_t *vmy, size_t
27012724 if (xp2 && jl_is_typevar (xp2 )) {
27022725 xb = lookup (e , (jl_tvar_t * )xp2 );
27032726 if (xb ) {
2704- xb -> intvalued = 1 ;
2727+ if ( xb -> intvalued == 0 ) xb -> intvalued = 1 ;
27052728 xb -> offset = offset ;
27062729 }
27072730 if (!yp2 )
@@ -2710,7 +2733,7 @@ static jl_value_t *intersect_varargs(jl_vararg_t *vmx, jl_vararg_t *vmy, size_t
27102733 if (yp2 && jl_is_typevar (yp2 )) {
27112734 yb = lookup (e , (jl_tvar_t * )yp2 );
27122735 if (yb ) {
2713- yb -> intvalued = 1 ;
2736+ if ( yb -> intvalued == 0 ) yb -> intvalued = 1 ;
27142737 yb -> offset = - offset ;
27152738 }
27162739 if (!xp2 )
0 commit comments