@@ -1120,6 +1120,93 @@ static jl_value_t *normalize_vararg(jl_value_t *va)
1120
1120
return va ;
1121
1121
}
1122
1122
1123
+ int _may_substitute_ub (jl_value_t * v , jl_tvar_t * var , int inside_inv , int * cov_count ) JL_NOTSAFEPOINT
1124
+ {
1125
+ if (v == (jl_value_t * )var ) {
1126
+ if (inside_inv ) {
1127
+ return 0 ;
1128
+ }
1129
+ else {
1130
+ (* cov_count )++ ;
1131
+ return * cov_count <= 1 || jl_is_concrete_type (var -> ub );
1132
+ }
1133
+ }
1134
+ else if (jl_is_uniontype (v )) {
1135
+ return _may_substitute_ub (((jl_uniontype_t * )v )-> a , var , inside_inv , cov_count ) &&
1136
+ _may_substitute_ub (((jl_uniontype_t * )v )-> b , var , inside_inv , cov_count );
1137
+ }
1138
+ else if (jl_is_unionall (v )) {
1139
+ jl_unionall_t * ua = (jl_unionall_t * )v ;
1140
+ if (ua -> var == var )
1141
+ return 1 ;
1142
+ return _may_substitute_ub (ua -> var -> lb , var , inside_inv , cov_count ) &&
1143
+ _may_substitute_ub (ua -> var -> ub , var , inside_inv , cov_count ) &&
1144
+ _may_substitute_ub (ua -> body , var , inside_inv , cov_count );
1145
+ }
1146
+ else if (jl_is_vararg_type (v )) {
1147
+ int old_count = * cov_count ;
1148
+ jl_value_t * vaT = jl_tparam0 (v );
1149
+ jl_value_t * vaN = jl_tparam1 (v );
1150
+ if (!_may_substitute_ub (vaT , var , inside_inv , cov_count ))
1151
+ return 0 ;
1152
+ if (* cov_count > old_count && !jl_is_concrete_type (var -> ub ))
1153
+ return 0 ;
1154
+ if (!_may_substitute_ub (vaN , var , 1 , cov_count ))
1155
+ return 0 ;
1156
+ }
1157
+ else if (jl_is_datatype (v )) {
1158
+ int invar = inside_inv || !jl_is_tuple_type (v );
1159
+ for (size_t i = 0 ; i < jl_nparams (v ); i ++ ) {
1160
+ if (!_may_substitute_ub (jl_tparam (v ,i ), var , invar , cov_count ))
1161
+ return 0 ;
1162
+ }
1163
+ }
1164
+ return 1 ;
1165
+ }
1166
+
1167
+ // Check whether `var` may be replaced with its upper bound `ub` in `v where var<:ub`
1168
+ // Conditions:
1169
+ // * `var` does not appear in invariant position
1170
+ // * `var` appears at most once (in covariant position) and not in a `Vararg`
1171
+ // unless the upper bound is concrete (diagonal rule)
1172
+ int may_substitute_ub (jl_value_t * v , jl_tvar_t * var ) JL_NOTSAFEPOINT
1173
+ {
1174
+ int cov_count = 0 ;
1175
+ return _may_substitute_ub (v , var , 0 , & cov_count );
1176
+ }
1177
+
1178
+ jl_value_t * normalize_unionalls (jl_value_t * t )
1179
+ {
1180
+ JL_GC_PUSH1 (& t );
1181
+ if (jl_is_uniontype (t )) {
1182
+ jl_uniontype_t * u = (jl_uniontype_t * )t ;
1183
+ jl_value_t * a = NULL ;
1184
+ jl_value_t * b = NULL ;
1185
+ JL_GC_PUSH2 (& a , & b );
1186
+ a = normalize_unionalls (u -> a );
1187
+ b = normalize_unionalls (u -> b );
1188
+ if (a != u -> a || b != u -> b ) {
1189
+ t = jl_new_struct (jl_uniontype_type , a , b );
1190
+ }
1191
+ JL_GC_POP ();
1192
+ }
1193
+ else if (jl_is_unionall (t )) {
1194
+ jl_unionall_t * u = (jl_unionall_t * )t ;
1195
+ jl_value_t * body = normalize_unionalls (u -> body );
1196
+ if (body != u -> body ) {
1197
+ JL_GC_PUSH1 (& body );
1198
+ t = jl_new_struct (jl_unionall_type , u -> var , body );
1199
+ JL_GC_POP ();
1200
+ u = (jl_unionall_t * )t ;
1201
+ }
1202
+
1203
+ if (u -> var -> lb == u -> var -> ub || may_substitute_ub (body , u -> var ))
1204
+ t = jl_instantiate_unionall (u , u -> var -> ub );
1205
+ }
1206
+ JL_GC_POP ();
1207
+ return t ;
1208
+ }
1209
+
1123
1210
static jl_value_t * _jl_instantiate_type_in_env (jl_value_t * ty , jl_unionall_t * env , jl_value_t * * vals , jl_typeenv_t * prev , jl_typestack_t * stack );
1124
1211
1125
1212
static jl_value_t * inst_datatype_inner (jl_datatype_t * dt , jl_svec_t * p , jl_value_t * * iparams , size_t ntp ,
@@ -1129,6 +1216,11 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
1129
1216
jl_typename_t * tn = dt -> name ;
1130
1217
int istuple = (tn == jl_tuple_typename );
1131
1218
int isnamedtuple = (tn == jl_namedtuple_typename );
1219
+ if (dt -> name != jl_type_typename ) {
1220
+ for (size_t i = 0 ; i < ntp ; i ++ )
1221
+ iparams [i ] = normalize_unionalls (iparams [i ]);
1222
+ }
1223
+
1132
1224
// check type cache
1133
1225
if (cacheable ) {
1134
1226
size_t i ;
0 commit comments