@@ -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