@@ -85,18 +85,43 @@ trait TypeOps { this: Context =>
8585 }
8686 }
8787
88+ private def enterArgBinding (formal : Symbol , info : Type , cls : ClassSymbol , decls : Scope ) = {
89+ val typeArgFlag = if (formal is Local ) TypeArgument else EmptyFlags
90+ val sym = ctx.newSymbol(cls, formal.name, formal.flags & RetainedTypeArgFlags | typeArgFlag, info)
91+ cls.enter(sym, decls)
92+ }
93+
94+ /** If we have member definitions
95+ *
96+ * type argSym v= from
97+ * type from v= to
98+ *
99+ * where the variances of both alias are the same, then enter a new definition
100+ *
101+ * type argSym v= to
102+ *
103+ * unless a definition for `argSym` already exists in the current scope.
104+ */
105+ def forwardRef (argSym : Symbol , from : Symbol , to : TypeBounds , cls : ClassSymbol , decls : Scope ) =
106+ argSym.info match {
107+ case info @ TypeBounds (lo2 @ TypeRef (ThisType (_), name), hi2) =>
108+ if (name == from.name &&
109+ (lo2 eq hi2) &&
110+ info.variance == to.variance &&
111+ ! decls.lookup(argSym.name).exists) {
112+ // println(s"short-circuit ${argSym.name} was: ${argSym.info}, now: $to")
113+ enterArgBinding(argSym, to, cls, decls)
114+ }
115+ case _ =>
116+ }
117+
118+
88119 /** Normalize a list of parent types of class `cls` that may contain refinements
89120 * to a list of typerefs referring to classes, by converting all refinements to member
90121 * definitions in scope `decls`. Can add members to `decls` as a side-effect.
91122 */
92123 def normalizeToClassRefs (parents : List [Type ], cls : ClassSymbol , decls : Scope ): List [TypeRef ] = {
93124
94- def enterArgBinding (formal : Symbol , info : Type ) = {
95- val typeArgFlag = if (formal is Local ) TypeArgument else EmptyFlags
96- val sym = ctx.newSymbol(cls, formal.name, formal.flags & RetainedTypeArgFlags | typeArgFlag, info)
97- cls.enter(sym, decls)
98- }
99-
100125 /** If we just entered the type argument binding
101126 *
102127 * type From = To
@@ -117,19 +142,8 @@ trait TypeOps { this: Context =>
117142 case to @ TypeBounds (lo1, hi1) if lo1 eq hi1 =>
118143 for (pref <- prefs)
119144 for (argSym <- pref.decls)
120- if (argSym is TypeArgument ) {
121- argSym.info match {
122- case info @ TypeBounds (lo2 @ TypeRef (ThisType (_), name), hi2) =>
123- if (name == from.name &&
124- (lo2 eq hi2) &&
125- info.variance == to.variance &&
126- ! decls.lookup(argSym.name).exists) {
127- // println(s"short-circuit ${argSym.name} was: ${argSym.info}, now: $to")
128- enterArgBinding(argSym, to)
129- }
130- case _ =>
131- }
132- }
145+ if (argSym is TypeArgument )
146+ forwardRef(argSym, from, to, cls, decls)
133147 case _ =>
134148 }
135149
@@ -155,7 +169,7 @@ trait TypeOps { this: Context =>
155169 refinements foreachBinding { (name, refinedInfo) =>
156170 assert(decls.lookup(name) == NoSymbol , // DEBUG
157171 s " redefinition of ${decls.lookup(name).debugString} in ${cls.showLocated}" )
158- enterArgBinding(formals(name), refinedInfo)
172+ enterArgBinding(formals(name), refinedInfo, cls, decls )
159173 }
160174 // These two loops cannot be fused because second loop assumes that
161175 // all arguments have been entered in `decls`.
0 commit comments