@@ -113,6 +113,8 @@ jl_unionall_t *jl_pointer_type;
113113jl_typename_t * jl_pointer_typename ;
114114jl_datatype_t * jl_void_type ;
115115jl_datatype_t * jl_voidpointer_type ;
116+ jl_typename_t * jl_namedtuple_typename ;
117+ jl_unionall_t * jl_namedtuple_type ;
116118jl_value_t * jl_an_empty_vec_any = NULL ;
117119jl_value_t * jl_stackovf_exception ;
118120#ifdef SEGV_EXCEPTION
@@ -1006,6 +1008,7 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
10061008 jl_typestack_t top ;
10071009 jl_typename_t * tn = dt -> name ;
10081010 int istuple = (tn == jl_tuple_typename );
1011+ int isnamedtuple = (tn == jl_namedtuple_typename );
10091012 // check type cache
10101013 if (cacheable ) {
10111014 JL_LOCK (& typecache_lock ); // Might GC
@@ -1126,7 +1129,32 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
11261129 ndt -> super = NULL ;
11271130 ndt -> parameters = p ;
11281131 jl_gc_wb (ndt , ndt -> parameters );
1129- ndt -> types = istuple ? p : NULL ; // to be filled in below
1132+ ndt -> types = NULL ; // to be filled in below
1133+ if (istuple ) {
1134+ ndt -> types = p ;
1135+ }
1136+ else if (isnamedtuple ) {
1137+ jl_value_t * names_tup = jl_svecref (p , 0 );
1138+ jl_value_t * values_tt = jl_svecref (p , 1 );
1139+ if (!jl_has_free_typevars (names_tup ) && !jl_has_free_typevars (values_tt )) {
1140+ if (!jl_is_tuple (names_tup ))
1141+ jl_type_error_rt ("NamedTuple" , "names" , jl_anytuple_type , names_tup );
1142+ size_t nf = jl_nfields (names_tup );
1143+ jl_svec_t * names = jl_alloc_svec_uninit (nf );
1144+ for (size_t i = 0 ; i < nf ; i ++ ) {
1145+ jl_value_t * ni = jl_fieldref (names_tup , i );
1146+ if (!jl_is_symbol (ni ))
1147+ jl_type_error_rt ("NamedTuple" , "name" , jl_symbol_type , ni );
1148+ jl_svecset (names , i , ni );
1149+ }
1150+ if (jl_is_va_tuple (values_tt ) || jl_nparams (values_tt ) != nf )
1151+ jl_error ("NamedTuple names and field types must have matching lengths" );
1152+ ndt -> names = names ;
1153+ jl_gc_wb (ndt , ndt -> names );
1154+ ndt -> types = ((jl_datatype_t * )values_tt )-> parameters ;
1155+ jl_gc_wb (ndt , ndt -> types );
1156+ }
1157+ }
11301158 ndt -> mutabl = dt -> mutabl ;
11311159 ndt -> abstract = dt -> abstract ;
11321160 ndt -> instance = NULL ;
@@ -1140,15 +1168,15 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
11401168 if (cacheable && !ndt -> abstract )
11411169 ndt -> uid = jl_assign_type_uid ();
11421170
1143- if (istuple ) {
1171+ if (istuple || isnamedtuple ) {
11441172 ndt -> super = jl_any_type ;
11451173 }
11461174 else if (dt -> super ) {
11471175 ndt -> super = (jl_datatype_t * )inst_type_w_ ((jl_value_t * )dt -> super , env , stack , 1 );
11481176 jl_gc_wb (ndt , ndt -> super );
11491177 }
11501178 jl_svec_t * ftypes = dt -> types ;
1151- if (!istuple && ndt -> name -> names == jl_emptysvec ) {
1179+ if (!istuple && jl_field_names ( ndt ) == jl_emptysvec ) {
11521180 assert (ftypes == NULL || ftypes == jl_emptysvec );
11531181 ndt -> size = dt -> size ;
11541182 ndt -> layout = dt -> layout ;
@@ -1161,13 +1189,13 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
11611189 if (ftypes == NULL || dt -> super == NULL ) {
11621190 // in the process of creating this type definition:
11631191 // need to instantiate the super and types fields later
1164- assert (inside_typedef && !istuple );
1192+ assert (inside_typedef && !istuple && ! isnamedtuple );
11651193 arraylist_push (& partial_inst , ndt );
11661194 }
11671195 else {
1168- if (ftypes != jl_emptysvec ) {
1196+ if (ftypes != jl_emptysvec || isnamedtuple ) {
11691197 assert (!ndt -> abstract );
1170- if (!istuple ) {
1198+ if (!istuple && ! isnamedtuple ) {
11711199 // recursively instantiate the types of the fields
11721200 ndt -> types = inst_all (ftypes , env , stack , 1 );
11731201 jl_gc_wb (ndt , ndt -> types );
@@ -1186,6 +1214,8 @@ static jl_value_t *inst_datatype(jl_datatype_t *dt, jl_svec_t *p, jl_value_t **i
11861214 }
11871215 if (istuple )
11881216 ndt -> ninitialized = ntp ;
1217+ else if (isnamedtuple )
1218+ ndt -> ninitialized = jl_svec_len (ndt -> types );
11891219 else
11901220 ndt -> ninitialized = dt -> ninitialized ;
11911221
@@ -1565,11 +1595,12 @@ void jl_init_types(void)
15651595 jl_datatype_type -> name -> wrapper = (jl_value_t * )jl_datatype_type ;
15661596 jl_datatype_type -> super = (jl_datatype_t * )jl_type_type ;
15671597 jl_datatype_type -> parameters = jl_emptysvec ;
1568- jl_datatype_type -> name -> names = jl_perm_symsvec (16 ,
1598+ jl_datatype_type -> name -> names = jl_perm_symsvec (17 ,
15691599 "name" ,
15701600 "super" ,
15711601 "parameters" ,
15721602 "types" ,
1603+ "names" ,
15731604 "instance" ,
15741605 "layout" ,
15751606 "size" ,
@@ -1582,11 +1613,11 @@ void jl_init_types(void)
15821613 "depth" ,
15831614 "hasfreetypevars" ,
15841615 "isleaftype" );
1585- jl_datatype_type -> types = jl_svec (16 ,
1616+ jl_datatype_type -> types = jl_svec (17 ,
15861617 jl_typename_type ,
15871618 jl_datatype_type ,
15881619 jl_simplevector_type ,
1589- jl_simplevector_type ,
1620+ jl_simplevector_type , jl_simplevector_type ,
15901621 jl_any_type , // instance
15911622 jl_any_type , jl_any_type , jl_any_type , jl_any_type ,
15921623 jl_any_type , jl_any_type , jl_any_type , jl_any_type ,
@@ -2028,20 +2059,28 @@ void jl_init_types(void)
20282059 jl_perm_symsvec (1 , "len" ), jl_svec1 (jl_long_type ),
20292060 0 , 1 , 1 );
20302061
2062+ jl_tvar_t * ntval_var = jl_new_typevar (jl_symbol ("T" ), (jl_value_t * )jl_bottom_type ,
2063+ (jl_value_t * )jl_anytuple_type );
2064+ tv = jl_svec2 (tvar ("names" ), ntval_var );
2065+ jl_datatype_t * ntt = jl_new_datatype (jl_symbol ("NamedTuple" ), jl_any_type , tv ,
2066+ jl_emptysvec , jl_emptysvec , 0 , 0 , 0 );
2067+ jl_namedtuple_type = (jl_unionall_t * )ntt -> name -> wrapper ;
2068+ jl_namedtuple_typename = ntt -> name ;
2069+
20312070 // complete builtin type metadata
20322071 jl_value_t * pointer_void = jl_apply_type1 ((jl_value_t * )jl_pointer_type , (jl_value_t * )jl_void_type );
20332072 jl_voidpointer_type = (jl_datatype_t * )pointer_void ;
2034- jl_svecset (jl_datatype_type -> types , 5 , jl_voidpointer_type );
2035- jl_svecset (jl_datatype_type -> types , 6 , jl_int32_type );
2073+ jl_svecset (jl_datatype_type -> types , 6 , jl_voidpointer_type );
20362074 jl_svecset (jl_datatype_type -> types , 7 , jl_int32_type );
20372075 jl_svecset (jl_datatype_type -> types , 8 , jl_int32_type );
2038- jl_svecset (jl_datatype_type -> types , 9 , jl_bool_type );
2076+ jl_svecset (jl_datatype_type -> types , 9 , jl_int32_type );
20392077 jl_svecset (jl_datatype_type -> types , 10 , jl_bool_type );
2040- jl_svecset (jl_datatype_type -> types , 11 , jl_voidpointer_type );
2078+ jl_svecset (jl_datatype_type -> types , 11 , jl_bool_type );
20412079 jl_svecset (jl_datatype_type -> types , 12 , jl_voidpointer_type );
2042- jl_svecset (jl_datatype_type -> types , 13 , jl_int32_type );
2043- jl_svecset (jl_datatype_type -> types , 14 , jl_bool_type );
2080+ jl_svecset (jl_datatype_type -> types , 13 , jl_voidpointer_type );
2081+ jl_svecset (jl_datatype_type -> types , 14 , jl_int32_type );
20442082 jl_svecset (jl_datatype_type -> types , 15 , jl_bool_type );
2083+ jl_svecset (jl_datatype_type -> types , 16 , jl_bool_type );
20452084 jl_svecset (jl_simplevector_type -> types , 0 , jl_long_type );
20462085 jl_svecset (jl_typename_type -> types , 1 , jl_module_type );
20472086 jl_svecset (jl_typename_type -> types , 6 , jl_long_type );
0 commit comments