@@ -1526,13 +1526,7 @@ class Namer { typer: Typer =>
1526
1526
index(constr)
1527
1527
index(rest)(using localCtx)
1528
1528
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
1536
1530
1537
1531
tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
1538
1532
denot.info = savedInfo
@@ -1860,31 +1854,6 @@ class Namer { typer: Typer =>
1860
1854
// Beware: ddef.name need not match sym.name if sym was freshened!
1861
1855
val isConstructor = sym.name == nme.CONSTRUCTOR
1862
1856
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
-
1888
1857
// The following 3 lines replace what was previously just completeParams(tparams).
1889
1858
// But that can cause bad bounds being computed, as witnessed by
1890
1859
// tests/pos/paramcycle.scala. The problematic sequence is this:
@@ -1914,33 +1883,10 @@ class Namer { typer: Typer =>
1914
1883
for tparam <- ddef.leadingTypeParams yield typedAheadExpr(tparam).symbol
1915
1884
if completedTypeParams.forall(_.isType) then
1916
1885
completer.setCompletedTypeParams(completedTypeParams.asInstanceOf [List [TypeSymbol ]])
1917
- ddef.trailingParamss.foreach(completeParams )
1886
+ completeTrailingParamss(ddef, sym )
1918
1887
val paramSymss = normalizeIfConstructor(ddef.paramss.nestedMap(symbolOfTree), isConstructor)
1919
1888
sym.setParamss(paramSymss)
1920
1889
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
-
1944
1890
def wrapMethType (restpe : Type ): Type =
1945
1891
instantiateDependent(restpe, paramSymss)
1946
1892
methodType(paramSymss, restpe, ddef.mods.is(JavaDefined ))
@@ -1966,6 +1912,68 @@ class Namer { typer: Typer =>
1966
1912
valOrDefDefSig(ddef, sym, paramSymss, wrapMethType)
1967
1913
end defDefSig
1968
1914
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
+
1969
1977
def inferredResultType (
1970
1978
mdef : ValOrDefDef ,
1971
1979
sym : Symbol ,
0 commit comments