@@ -1521,13 +1521,7 @@ class Namer { typer: Typer =>
1521
1521
index(constr)
1522
1522
index(rest)(using localCtx)
1523
1523
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
1531
1525
1532
1526
tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
1533
1527
denot.info = savedInfo
@@ -1855,31 +1849,6 @@ class Namer { typer: Typer =>
1855
1849
// Beware: ddef.name need not match sym.name if sym was freshened!
1856
1850
val isConstructor = sym.name == nme.CONSTRUCTOR
1857
1851
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
-
1883
1852
// The following 3 lines replace what was previously just completeParams(tparams).
1884
1853
// But that can cause bad bounds being computed, as witnessed by
1885
1854
// tests/pos/paramcycle.scala. The problematic sequence is this:
@@ -1909,33 +1878,10 @@ class Namer { typer: Typer =>
1909
1878
for tparam <- ddef.leadingTypeParams yield typedAheadExpr(tparam).symbol
1910
1879
if completedTypeParams.forall(_.isType) then
1911
1880
completer.setCompletedTypeParams(completedTypeParams.asInstanceOf [List [TypeSymbol ]])
1912
- ddef.trailingParamss.foreach(completeParams )
1881
+ completeTrailingParamss(ddef, sym )
1913
1882
val paramSymss = normalizeIfConstructor(ddef.paramss.nestedMap(symbolOfTree), isConstructor)
1914
1883
sym.setParamss(paramSymss)
1915
1884
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
-
1939
1885
def wrapMethType (restpe : Type ): Type =
1940
1886
instantiateDependent(restpe, paramSymss)
1941
1887
methodType(paramSymss, restpe, ddef.mods.is(JavaDefined ))
@@ -1961,6 +1907,68 @@ class Namer { typer: Typer =>
1961
1907
valOrDefDefSig(ddef, sym, paramSymss, wrapMethType)
1962
1908
end defDefSig
1963
1909
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
+
1964
1972
def inferredResultType (
1965
1973
mdef : ValOrDefDef ,
1966
1974
sym : Symbol ,
0 commit comments