Skip to content

Commit 27092c9

Browse files
dwijnandWojciechMazur
authored andcommitted
Extract parts of defDefSig (& completeConstructor)
[Cherry-picked e541683]
1 parent 18c6484 commit 27092c9

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
@@ -1521,13 +1521,7 @@ class Namer { typer: Typer =>
15211521
index(constr)
15221522
index(rest)(using localCtx)
15231523

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

15321526
tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf[TempClassInfo]
15331527
denot.info = savedInfo
@@ -1855,31 +1849,6 @@ class Namer { typer: Typer =>
18551849
// Beware: ddef.name need not match sym.name if sym was freshened!
18561850
val isConstructor = sym.name == nme.CONSTRUCTOR
18571851

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

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

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

0 commit comments

Comments
 (0)