@@ -2426,65 +2426,32 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
24262426    val  TypeDef (name, impl @  Template (constr, _, self, _)) =  cdef : @ unchecked
24272427    val  parents  =  impl.parents
24282428    val  superCtx  =  ctx.superCallContext
2429- 
2430-     /**  If `ref` is an implicitly parameterized trait, pass an implicit argument list. 
2431-      *  Otherwise, if `ref` is a parameterized trait, error. 
2432-      *  Note: Traits and classes have sometimes a synthesized empty parameter list () 
2433-      *  in front or after the implicit parameter(s). See NamerOps.normalizeIfConstructor. 
2434-      *  We synthesize a () argument at the correct place in this case. 
2435-      *  @param  ref    The tree referring to the (parent) trait 
2436-      *  @param  psym   Its type symbol 
2437-      */  
2438-     def  maybeCall (ref : Tree , psym : Symbol ):  Tree  = 
2439-       def  appliedRef  = 
2440-         typedExpr(untpd.New (untpd.TypedSplice (ref)(using  superCtx), Nil ))(using  superCtx)
2441-       def  dropContextual (tp : Type ):  Type  =  tp.stripPoly match 
2442-         case  mt : MethodType  if  mt.isContextualMethod =>  dropContextual(mt.resType)
2443-         case  _ =>  tp
2444-       psym.primaryConstructor.info.stripPoly match 
2445-         case  cinfo @  MethodType (Nil )
2446-         if  cinfo.resultType.isImplicitMethod &&  ! cinfo.resultType.isContextualMethod => 
2447-           appliedRef
2448-         case  cinfo => 
2449-           val  cinfo1  =  dropContextual(cinfo)
2450-           cinfo1 match 
2451-             case  cinfo1 @  MethodType (Nil ) if  ! cinfo1.resultType.isInstanceOf [MethodType ] => 
2452-               if  cinfo1 ne cinfo then  appliedRef else  ref
2453-             case  cinfo1 : MethodType  if  ! ctx.erasedTypes => 
2454-               report.error(ParameterizedTypeLacksArguments (psym), ref.srcPos)
2455-               ref
2456-             case  _ => 
2457-               ref
2458- 
24592429    val  seenParents  =  mutable.Set [Symbol ]()
24602430
2461-     def  typedParent (tree : untpd.Tree ):  Tree  =  {
2462-       def  isTreeType (t : untpd.Tree ):  Boolean  =  t match  {
2463-         case  _ : untpd.Apply  =>  false 
2464-         case  _ =>  true 
2465-       }
2466-       var  result  = 
2467-         if  isTreeType(tree) then  typedType(tree)(using  superCtx)
2468-         else  typedExpr(tree)(using  superCtx)
2469-       val  psym  =  result.tpe.dealias.typeSymbol
2470-       if  (seenParents.contains(psym) &&  ! cls.isRefinementClass) {
2471-         //  Desugaring can adds parents to classes, but we don't want to emit an
2431+     def  typedParent (tree : untpd.Tree ):  Tree  = 
2432+       val  parent  =  tree match 
2433+         case  _ : untpd.Apply  =>  typedExpr(tree)(using  superCtx)
2434+         case  _ =>  typedType(tree)(using  superCtx)
2435+       val  psym  =  parent.tpe.dealias.typeSymbol
2436+       if  seenParents.contains(psym) &&  ! cls.isRefinementClass then 
2437+         //  Desugaring can add parents to classes, but we don't want to emit an
24722438        //  error if the same parent was explicitly added in user code.
2473-         if  ( ! tree.span.isSourceDerived) 
2439+         if  ! tree.span.isSourceDerived  then 
24742440          return  EmptyTree 
2475- 
2476-         if  (! ctx.isAfterTyper) report.error(i " $psym is extended twice " , tree.srcPos)
2477-       }
2478-       else  seenParents +=  psym
2479-       if  (tree.isType) {
2480-         checkSimpleKinded(result) //  Not needed for constructor calls, as type arguments will be inferred.
2481-         if  (psym.is(Trait ) &&  ! cls.is(Trait ) &&  ! cls.superClass.isSubClass(psym))
2482-           result =  maybeCall(result, psym)
2483-       }
2484-       else  checkParentCall(result, cls)
2485-       if  (cls is Case ) checkCaseInheritance(psym, cls, tree.srcPos)
2441+         if  ! ctx.isAfterTyper then  report.error(i " $psym is extended twice " , tree.srcPos)
2442+       else 
2443+         seenParents +=  psym
2444+       val  result  =  ensureConstrCall(cls, parent, psym)(using  superCtx)
2445+       if  parent.isType then 
2446+         if  ! result.symbol.info.takesImplicitParams then 
2447+           checkSimpleKinded(parent)
2448+             //  allow missing type parameters if there are implicit arguments to pass
2449+             //  since we can infer type arguments from them
2450+       else 
2451+         checkParentCall(result, cls)
2452+       if  cls is Case  then 
2453+         checkCaseInheritance(psym, cls, tree.srcPos)
24862454      result
2487-     }
24882455
24892456    def  ensureCorrectSuperClass ():  Unit  = 
24902457      val  parents0  =  cls.classInfo.declaredParents
@@ -2499,23 +2466,27 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
24992466    /**  Augment `ptrees` to have the same class symbols as `parents`. Generate TypeTrees 
25002467     *  or New trees to fill in any parents for which no tree exists yet. 
25012468     */  
2502-     def  parentTrees (parents : List [Type ], ptrees : List [Tree ]):  List [Tree ] =  parents match 
2503-       case  parent ::  parents1 => 
2504-         val  psym  =  parent.classSymbol
2505-         def  hasSameParent (ptree : Tree ) =  ptree.tpe.classSymbol ==  psym
2506-         ptrees match 
2507-           case  ptree ::  ptrees1 if  hasSameParent(ptree) => 
2508-             ptree ::  parentTrees(parents1, ptrees1)
2509-           case  ptree ::  ptrees1 if  ptrees1.exists(hasSameParent) => 
2510-             ptree ::  parentTrees(parents, ptrees1)
2511-           case  _ => 
2512-             var  added :  Tree  =  TypeTree (parent).withSpan(cdef.nameSpan.focus)
2513-             if  psym.is(Trait ) &&  psym.primaryConstructor.info.takesImplicitParams then 
2514-               //  classes get a constructor separately using a different context
2515-               added =  ensureConstrCall(cls, added)(using  superCtx)
2516-             added ::  parentTrees(parents1, ptrees)
2517-       case  _ => 
2518-         ptrees
2469+     def  parentTrees (parents : List [Type ], ptrees : List [Tree ]):  List [Tree ] = 
2470+       if  ptrees.exists(_.tpe.isError) then  ptrees
2471+       else  parents match 
2472+         case  parent ::  parents1 => 
2473+           val  psym  =  parent.classSymbol
2474+           def  hasSameParent (ptree : Tree ) = 
2475+             psym ==  (
2476+               if  ptree.symbol.isConstructor then  ptree.symbol.owner
2477+               else  ptree.tpe.classSymbol
2478+             )
2479+           ptrees match 
2480+             case  ptree ::  ptrees1 if  hasSameParent(ptree) => 
2481+               ptree ::  parentTrees(parents1, ptrees1)
2482+             case  ptree ::  ptrees1 if  ptrees1.exists(hasSameParent) => 
2483+               ptree ::  parentTrees(parents, ptrees1)
2484+             case  _ => 
2485+               val  added :  Tree  =  ensureConstrCall(
2486+                 cls, TypeTree (parent).withSpan(cdef.nameSpan.focus), psym)(using  superCtx)
2487+               added ::  parentTrees(parents1, ptrees)
2488+         case  _ => 
2489+           ptrees
25192490
25202491    /**  Checks if one of the decls is a type with the same name as class type member in selfType */  
25212492    def  classExistsOnSelf (decls : Scope , self : tpd.ValDef ):  Boolean  =  {
@@ -2538,10 +2509,9 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
25382509    ensureCorrectSuperClass()
25392510    completeAnnotations(cdef, cls)
25402511    val  constr1  =  typed(constr).asInstanceOf [DefDef ]
2541-     val  parents0  =  parentTrees(
2512+     val  parents1  =  parentTrees(
25422513        cls.classInfo.declaredParents,
25432514        parents.mapconserve(typedParent).filterConserve(! _.isEmpty))
2544-     val  parents1  =  ensureConstrCall(cls, parents0)(using  superCtx)
25452515    val  firstParentTpe  =  parents1.head.tpe.dealias
25462516    val  firstParent  =  firstParentTpe.typeSymbol
25472517
@@ -2610,23 +2580,19 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
26102580  protected  def  addAccessorDefs (cls : Symbol , body : List [Tree ])(using  Context ):  List [Tree ] = 
26112581    PrepareInlineable .addAccessorDefs(cls, body)
26122582
2613-   /**  If this is a real class, make sure its first parent is a 
2614-    *  constructor call. Cannot simply use a type. Overridden in ReTyper. 
2583+   /**  Turn a parent type into a constructor call where needed. This is the case where 
2584+    *   - we are in a Scala class or module (not a Java class, nor a trait), and 
2585+    *     - the parent symbol is a non-trait class, or 
2586+    *     - the parent symbol is a trait that takes at least one (explicit or implicit) parameter 
2587+    *       and the parent symbol is directly extended by the current class (i.e. not 
2588+    *       extended by the superclass). 
26152589   */  
2616-   def  ensureConstrCall (cls : ClassSymbol , parents : List [Tree ])(using  Context ):  List [Tree ] =  parents match 
2617-     case  parents @  (first ::  others) => 
2618-       parents.derivedCons(ensureConstrCall(cls, first), others)
2619-     case  parents => 
2620-       parents
2621- 
2622-  /**  If this is a real class, make sure its first parent is a 
2623-    *  constructor call. Cannot simply use a type. Overridden in ReTyper. 
2624-    */  
2625-   def  ensureConstrCall (cls : ClassSymbol , parent : Tree )(using  Context ):  Tree  = 
2626-     if  (parent.isType &&  ! cls.is(Trait ) &&  ! cls.is(JavaDefined ))
2627-       typed(untpd.New (untpd.TypedSplice (parent), Nil ))
2628-     else 
2629-       parent
2590+   def  ensureConstrCall (cls : ClassSymbol , parent : Tree , psym : Symbol )(using  Context ):  Tree  = 
2591+     if  parent.isType &&  ! cls.is(Trait ) &&  ! cls.is(JavaDefined ) &&  psym.isClass
2592+         &&  (! psym.is(Trait )
2593+             ||  psym.primaryConstructor.info.takesParams &&  ! cls.superClass.isSubClass(psym))
2594+     then  typed(untpd.New (untpd.TypedSplice (parent), Nil ))
2595+     else  parent
26302596
26312597  def  localDummy (cls : ClassSymbol , impl : untpd.Template )(using  Context ):  Symbol  = 
26322598    newLocalDummy(cls, impl.span)
0 commit comments