@@ -333,7 +333,7 @@ JL_DLLEXPORT int jl_get_size(jl_value_t *val, size_t *pnt)
333333 if (jl_is_long (val )) {
334334 ssize_t slen = jl_unbox_long (val );
335335 if (slen < 0 )
336- jl_errorf ("size or dimension is negative: %d " , slen );
336+ jl_errorf ("size or dimension is negative: %zd " , slen );
337337 * pnt = slen ;
338338 return 1 ;
339339 }
@@ -1435,17 +1435,6 @@ jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *ty)
14351435 return rettyp ;
14361436}
14371437
1438- // used to expand an NTuple to a flat representation
1439- static jl_value_t * jl_tupletype_fill (size_t n , jl_value_t * v )
1440- {
1441- jl_value_t * p = NULL ;
1442- JL_GC_PUSH1 (& p );
1443- p = (jl_value_t * )jl_svec_fill (n , v );
1444- p = jl_apply_tuple_type ((jl_svec_t * )p );
1445- JL_GC_POP ();
1446- return p ;
1447- }
1448-
14491438JL_EXTENSION struct _jl_typestack_t {
14501439 jl_datatype_t * tt ;
14511440 struct _jl_typestack_t * prev ;
@@ -1796,13 +1785,13 @@ int _may_substitute_ub(jl_value_t *v, jl_tvar_t *var, int inside_inv, int *cov_c
17961785// * `var` does not appear in invariant position
17971786// * `var` appears at most once (in covariant position) and not in a `Vararg`
17981787// unless the upper bound is concrete (diagonal rule)
1799- int may_substitute_ub (jl_value_t * v , jl_tvar_t * var ) JL_NOTSAFEPOINT
1788+ static int may_substitute_ub (jl_value_t * v , jl_tvar_t * var ) JL_NOTSAFEPOINT
18001789{
18011790 int cov_count = 0 ;
18021791 return _may_substitute_ub (v , var , 0 , & cov_count );
18031792}
18041793
1805- jl_value_t * normalize_unionalls (jl_value_t * t )
1794+ static jl_value_t * normalize_unionalls (jl_value_t * t )
18061795{
18071796 if (jl_is_uniontype (t )) {
18081797 jl_uniontype_t * u = (jl_uniontype_t * )t ;
@@ -1840,6 +1829,29 @@ jl_value_t *normalize_unionalls(jl_value_t *t)
18401829 return t ;
18411830}
18421831
1832+ // used to expand an NTuple to a flat representation
1833+ static jl_value_t * jl_tupletype_fill (size_t n , jl_value_t * t , int check )
1834+ {
1835+ if (check ) {
1836+ // Since we are skipping making the Vararg, we inline the checks from jl_wrap_vararg here
1837+ if (!jl_is_type (t ) && !jl_is_typevar (t )) {
1838+ jl_type_error_rt ("Vararg" , "type" , (jl_value_t * )jl_type_type , t );
1839+ }
1840+ // jl_wrap_vararg sometimes simplifies the type, so we only do this 1 time, instead of for each n later
1841+ t = normalize_unionalls (t );
1842+ jl_value_t * tw = extract_wrapper (t );
1843+ if (tw && t != tw && jl_types_equal (t , tw ))
1844+ t = tw ;
1845+ check = 0 ; // remember that checks are already done now
1846+ }
1847+ jl_value_t * p = NULL ;
1848+ JL_GC_PUSH1 (& p );
1849+ p = (jl_value_t * )jl_svec_fill (n , t );
1850+ p = jl_apply_tuple_type ((jl_svec_t * )p , check );
1851+ JL_GC_POP ();
1852+ return p ;
1853+ }
1854+
18431855static 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 );
18441856
18451857static jl_value_t * inst_datatype_inner (jl_datatype_t * dt , jl_svec_t * p , jl_value_t * * iparams , size_t ntp ,
@@ -1962,7 +1974,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
19621974 if (nt == 0 || !jl_has_free_typevars (va0 )) {
19631975 if (ntp == 1 ) {
19641976 JL_GC_POP ();
1965- return jl_tupletype_fill (nt , va0 );
1977+ return jl_tupletype_fill (nt , va0 , 0 );
19661978 }
19671979 size_t i , l ;
19681980 p = jl_alloc_svec (ntp - 1 + nt );
@@ -1971,7 +1983,7 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
19711983 l = ntp - 1 + nt ;
19721984 for (; i < l ; i ++ )
19731985 jl_svecset (p , i , va0 );
1974- jl_value_t * ndt = jl_apply_tuple_type (p );
1986+ jl_value_t * ndt = jl_apply_tuple_type (p , check );
19751987 JL_GC_POP ();
19761988 return ndt ;
19771989 }
@@ -2136,19 +2148,19 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
21362148 return (jl_value_t * )ndt ;
21372149}
21382150
2139- static jl_value_t * jl_apply_tuple_type_v_ (jl_value_t * * p , size_t np , jl_svec_t * params )
2151+ static jl_value_t * jl_apply_tuple_type_v_ (jl_value_t * * p , size_t np , jl_svec_t * params , int check )
21402152{
2141- return inst_datatype_inner (jl_anytuple_type , params , p , np , NULL , NULL , 1 );
2153+ return inst_datatype_inner (jl_anytuple_type , params , p , np , NULL , NULL , check );
21422154}
21432155
2144- JL_DLLEXPORT jl_value_t * jl_apply_tuple_type (jl_svec_t * params )
2156+ JL_DLLEXPORT jl_value_t * jl_apply_tuple_type (jl_svec_t * params , int check )
21452157{
2146- return jl_apply_tuple_type_v_ (jl_svec_data (params ), jl_svec_len (params ), params );
2158+ return jl_apply_tuple_type_v_ (jl_svec_data (params ), jl_svec_len (params ), params , check );
21472159}
21482160
21492161JL_DLLEXPORT jl_value_t * jl_apply_tuple_type_v (jl_value_t * * p , size_t np )
21502162{
2151- return jl_apply_tuple_type_v_ (p , np , NULL );
2163+ return jl_apply_tuple_type_v_ (p , np , NULL , 1 );
21522164}
21532165
21542166jl_tupletype_t * jl_lookup_arg_tuple_type (jl_value_t * arg1 , jl_value_t * * args , size_t nargs , int leaf )
@@ -2211,13 +2223,16 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_
22112223 jl_datatype_t * tt = (jl_datatype_t * )t ;
22122224 jl_svec_t * tp = tt -> parameters ;
22132225 size_t ntp = jl_svec_len (tp );
2214- // Instantiate NTuple{3,Int}
2226+ // Instantiate Tuple{Vararg{T,N}} where T is fixed and N is known, such as Dims{3}
2227+ // And avoiding allocating the intermediate steps
22152228 // Note this does not instantiate Tuple{Vararg{Int,3}}; that's done in inst_datatype_inner
2229+ // Note this does not instantiate NTuple{N,T}, since it is unnecessary and inefficient to expand that now
2230+ // and it may skip the constructor checks for jl_wrap_vararg
22162231 if (jl_is_va_tuple (tt ) && ntp == 1 ) {
2217- // If this is a Tuple{Vararg{T,N}} with known N, expand it to
2232+ // If this is a Tuple{Vararg{T,N}} with known N and T , expand it to
22182233 // a fixed-length tuple
22192234 jl_value_t * T = NULL , * N = NULL ;
2220- jl_value_t * va = jl_unwrap_unionall ( jl_tparam0 (tt ) );
2235+ jl_value_t * va = jl_tparam0 (tt );
22212236 jl_value_t * ttT = jl_unwrap_vararg (va );
22222237 jl_value_t * ttN = jl_unwrap_vararg_num (va );
22232238 jl_typeenv_t * e = env ;
@@ -2228,11 +2243,12 @@ static jl_value_t *inst_tuple_w_(jl_value_t *t, jl_typeenv_t *env, jl_typestack_
22282243 N = e -> val ;
22292244 e = e -> prev ;
22302245 }
2231- if (T != NULL && N != NULL && jl_is_long (N )) {
2246+ if (T != NULL && N != NULL && jl_is_long (N ) && !jl_has_free_typevars (T )) {
2247+ // Since this is skipping jl_wrap_vararg, we inline the checks from it here
22322248 ssize_t nt = jl_unbox_long (N );
22332249 if (nt < 0 )
2234- jl_errorf ("size or dimension is negative: %zd" , nt );
2235- return jl_tupletype_fill (nt , T );
2250+ jl_errorf ("Vararg length is negative: %zd" , nt );
2251+ return jl_tupletype_fill (nt , T , check );
22362252 }
22372253 }
22382254 jl_value_t * * iparams ;
@@ -2429,6 +2445,8 @@ jl_vararg_t *jl_wrap_vararg(jl_value_t *t, jl_value_t *n, int check)
24292445 }
24302446 if (t ) {
24312447 if (!jl_is_type (t ) && !jl_is_typevar (t )) {
2448+ // Vararg{T} validation is slightly more strict than DataType parameters,
2449+ // since it only allows Types and not other things like isbits
24322450 jl_type_error_rt ("Vararg" , "type" , (jl_value_t * )jl_type_type , t );
24332451 }
24342452 t = normalize_unionalls (t );
@@ -2729,7 +2747,7 @@ void jl_init_types(void) JL_GC_DISABLED
27292747 jl_anytuple_type -> layout = NULL ;
27302748
27312749 jl_typeofbottom_type -> super = jl_wrap_Type (jl_bottom_type );
2732- jl_emptytuple_type = (jl_datatype_t * )jl_apply_tuple_type (jl_emptysvec );
2750+ jl_emptytuple_type = (jl_datatype_t * )jl_apply_tuple_type (jl_emptysvec , 0 );
27332751 jl_emptytuple = jl_gc_permobj (0 , jl_emptytuple_type );
27342752 jl_emptytuple_type -> instance = jl_emptytuple ;
27352753
0 commit comments