@@ -1545,6 +1545,8 @@ class Namer { typer: Typer =>
1545
1545
case completer : Completer => completer.indexConstructor(constr, constrSym)
1546
1546
case _ =>
1547
1547
1548
+ // constrSym.info = typeSig(constrSym)
1549
+
1548
1550
tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
1549
1551
denot.info = savedInfo
1550
1552
}
@@ -1646,14 +1648,17 @@ class Namer { typer: Typer =>
1646
1648
* as an attachment on the ClassDef tree.
1647
1649
*/
1648
1650
def enterParentRefinementSyms (refinements : List [(Name , Type )]) =
1651
+ println(s " For class $cls, entering parent refinements: $refinements" )
1649
1652
val refinedSyms = mutable.ListBuffer [Symbol ]()
1650
1653
for (name, tp) <- refinements do
1651
1654
if decls.lookupEntry(name) == null then
1652
1655
val flags = tp match
1653
1656
case tp : MethodOrPoly => Method | Synthetic | Deferred | Tracked
1654
1657
case _ if name.isTermName => Synthetic | Deferred | Tracked
1655
1658
case _ => Synthetic | Deferred
1656
- refinedSyms += newSymbol(cls, name, flags, tp, coord = original.rhs.span.startPos).entered
1659
+ val s = newSymbol(cls, name, flags, tp, coord = original.rhs.span.startPos).entered
1660
+ refinedSyms += s
1661
+ println(s " entered $s" )
1657
1662
if refinedSyms.nonEmpty then
1658
1663
typr.println(i " parent refinement symbols: ${refinedSyms.toList}" )
1659
1664
original.pushAttachment(ParentRefinements , refinedSyms.toList)
@@ -1695,6 +1700,7 @@ class Namer { typer: Typer =>
1695
1700
end addUsingTraits
1696
1701
1697
1702
completeConstructor(denot)
1703
+ val constrSym = symbolOfTree(constr)
1698
1704
denot.info = tempInfo.nn
1699
1705
1700
1706
val parentTypes = defn.adjustForTuple(cls, cls.typeParams,
@@ -1928,7 +1934,7 @@ class Namer { typer: Typer =>
1928
1934
val mt = wrapMethType(effectiveResultType(sym, paramSymss))
1929
1935
if sym.isPrimaryConstructor then checkCaseClassParamDependencies(mt, sym.owner)
1930
1936
mt
1931
- else if sym.isAllOf( Given | Method ) && Feature .enabled(modularity) then
1937
+ else if Feature .enabled(modularity) then
1932
1938
// set every context bound evidence parameter of a given companion method
1933
1939
// to be tracked, provided it has a type that has an abstract type member.
1934
1940
// Add refinements for all tracked parameters to the result type.
@@ -1986,14 +1992,60 @@ class Namer { typer: Typer =>
1986
1992
cls.srcPos)
1987
1993
case _ =>
1988
1994
1989
- /** Under x.modularity, we add `tracked` to context bound witnesses
1990
- * that have abstract type members
1995
+ /** Try to infer if the parameter needs a `tracked` modifier
1991
1996
*/
1992
1997
def needsTracked (sym : Symbol , param : ValDef )(using Context ) =
1993
1998
! sym.is(Tracked )
1994
- && param.hasAttachment(ContextBoundParam )
1999
+ && (
2000
+ isContextBoundWitnessWithAbstractMembers(sym, param)
2001
+ || isReferencedInPublicSignatures(sym)
2002
+ // || isPassedToTrackedParentParameter(sym, param)
2003
+ )
2004
+
2005
+ /** Under x.modularity, we add `tracked` to context bound witnesses
2006
+ * that have abstract type members
2007
+ */
2008
+ def isContextBoundWitnessWithAbstractMembers (sym : Symbol , param : ValDef )(using Context ): Boolean =
2009
+ param.hasAttachment(ContextBoundParam )
1995
2010
&& sym.info.memberNames(abstractTypeNameFilter).nonEmpty
1996
2011
2012
+ /** Under x.modularity, we add `tracked` to term parameters whose types are referenced
2013
+ * in public signatures of the defining class
2014
+ */
2015
+ def isReferencedInPublicSignatures (sym : Symbol )(using Context ): Boolean =
2016
+ val owner = sym.maybeOwner.maybeOwner
2017
+ val accessorSyms = maybeParamAccessors(owner, sym)
2018
+ def checkOwnerMemberSignatures (owner : Symbol ): Boolean =
2019
+ owner.infoOrCompleter match
2020
+ case info : ClassInfo =>
2021
+ info.decls.filter(d => ! d.isConstructor).exists(d => tpeContainsSymbolRef(d.info, accessorSyms))
2022
+ case _ => false
2023
+ checkOwnerMemberSignatures(owner)
2024
+
2025
+ def isPassedToTrackedParentParameter (sym : Symbol , param : ValDef )(using Context ): Boolean =
2026
+ val owner = sym.maybeOwner.maybeOwner
2027
+ val accessorSyms = maybeParamAccessors(owner, sym)
2028
+ owner.infoOrCompleter match
2029
+ // case info: ClassInfo =>
2030
+ // info.parents.foreach(println)
2031
+ // info.parents.exists(tpeContainsSymbolRef(_, accessorSyms))
2032
+ case _ => false
2033
+
2034
+ private def namedTypeWithPrefixContainsSymbolRef (tpe : Type , syms : List [Symbol ])(using Context ): Boolean = tpe match
2035
+ case tpe : NamedType => tpe.prefix.exists && tpeContainsSymbolRef(tpe.prefix, syms)
2036
+ case _ => false
2037
+
2038
+ private def tpeContainsSymbolRef (tpe : Type , syms : List [Symbol ])(using Context ): Boolean =
2039
+ tpe.termSymbol.exists && syms.contains(tpe.termSymbol)
2040
+ || tpe.argInfos.exists(tpeContainsSymbolRef(_, syms))
2041
+ || namedTypeWithPrefixContainsSymbolRef(tpe, syms)
2042
+
2043
+ private def maybeParamAccessors (owner : Symbol , sym : Symbol )(using Context ): List [Symbol ] =
2044
+ owner.infoOrCompleter match
2045
+ case info : ClassInfo =>
2046
+ info.decls.lookupAll(sym.name).filter(d => d.is(ParamAccessor )).toList
2047
+ case _ => List .empty
2048
+
1997
2049
/** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
1998
2050
* provided it has a type that has an abstract type member. Reset private and local flags
1999
2051
* so that the parameter becomes a `val`.
0 commit comments