Skip to content

Commit 0ce9bab

Browse files
committed
Don't add tracked to PrivateLocal witnesses
1 parent f53e113 commit 0ce9bab

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Namer.scala

+27-23
Original file line numberDiff line numberDiff line change
@@ -1791,7 +1791,7 @@ class Namer { typer: Typer =>
17911791
sym.owner.typeParams.foreach(_.ensureCompleted())
17921792
completeTrailingParamss(constr, sym, indexingCtor = true)
17931793
if Feature.enabled(modularity) then
1794-
constr.termParamss.foreach(_.foreach(setTracked))
1794+
constr.termParamss.foreach(_.foreach(setTrackedConstrParam))
17951795

17961796
/** The signature of a module valdef.
17971797
* This will compute the corresponding module class TypeRef immediately
@@ -1935,10 +1935,8 @@ class Namer { typer: Typer =>
19351935
for params <- ddef.termParamss; param <- params do
19361936
val psym = symbolOfTree(param)
19371937
if needsTracked(psym, param, owningSym) then
1938-
for acc <- sym.maybeOwner.infoOrCompleter.decls.lookupAll(psym.name) if acc.is(ParamAccessor) do
1939-
acc.resetFlag(PrivateLocal)
1940-
psym.setFlag(Tracked)
1941-
acc.setFlag(Tracked)
1938+
psym.setFlag(Tracked)
1939+
setParamTrackedWithAccessors(psym, sym.maybeOwner.infoOrCompleter)
19421940

19431941
if Feature.enabled(modularity) then addTrackedIfNeeded(ddef, sym.maybeOwner)
19441942

@@ -1999,8 +1997,15 @@ class Namer { typer: Typer =>
19991997
cls.srcPos)
20001998
case _ =>
20011999

2002-
/** `psym` needs tracked if it is referenced in any of the public signatures of the defining class
2003-
* or when `psym` is a context bound witness with an abstract type member
2000+
private def setParamTrackedWithAccessors(psym: Symbol, ownerTpe: Type)(using Context): Unit =
2001+
for acc <- ownerTpe.decls.lookupAll(psym.name) if acc.is(ParamAccessor) do
2002+
acc.resetFlag(PrivateLocal)
2003+
psym.setFlag(Tracked)
2004+
acc.setFlag(Tracked)
2005+
2006+
/** `psym` needs tracked if it is referenced in any of the public signatures
2007+
* of the defining class or when `psym` is a context bound witness with an
2008+
* abstract type member
20042009
*/
20052010
def needsTracked(psym: Symbol, param: ValDef, owningSym: Symbol)(using Context) =
20062011
lazy val abstractContextBound = isContextBoundWitnessWithAbstractMembers(psym, param, owningSym)
@@ -2014,24 +2019,25 @@ class Namer { typer: Typer =>
20142019
|| isRefInSignatures
20152020
)
20162021

2017-
/** Under x.modularity, we add `tracked` to context bound witnesses
2018-
* that have abstract type members
2022+
/** Under x.modularity, we add `tracked` to context bound witnesses and
2023+
* explicit evidence parameters that have abstract type members
20192024
*/
2020-
def isContextBoundWitnessWithAbstractMembers(psym: Symbol, param: ValDef, owningSym: Symbol)(using Context): Boolean =
2025+
private def isContextBoundWitnessWithAbstractMembers(psym: Symbol, param: ValDef, owningSym: Symbol)(using Context): Boolean =
2026+
val accessorSyms = maybeParamAccessors(owningSym, psym)
20212027
(owningSym.isClass || owningSym.isAllOf(Given | Method))
2022-
&& (param.hasAttachment(ContextBoundParam) || psym.isOneOf(GivenOrImplicit))
2028+
&& (param.hasAttachment(ContextBoundParam) || (psym.isOneOf(GivenOrImplicit) && !accessorSyms.forall(_.isOneOf(PrivateLocal))))
20232029
&& psym.info.memberNames(abstractTypeNameFilter).nonEmpty
20242030

20252031
extension (sym: Symbol)
2026-
def infoWithForceNonInferingCompleter(using Context): Type = sym.infoOrCompleter match
2032+
private def infoWithForceNonInferingCompleter(using Context): Type = sym.infoOrCompleter match
20272033
case tpe: LazyType if tpe.isNonInfering => sym.info
20282034
case tpe if sym.isType => sym.info
20292035
case info => info
20302036

2031-
/** Under x.modularity, we add `tracked` to term parameters whose types are referenced
2032-
* in public signatures of the defining class
2037+
/** Under x.modularity, we add `tracked` to term parameters whose types are
2038+
* referenced in public signatures of the defining class
20332039
*/
2034-
def isReferencedInPublicSignatures(sym: Symbol)(using Context): Boolean =
2040+
private def isReferencedInPublicSignatures(sym: Symbol)(using Context): Boolean =
20352041
val owner = sym.maybeOwner.maybeOwner
20362042
val accessorSyms = maybeParamAccessors(owner, sym)
20372043
def checkOwnerMemberSignatures(owner: Symbol): Boolean =
@@ -2061,20 +2067,18 @@ class Namer { typer: Typer =>
20612067
info.decls.lookupAll(sym.name).filter(d => d.is(ParamAccessor)).toList
20622068
case _ => List(sym)
20632069

2064-
/** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
2065-
* provided it has a type that has an abstract type member. Reset private and local flags
2066-
* so that the parameter becomes a `val`.
2070+
/** Under x.modularity, set every context bound evidence parameter or public
2071+
* using parameter of a class to be tracked, provided it has a type that has
2072+
* an abstract type member. Reset private and local flags so that the
2073+
* parameter becomes a `val`.
20672074
*/
2068-
def setTracked(param: ValDef)(using Context): Unit =
2075+
def setTrackedConstrParam(param: ValDef)(using Context): Unit =
20692076
val sym = symbolOfTree(param)
20702077
sym.maybeOwner.maybeOwner.infoOrCompleter match
20712078
case info: ClassInfo
20722079
if !sym.is(Tracked) && isContextBoundWitnessWithAbstractMembers(sym, param, sym.maybeOwner.maybeOwner) =>
20732080
typr.println(i"set tracked $param, $sym: ${sym.info} containing ${sym.info.memberNames(abstractTypeNameFilter).toList}")
2074-
for acc <- info.decls.lookupAll(sym.name) if acc.is(ParamAccessor) do
2075-
acc.resetFlag(PrivateLocal)
2076-
acc.setFlag(Tracked)
2077-
sym.setFlag(Tracked)
2081+
setParamTrackedWithAccessors(sym, info)
20782082
case _ =>
20792083

20802084
def inferredResultType(

Diff for: tests/neg/infer-tracked-explicit-witness.scala

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.language.experimental.modularity
2+
3+
trait T:
4+
type Self
5+
type X
6+
def foo: Self
7+
8+
class D[C](using wd: C is T)
9+
class E(using we: Int is T)
10+
11+
def Test =
12+
given w: Int is T:
13+
def foo: Int = 42
14+
type X = Long
15+
val d = D(using w)
16+
summon[d.wd.X =:= Long] // error
17+
val e = E(using w)
18+
summon[e.we.X =:= Long] // error

0 commit comments

Comments
 (0)