@@ -1844,13 +1844,8 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
18441844 jl_typename_t * tn = dt -> name ;
18451845 int istuple = (tn == jl_tuple_typename );
18461846 int isnamedtuple = (tn == jl_namedtuple_typename );
1847- if (check && tn != jl_type_typename ) {
1848- size_t i ;
1849- for (i = 0 ; i < ntp ; i ++ )
1850- iparams [i ] = normalize_unionalls (iparams [i ]);
1851- }
18521847
1853- // check type cache, if applicable
1848+ // check if type cache will be applicable
18541849 int cacheable = 1 ;
18551850 if (istuple ) {
18561851 size_t i ;
@@ -1886,26 +1881,32 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
18861881 if (jl_has_free_typevars (iparams [i ]))
18871882 cacheable = 0 ;
18881883 }
1884+ // if applicable, check the cache first for a match
18891885 if (cacheable ) {
1886+ jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
1887+ if (lkup != NULL )
1888+ return lkup ;
1889+ }
1890+ // if some normalization might be needed, do that now
1891+ // it is probably okay to mutate iparams, and we only store globally rooted objects here
1892+ if (check && cacheable ) {
18901893 size_t i ;
18911894 for (i = 0 ; i < ntp ; i ++ ) {
18921895 jl_value_t * pi = iparams [i ];
18931896 if (pi == jl_bottom_type )
18941897 continue ;
18951898 if (jl_is_datatype (pi ))
18961899 continue ;
1897- if (jl_is_vararg (pi )) {
1898- pi = jl_unwrap_vararg (pi );
1899- if (jl_has_free_typevars (pi ))
1900- continue ;
1901- }
1902- // normalize types equal to wrappers (prepare for wrapper_id)
1900+ if (jl_is_vararg (pi ))
1901+ // This would require some special handling, but is not needed
1902+ // at the moment (and might be better handled in jl_wrap_vararg instead).
1903+ continue ;
1904+ if (!cacheable && jl_has_free_typevars (pi ))
1905+ continue ;
1906+ // normalize types equal to wrappers (prepare for Typeofwrapper)
19031907 jl_value_t * tw = extract_wrapper (pi );
19041908 if (tw && tw != pi && (tn != jl_type_typename || jl_typeof (pi ) == jl_typeof (tw )) &&
19051909 jl_types_equal (pi , tw )) {
1906- // This would require some special handling, but is never used at
1907- // the moment.
1908- assert (!jl_is_vararg (iparams [i ]));
19091910 iparams [i ] = tw ;
19101911 if (p ) jl_gc_wb (p , tw );
19111912 }
@@ -1915,6 +1916,9 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
19151916 // normalize Type{Type{Union{}}} to Type{TypeofBottom}
19161917 iparams [0 ] = (jl_value_t * )jl_typeofbottom_type ;
19171918 }
1919+ }
1920+ // then check the cache again, if applicable
1921+ if (cacheable ) {
19181922 jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
19191923 if (lkup != NULL )
19201924 return lkup ;
@@ -1923,12 +1927,15 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
19231927 if (stack_lkup )
19241928 return stack_lkup ;
19251929
1930+ // check parameters against bounds in type definition
1931+ // for whether this is even valid
19261932 if (check && !istuple ) {
1927- // check parameters against bounds in type definition
1933+ assert ( ntp > 0 );
19281934 check_datatype_parameters (tn , iparams , ntp );
19291935 }
19301936 else if (ntp == 0 && jl_emptytuple_type != NULL ) {
19311937 // empty tuple type case
1938+ assert (istuple );
19321939 return (jl_value_t * )jl_emptytuple_type ;
19331940 }
19341941
@@ -1974,6 +1981,42 @@ static jl_value_t *inst_datatype_inner(jl_datatype_t *dt, jl_svec_t *p, jl_value
19741981 jl_svecset (p , i , iparams [i ]);
19751982 }
19761983
1984+ // try to simplify some type parameters
1985+ if (check && tn != jl_type_typename ) {
1986+ size_t i ;
1987+ int changed = 0 ;
1988+ if (istuple ) // normalization might change Tuple's, but not other types's, cacheable status
1989+ cacheable = 1 ;
1990+ for (i = 0 ; i < ntp ; i ++ ) {
1991+ jl_value_t * newp = normalize_unionalls (iparams [i ]);
1992+ if (newp != iparams [i ]) {
1993+ iparams [i ] = newp ;
1994+ jl_svecset (p , i , newp );
1995+ changed = 1 ;
1996+ }
1997+ if (istuple && cacheable && !jl_is_concrete_type (newp ))
1998+ cacheable = 0 ;
1999+ }
2000+ if (changed ) {
2001+ // If this changed something, we need to check the cache again, in
2002+ // case we missed the match earlier before the normalizations
2003+ //
2004+ // e.g. return inst_datatype_inner(dt, p, iparams, ntp, stack, env, 0);
2005+ if (cacheable ) {
2006+ jl_value_t * lkup = (jl_value_t * )lookup_type (tn , iparams , ntp );
2007+ if (lkup != NULL ) {
2008+ JL_GC_POP ();
2009+ return lkup ;
2010+ }
2011+ }
2012+ jl_value_t * stack_lkup = lookup_type_stack (stack , dt , ntp , iparams );
2013+ if (stack_lkup ) {
2014+ JL_GC_POP ();
2015+ return stack_lkup ;
2016+ }
2017+ }
2018+ }
2019+
19772020 // acquire the write lock now that we know we need a new object
19782021 // since we're going to immediately leak it globally via the instantiation stack
19792022 if (cacheable ) {
0 commit comments