Skip to content

Commit e541683

Browse files
committed
Extract parts of defDefSig (& completeConstructor)
1 parent c09154a commit e541683

File tree

1 file changed

+64
-56
lines changed

1 file changed

+64
-56
lines changed

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,13 +1526,7 @@ class Namer { typer: Typer =>
15261526
index(constr)
15271527
index(rest)(using localCtx)
15281528

1529-
symbolOfTree(constr).info.stripPoly match // Completes constr symbol as a side effect
1530-
case mt: MethodType if cls.is(Case) && mt.isParamDependent =>
1531-
// See issue #8073 for background
1532-
report.error(
1533-
em"""Implementation restriction: case classes cannot have dependencies between parameters""",
1534-
cls.srcPos)
1535-
case _ =>
1529+
checkCaseClassParamDependencies(symbolOfTree(constr).info, cls) // Completes constr symbol as a side effect
15361530

15371531
tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf[TempClassInfo]
15381532
denot.info = savedInfo
@@ -1860,31 +1854,6 @@ class Namer { typer: Typer =>
18601854
// Beware: ddef.name need not match sym.name if sym was freshened!
18611855
val isConstructor = sym.name == nme.CONSTRUCTOR
18621856

1863-
// A map from context-bounded type parameters to associated evidence parameter names
1864-
val witnessNamesOfParam = mutable.Map[TypeDef, List[TermName]]()
1865-
if !ddef.name.is(DefaultGetterName) && !sym.is(Synthetic) then
1866-
for params <- ddef.paramss; case tdef: TypeDef <- params do
1867-
for case WitnessNamesAnnot(ws) <- tdef.mods.annotations do
1868-
witnessNamesOfParam(tdef) = ws
1869-
1870-
/** Is each name in `wnames` defined somewhere in the longest prefix of all `params`
1871-
* that have been typed ahead (i.e. that carry the TypedAhead attachment)?
1872-
*/
1873-
def allParamsSeen(wnames: List[TermName], params: List[MemberDef]) =
1874-
(wnames.toSet[Name] -- params.takeWhile(_.hasAttachment(TypedAhead)).map(_.name)).isEmpty
1875-
1876-
/** Enter and typecheck parameter list.
1877-
* Once all witness parameters for a context bound are seen, create a
1878-
* context bound companion for it.
1879-
*/
1880-
def completeParams(params: List[MemberDef])(using Context): Unit =
1881-
index(params)
1882-
for param <- params do
1883-
typedAheadExpr(param)
1884-
for (tdef, wnames) <- witnessNamesOfParam do
1885-
if wnames.contains(param.name) && allParamsSeen(wnames, params) then
1886-
addContextBoundCompanionFor(symbolOfTree(tdef), wnames, params.map(symbolOfTree))
1887-
18881857
// The following 3 lines replace what was previously just completeParams(tparams).
18891858
// But that can cause bad bounds being computed, as witnessed by
18901859
// tests/pos/paramcycle.scala. The problematic sequence is this:
@@ -1914,33 +1883,10 @@ class Namer { typer: Typer =>
19141883
for tparam <- ddef.leadingTypeParams yield typedAheadExpr(tparam).symbol
19151884
if completedTypeParams.forall(_.isType) then
19161885
completer.setCompletedTypeParams(completedTypeParams.asInstanceOf[List[TypeSymbol]])
1917-
ddef.trailingParamss.foreach(completeParams)
1886+
completeTrailingParamss(ddef, sym)
19181887
val paramSymss = normalizeIfConstructor(ddef.paramss.nestedMap(symbolOfTree), isConstructor)
19191888
sym.setParamss(paramSymss)
19201889

1921-
/** Under x.modularity, we add `tracked` to context bound witnesses
1922-
* that have abstract type members
1923-
*/
1924-
def needsTracked(sym: Symbol, param: ValDef)(using Context) =
1925-
!sym.is(Tracked)
1926-
&& param.hasAttachment(ContextBoundParam)
1927-
&& sym.info.memberNames(abstractTypeNameFilter).nonEmpty
1928-
1929-
/** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
1930-
* provided it has a type that has an abstract type member. Reset private and local flags
1931-
* so that the parameter becomes a `val`.
1932-
*/
1933-
def setTracked(param: ValDef): Unit =
1934-
val sym = symbolOfTree(param)
1935-
sym.maybeOwner.maybeOwner.infoOrCompleter match
1936-
case info: TempClassInfo if needsTracked(sym, param) =>
1937-
typr.println(i"set tracked $param, $sym: ${sym.info} containing ${sym.info.memberNames(abstractTypeNameFilter).toList}")
1938-
for acc <- info.decls.lookupAll(sym.name) if acc.is(ParamAccessor) do
1939-
acc.resetFlag(PrivateLocal)
1940-
acc.setFlag(Tracked)
1941-
sym.setFlag(Tracked)
1942-
case _ =>
1943-
19441890
def wrapMethType(restpe: Type): Type =
19451891
instantiateDependent(restpe, paramSymss)
19461892
methodType(paramSymss, restpe, ddef.mods.is(JavaDefined))
@@ -1966,6 +1912,68 @@ class Namer { typer: Typer =>
19661912
valOrDefDefSig(ddef, sym, paramSymss, wrapMethType)
19671913
end defDefSig
19681914

1915+
def completeTrailingParamss(ddef: DefDef, sym: Symbol)(using Context): Unit =
1916+
// A map from context-bounded type parameters to associated evidence parameter names
1917+
val witnessNamesOfParam = mutable.Map[TypeDef, List[TermName]]()
1918+
if !ddef.name.is(DefaultGetterName) && !sym.is(Synthetic) then
1919+
for params <- ddef.paramss; case tdef: TypeDef <- params do
1920+
for case WitnessNamesAnnot(ws) <- tdef.mods.annotations do
1921+
witnessNamesOfParam(tdef) = ws
1922+
1923+
/** Is each name in `wnames` defined somewhere in the longest prefix of all `params`
1924+
* that have been typed ahead (i.e. that carry the TypedAhead attachment)?
1925+
*/
1926+
def allParamsSeen(wnames: List[TermName], params: List[MemberDef]) =
1927+
(wnames.toSet[Name] -- params.takeWhile(_.hasAttachment(TypedAhead)).map(_.name)).isEmpty
1928+
1929+
/** Enter and typecheck parameter list.
1930+
* Once all witness parameters for a context bound are seen, create a
1931+
* context bound companion for it.
1932+
*/
1933+
def completeParams(params: List[MemberDef])(using Context): Unit =
1934+
index(params)
1935+
for param <- params do
1936+
typedAheadExpr(param)
1937+
for (tdef, wnames) <- witnessNamesOfParam do
1938+
if wnames.contains(param.name) && allParamsSeen(wnames, params) then
1939+
addContextBoundCompanionFor(symbolOfTree(tdef), wnames, params.map(symbolOfTree))
1940+
1941+
ddef.trailingParamss.foreach(completeParams)
1942+
end completeTrailingParamss
1943+
1944+
/** Checks an implementation restriction on case classes. */
1945+
def checkCaseClassParamDependencies(mt: Type, cls: Symbol)(using Context): Unit =
1946+
mt.stripPoly match
1947+
case mt: MethodType if cls.is(Case) && mt.isParamDependent =>
1948+
// See issue #8073 for background
1949+
report.error(
1950+
em"""Implementation restriction: case classes cannot have dependencies between parameters""",
1951+
cls.srcPos)
1952+
case _ =>
1953+
1954+
/** Under x.modularity, we add `tracked` to context bound witnesses
1955+
* that have abstract type members
1956+
*/
1957+
def needsTracked(sym: Symbol, param: ValDef)(using Context) =
1958+
!sym.is(Tracked)
1959+
&& param.hasAttachment(ContextBoundParam)
1960+
&& sym.info.memberNames(abstractTypeNameFilter).nonEmpty
1961+
1962+
/** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
1963+
* provided it has a type that has an abstract type member. Reset private and local flags
1964+
* so that the parameter becomes a `val`.
1965+
*/
1966+
def setTracked(param: ValDef)(using Context): Unit =
1967+
val sym = symbolOfTree(param)
1968+
sym.maybeOwner.maybeOwner.infoOrCompleter match
1969+
case info: TempClassInfo if needsTracked(sym, param) =>
1970+
typr.println(i"set tracked $param, $sym: ${sym.info} containing ${sym.info.memberNames(abstractTypeNameFilter).toList}")
1971+
for acc <- info.decls.lookupAll(sym.name) if acc.is(ParamAccessor) do
1972+
acc.resetFlag(PrivateLocal)
1973+
acc.setFlag(Tracked)
1974+
sym.setFlag(Tracked)
1975+
case _ =>
1976+
19691977
def inferredResultType(
19701978
mdef: ValOrDefDef,
19711979
sym: Symbol,

0 commit comments

Comments
 (0)