@@ -1545,6 +1545,8 @@ class Namer { typer: Typer =>
15451545 case completer : Completer => completer.indexConstructor(constr, constrSym)
15461546 case _ =>
15471547
1548+ // constrSym.info = typeSig(constrSym)
1549+
15481550 tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
15491551 denot.info = savedInfo
15501552 }
@@ -1646,14 +1648,17 @@ class Namer { typer: Typer =>
16461648 * as an attachment on the ClassDef tree.
16471649 */
16481650 def enterParentRefinementSyms (refinements : List [(Name , Type )]) =
1651+ println(s " For class $cls, entering parent refinements: $refinements" )
16491652 val refinedSyms = mutable.ListBuffer [Symbol ]()
16501653 for (name, tp) <- refinements do
16511654 if decls.lookupEntry(name) == null then
16521655 val flags = tp match
16531656 case tp : MethodOrPoly => Method | Synthetic | Deferred | Tracked
16541657 case _ if name.isTermName => Synthetic | Deferred | Tracked
16551658 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" )
16571662 if refinedSyms.nonEmpty then
16581663 typr.println(i " parent refinement symbols: ${refinedSyms.toList}" )
16591664 original.pushAttachment(ParentRefinements , refinedSyms.toList)
@@ -1695,6 +1700,7 @@ class Namer { typer: Typer =>
16951700 end addUsingTraits
16961701
16971702 completeConstructor(denot)
1703+ val constrSym = symbolOfTree(constr)
16981704 denot.info = tempInfo.nn
16991705
17001706 val parentTypes = defn.adjustForTuple(cls, cls.typeParams,
@@ -1928,7 +1934,7 @@ class Namer { typer: Typer =>
19281934 val mt = wrapMethType(effectiveResultType(sym, paramSymss))
19291935 if sym.isPrimaryConstructor then checkCaseClassParamDependencies(mt, sym.owner)
19301936 mt
1931- else if sym.isAllOf( Given | Method ) && Feature .enabled(modularity) then
1937+ else if Feature .enabled(modularity) then
19321938 // set every context bound evidence parameter of a given companion method
19331939 // to be tracked, provided it has a type that has an abstract type member.
19341940 // Add refinements for all tracked parameters to the result type.
@@ -1986,14 +1992,60 @@ class Namer { typer: Typer =>
19861992 cls.srcPos)
19871993 case _ =>
19881994
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
19911996 */
19921997 def needsTracked (sym : Symbol , param : ValDef )(using Context ) =
19931998 ! 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 )
19952010 && sym.info.memberNames(abstractTypeNameFilter).nonEmpty
19962011
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+
19972049 /** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
19982050 * provided it has a type that has an abstract type member. Reset private and local flags
19992051 * so that the parameter becomes a `val`.
0 commit comments