@@ -452,6 +452,7 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb))
452452        aty =  widenconst (typea)
453453        bty =  widenconst (typeb)
454454        if  aty ===  bty
455+             #  must have egal here, since we do not create PartialStruct for non-concrete types
455456            typea_nfields =  nfields_tfunc (typea)
456457            typeb_nfields =  nfields_tfunc (typeb)
457458            isa (typea_nfields, Const) ||  return  aty
@@ -460,18 +461,40 @@ function tmerge(@nospecialize(typea), @nospecialize(typeb))
460461            type_nfields ===  typeb_nfields. val:: Int  ||  return  aty
461462            type_nfields ==  0  &&  return  aty
462463            fields =  Vector {Any} (undef, type_nfields)
463-             anyconst  =  false 
464+             anyrefine  =  false 
464465            for  i =  1 : type_nfields
465466                ai =  getfield_tfunc (typea, Const (i))
466467                bi =  getfield_tfunc (typeb, Const (i))
467-                 ity =  tmerge (ai, bi)
468-                 if  ai ===  Union{} ||  bi ===  Union{}
469-                     ity =  widenconst (ity)
468+                 ft =  fieldtype (aty, i)
469+                 if  is_lattice_equal (ai, bi) ||  is_lattice_equal (ai, ft)
470+                     #  Since ai===bi, the given type has no restrictions on complexity.
471+                     #  and can be used to refine ft
472+                     tyi =  ai
473+                 elseif  is_lattice_equal (bi, ft)
474+                     tyi =  bi
475+                 else 
476+                     #  Otherwise choose between using the fieldtype or some other simple merged type.
477+                     #  The wrapper type never has restrictions on complexity,
478+                     #  so try to use that to refine the estimated type too.
479+                     tni =  _typename (widenconst (ai))
480+                     if  tni isa  Const &&  tni ===  _typename (widenconst (bi))
481+                         #  A tmeet call may cause tyi to become complex, but since the inputs were
482+                         #  strictly limited to being egal, this has no restrictions on complexity.
483+                         #  (Otherwise, we would need to use <: and take the narrower one without
484+                         #  intersection. See the similar comment in abstract_call_method.)
485+                         tyi =  typeintersect (ft, (tni. val:: Core.TypeName ). wrapper)
486+                     else 
487+                         #  Since aty===bty, the fieldtype has no restrictions on complexity.
488+                         tyi =  ft
489+                     end 
490+                 end 
491+                 fields[i] =  tyi
492+                 if  ! anyrefine
493+                     anyrefine =  has_nontrivial_const_info (tyi) ||  #  constant information
494+                                 tyi ⋤  ft                          #  just a type-level information, but more precise than the declared type
470495                end 
471-                 fields[i] =  ity
472-                 anyconst |=  has_nontrivial_const_info (ity)
473496            end 
474-             return  anyconst  ?  PartialStruct (aty, fields) :  aty
497+             return  anyrefine  ?  PartialStruct (aty, fields) :  aty
475498        end 
476499    end 
477500    if  isa (typea, PartialOpaque) &&  isa (typeb, PartialOpaque) &&  widenconst (typea) ==  widenconst (typeb)
@@ -658,44 +681,3 @@ function tuplemerge(a::DataType, b::DataType)
658681    end 
659682    return  Tuple{p... }
660683end 
661- 
662- #  compute typeintersect over the extended inference lattice
663- #  where v is in the extended lattice, and t is a Type
664- function  tmeet (@nospecialize (v), @nospecialize (t))
665-     if  isa (v, Const)
666-         if  ! has_free_typevars (t) &&  ! isa (v. val, t)
667-             return  Bottom
668-         end 
669-         return  v
670-     elseif  isa (v, PartialStruct)
671-         has_free_typevars (t) &&  return  v
672-         widev =  widenconst (v)
673-         if  widev <:  t 
674-             return  v
675-         end 
676-         ti =  typeintersect (widev, t)
677-         valid_as_lattice (ti) ||  return  Bottom
678-         @assert  widev <:  Tuple 
679-         new_fields =  Vector {Any} (undef, length (v. fields))
680-         for  i =  1 : length (new_fields)
681-             vfi =  v. fields[i]
682-             if  isvarargtype (vfi)
683-                 new_fields[i] =  vfi
684-             else 
685-                 new_fields[i] =  tmeet (vfi, widenconst (getfield_tfunc (t, Const (i))))
686-                 if  new_fields[i] ===  Bottom
687-                     return  Bottom
688-                 end 
689-             end 
690-         end 
691-         return  tuple_tfunc (new_fields)
692-     elseif  isa (v, Conditional)
693-         if  ! (Bool <:  t )
694-             return  Bottom
695-         end 
696-         return  v
697-     end 
698-     ti =  typeintersect (widenconst (v), t)
699-     valid_as_lattice (ti) ||  return  Bottom
700-     return  ti
701- end 
0 commit comments