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