@@ -2278,8 +2278,11 @@ class Typer extends Namer
2278
2278
2279
2279
completeAnnotations(cdef, cls)
2280
2280
val constr1 = typed(constr).asInstanceOf [DefDef ]
2281
- val parentsWithClass = ensureFirstTreeIsClass(parents.mapconserve(typedParent).filterConserve(! _.isEmpty), cdef.nameSpan)
2282
- val parents1 = ensureConstrCall(cls, parentsWithClass)(using superCtx)
2281
+ val parents0 = parentTrees(
2282
+ cls.classInfo.declaredParents,
2283
+ parents.mapconserve(typedParent).filterConserve(! _.isEmpty),
2284
+ cdef.nameSpan)
2285
+ val parents1 = ensureConstrCall(cls, parents0)(using superCtx)
2283
2286
val firstParentTpe = parents1.head.tpe.dealias
2284
2287
val firstParent = firstParentTpe.typeSymbol
2285
2288
@@ -2348,42 +2351,22 @@ class Typer extends Namer
2348
2351
protected def addAccessorDefs (cls : Symbol , body : List [Tree ])(using Context ): List [Tree ] =
2349
2352
ctx.compilationUnit.inlineAccessors.addAccessorDefs(cls, body)
2350
2353
2351
- /** Ensure that the first type in a list of parent types Ps points to a non-trait class.
2352
- * If that's not already the case, add one. The added class type CT is determined as follows.
2353
- * First, let C be the unique class such that
2354
- * - there is a parent P_i such that P_i derives from C, and
2355
- * - for every class D: If some parent P_j, j <= i derives from D, then C derives from D.
2356
- * Then, let CT be the smallest type which
2357
- * - has C as its class symbol, and
2358
- * - for all parents P_i: If P_i derives from C then P_i <:< CT.
2354
+ /** Augment `ptrees` to have the same class symbols as `parents`. Generate TypeTrees
2355
+ * to fill in any parents for wich no tree exists yet.
2359
2356
*/
2360
- def ensureFirstIsClass (parents : List [Type ], span : Span )(using Context ): List [Type ] = {
2361
- def realClassParent (cls : Symbol ): ClassSymbol =
2362
- if (! cls.isClass) defn.ObjectClass
2363
- else if (! cls.is(Trait )) cls.asClass
2364
- else cls.info.parents match {
2365
- case parentRef :: _ => realClassParent(parentRef.typeSymbol)
2366
- case nil => defn.ObjectClass
2367
- }
2368
- def improve (candidate : ClassSymbol , parent : Type ): ClassSymbol = {
2369
- val pcls = realClassParent(parent.classSymbol)
2370
- if (pcls derivesFrom candidate) pcls else candidate
2371
- }
2372
- parents match {
2373
- case p :: _ if p.classSymbol.isRealClass => parents
2374
- case _ =>
2375
- val pcls = parents.foldLeft(defn.ObjectClass )(improve)
2376
- typr.println(i " ensure first is class $parents%, % --> ${parents map (_ baseType pcls)}%, % " )
2377
- val first = TypeComparer .glb(defn.ObjectType :: parents.map(_.baseType(pcls)))
2378
- checkFeasibleParent(first, ctx.source.atSpan(span), em " in inferred superclass $first" ) :: parents
2379
- }
2380
- }
2381
-
2382
- /** Ensure that first parent tree refers to a real class. */
2383
- def ensureFirstTreeIsClass (parents : List [Tree ], span : Span )(using Context ): List [Tree ] = parents match {
2384
- case p :: ps if p.tpe.classSymbol.isRealClass => parents
2385
- case _ => TypeTree (ensureFirstIsClass(parents.tpes, span).head).withSpan(span.focus) :: parents
2386
- }
2357
+ def parentTrees (parents : List [Type ], ptrees : List [Tree ], span : Span )(using Context ): List [Tree ] = parents match
2358
+ case parent :: parents1 =>
2359
+ val psym = parent.classSymbol
2360
+ def hasSameParent (ptree : Tree ) = ptree.tpe.classSymbol == psym
2361
+ ptrees match
2362
+ case ptree :: ptrees1 if hasSameParent(ptree) =>
2363
+ ptree :: parentTrees(parents1, ptrees1, span)
2364
+ case ptree :: ptrees1 if ptrees1.exists(hasSameParent) =>
2365
+ ptree :: parentTrees(parents, ptrees1, span)
2366
+ case _ =>
2367
+ TypeTree (parent).withSpan(span.focus) :: parentTrees(parents1, ptrees, span)
2368
+ case _ =>
2369
+ ptrees
2387
2370
2388
2371
/** If this is a real class, make sure its first parent is a
2389
2372
* constructor call. Cannot simply use a type. Overridden in ReTyper.
0 commit comments