@@ -1500,8 +1500,13 @@ class Namer { typer: Typer =>
1500
1500
core match
1501
1501
case Select (New (tpt), nme.CONSTRUCTOR ) =>
1502
1502
val targs1 = targs map (typedAheadType(_))
1503
- val ptype = typedAheadType(tpt).tpe appliedTo targs1.tpes
1504
- if (ptype.typeParams.isEmpty) ptype
1503
+ val ptype = typedAheadType(tpt).tpe.appliedTo(targs1.tpes)
1504
+ if ptype.typeParams.isEmpty
1505
+ // && !ptype.dealias.typeSymbol.primaryConstructor.info.finalResultType.isInstanceOf[RefinedType]
1506
+ && ! ptype.dealias.typeSymbol.is(Dependent )
1507
+ || ctx.erasedTypes
1508
+ then
1509
+ ptype
1505
1510
else
1506
1511
if (denot.is(ModuleClass ) && denot.sourceModule.isOneOf(GivenOrImplicit ))
1507
1512
missingType(denot.symbol, " parent " )(using creationContext)
@@ -1539,7 +1544,7 @@ class Namer { typer: Typer =>
1539
1544
if (cls.isRefinementClass) ptype
1540
1545
else {
1541
1546
val pt = checkClassType(ptype, parent.srcPos,
1542
- traitReq = parent ne parents.head, stablePrefixReq = true )
1547
+ traitReq = parent ne parents.head, stablePrefixReq = true , refinementOK = true )
1543
1548
if (pt.derivesFrom(cls)) {
1544
1549
val addendum = parent match {
1545
1550
case Select (qual : Super , _) if Feature .migrateTo3 =>
@@ -1605,14 +1610,52 @@ class Namer { typer: Typer =>
1605
1610
completeConstructor(denot)
1606
1611
denot.info = tempInfo.nn
1607
1612
1608
- val parentTypes = defn.adjustForTuple(cls, cls.typeParams,
1609
- defn.adjustForBoxedUnit(cls,
1610
- addUsingTraits(
1611
- ensureFirstIsClass(cls, parents.map(checkedParentType(_)))
1612
- )
1613
- )
1614
- )
1615
- typr.println(i " completing $denot, parents = $parents%, %, parentTypes = $parentTypes%, % " )
1613
+ /** The refinements coming from all parent class constructor applications */
1614
+ val parentRefinements = mutable.LinkedHashMap [Name , Type ]()
1615
+
1616
+ /** Split refinements off parent type and add them to `parentRefinements` */
1617
+ def separateRefinements (tp : Type ): Type = tp match
1618
+ case RefinedType (tp1, rname, rinfo) =>
1619
+ try separateRefinements(tp1)
1620
+ finally
1621
+ parentRefinements(rname) = parentRefinements.get(rname) match
1622
+ case Some (tp) => tp & rinfo
1623
+ case None => rinfo
1624
+ case tp => tp
1625
+
1626
+ /** Add all parent refinements to the result type of the `info` of
1627
+ * the class constructor. Parent refinements refer to parameter accessors
1628
+ * in the current class. These have to be mapped to the paramRefs of the
1629
+ * constructor info.
1630
+ * @param info The (remaining part) of the constructor info
1631
+ * @param nameToParamRef The map from parameter names to paramRefs of
1632
+ * previously encountered parts of `info`.
1633
+ */
1634
+ def integrateParentRefinements (info : Type , nameToParamRef : Map [Name , Type ]): Type = info match
1635
+ case info : MethodOrPoly =>
1636
+ info.derivedLambdaType(resType =
1637
+ integrateParentRefinements(info.resType,
1638
+ nameToParamRef ++ info.paramNames.zip(info.paramRefs)))
1639
+ case _ =>
1640
+ val mapParams = new TypeMap :
1641
+ def apply (t : Type ) = t match
1642
+ case t : TermRef if t.symbol.is(ParamAccessor ) && t.symbol.owner == cls =>
1643
+ nameToParamRef(t.name)
1644
+ case _ =>
1645
+ mapOver(t)
1646
+ parentRefinements.foldLeft(info): (info, refinement) =>
1647
+ val (rname, rinfo) = refinement
1648
+ RefinedType (info, rname, mapParams(rinfo))
1649
+
1650
+ val parentTypes =
1651
+ defn.adjustForTuple(cls, cls.typeParams,
1652
+ defn.adjustForBoxedUnit(cls,
1653
+ addUsingTraits(
1654
+ ensureFirstIsClass(cls, parents.map(checkedParentType(_)))
1655
+ ))).map(separateRefinements)
1656
+
1657
+ typr.println(i " completing $denot, parents = $parents%, %, stripped parent types = $parentTypes%, % " )
1658
+ typr.println(i " constr type = ${cls.primaryConstructor.infoOrCompleter}, refinements = ${parentRefinements.toList}" )
1616
1659
1617
1660
if (impl.derived.nonEmpty) {
1618
1661
val (derivingClass, derivePos) = original.removeAttachment(desugar.DerivingCompanion ) match {
@@ -1627,6 +1670,10 @@ class Namer { typer: Typer =>
1627
1670
denot.info = tempInfo.nn.finalized(parentTypes)
1628
1671
tempInfo = null // The temporary info can now be garbage-collected
1629
1672
1673
+ if parentRefinements.nonEmpty then
1674
+ val constr = cls.primaryConstructor
1675
+ constr.info = integrateParentRefinements(constr.info, Map ())
1676
+ cls.setFlag(Dependent )
1630
1677
Checking .checkWellFormed(cls)
1631
1678
if (isDerivedValueClass(cls)) cls.setFlag(Final )
1632
1679
cls.info = avoidPrivateLeaks(cls)
0 commit comments