@@ -822,8 +822,7 @@ class Namer { typer: Typer =>
822
822
if (sym.is(Module )) moduleValSig(sym)
823
823
else valOrDefDefSig(original, sym, Nil , identity)(using localContext(sym).setNewScope)
824
824
case original : DefDef =>
825
- val typer1 = ctx.typer.newLikeThis(ctx.nestingLevel + 1 )
826
- nestedTyper(sym) = typer1
825
+ val typer1 = newNestedTyper(sym)
827
826
typer1.defDefSig(original, sym, this )(using localContext(sym).setTyper(typer1))
828
827
case imp : Import =>
829
828
try
@@ -833,6 +832,12 @@ class Namer { typer: Typer =>
833
832
typr.println(s " error while completing ${imp.expr}" )
834
833
throw ex
835
834
835
+ def newNestedTyper (sym : Symbol ) = nestedTyper.getOrElseUpdate(sym, ctx.typer.newLikeThis(ctx.nestingLevel + 1 ))
836
+
837
+ def indexConstructor (constr : DefDef , sym : Symbol ): Unit =
838
+ val typer1 = newNestedTyper(sym)
839
+ typer1.indexConstructor(constr, sym)(using localContext(sym).setTyper(typer1))
840
+
836
841
final override def complete (denot : SymDenotation )(using Context ): Unit = {
837
842
if (Config .showCompletions && ctx.typerState != creationContext.typerState) {
838
843
def levels (c : Context ): Int =
@@ -986,15 +991,16 @@ class Namer { typer: Typer =>
986
991
987
992
/** If completion of the owner of the to be completed symbol has not yet started,
988
993
* complete the owner first and check again. This prevents cyclic references
989
- * where we need to copmplete a type parameter that has an owner that is not
994
+ * where we need to complete a type parameter that has an owner that is not
990
995
* yet completed. Test case is pos/i10967.scala.
991
996
*/
992
997
override def needsCompletion (symd : SymDenotation )(using Context ): Boolean =
993
998
val owner = symd.owner
994
999
! owner.exists
995
1000
|| owner.is(Touched )
996
1001
|| {
997
- owner.ensureCompleted()
1002
+ if owner.isType then
1003
+ owner.ensureCompleted()
998
1004
! symd.isCompleted
999
1005
}
1000
1006
@@ -1519,12 +1525,9 @@ class Namer { typer: Typer =>
1519
1525
index(constr)
1520
1526
index(rest)(using localCtx)
1521
1527
1522
- symbolOfTree(constr).info.stripPoly match // Completes constr symbol as a side effect
1523
- case mt : MethodType if cls.is(Case ) && mt.isParamDependent =>
1524
- // See issue #8073 for background
1525
- report.error(
1526
- em """ Implementation restriction: case classes cannot have dependencies between parameters """ ,
1527
- cls.srcPos)
1528
+ val constrSym = symbolOfTree(constr)
1529
+ constrSym.infoOrCompleter match
1530
+ case completer : Completer => completer.indexConstructor(constr, constrSym)
1528
1531
case _ =>
1529
1532
1530
1533
tempInfo = denot.asClass.classInfo.integrateOpaqueMembers.asInstanceOf [TempClassInfo ]
@@ -1853,31 +1856,6 @@ class Namer { typer: Typer =>
1853
1856
// Beware: ddef.name need not match sym.name if sym was freshened!
1854
1857
val isConstructor = sym.name == nme.CONSTRUCTOR
1855
1858
1856
- // A map from context-bounded type parameters to associated evidence parameter names
1857
- val witnessNamesOfParam = mutable.Map [TypeDef , List [TermName ]]()
1858
- if ! ddef.name.is(DefaultGetterName ) && ! sym.is(Synthetic ) then
1859
- for params <- ddef.paramss; case tdef : TypeDef <- params do
1860
- for case WitnessNamesAnnot (ws) <- tdef.mods.annotations do
1861
- witnessNamesOfParam(tdef) = ws
1862
-
1863
- /** Is each name in `wnames` defined somewhere in the longest prefix of all `params`
1864
- * that have been typed ahead (i.e. that carry the TypedAhead attachment)?
1865
- */
1866
- def allParamsSeen (wnames : List [TermName ], params : List [MemberDef ]) =
1867
- (wnames.toSet[Name ] -- params.takeWhile(_.hasAttachment(TypedAhead )).map(_.name)).isEmpty
1868
-
1869
- /** Enter and typecheck parameter list.
1870
- * Once all witness parameters for a context bound are seen, create a
1871
- * context bound companion for it.
1872
- */
1873
- def completeParams (params : List [MemberDef ])(using Context ): Unit =
1874
- index(params)
1875
- for param <- params do
1876
- typedAheadExpr(param)
1877
- for (tdef, wnames) <- witnessNamesOfParam do
1878
- if wnames.contains(param.name) && allParamsSeen(wnames, params) then
1879
- addContextBoundCompanionFor(symbolOfTree(tdef), wnames, params.map(symbolOfTree))
1880
-
1881
1859
// The following 3 lines replace what was previously just completeParams(tparams).
1882
1860
// But that can cause bad bounds being computed, as witnessed by
1883
1861
// tests/pos/paramcycle.scala. The problematic sequence is this:
@@ -1901,39 +1879,15 @@ class Namer { typer: Typer =>
1901
1879
// 3. Info of CP is computed (to be copied to DP).
1902
1880
// 4. CP is completed.
1903
1881
// 5. Info of CP is copied to DP and DP is completed.
1904
- index(ddef.leadingTypeParams)
1905
- if (isConstructor) sym.owner.typeParams.foreach(_.ensureCompleted())
1882
+ if ! sym.isPrimaryConstructor then index(ddef.leadingTypeParams)
1906
1883
val completedTypeParams =
1907
1884
for tparam <- ddef.leadingTypeParams yield typedAheadExpr(tparam).symbol
1908
1885
if completedTypeParams.forall(_.isType) then
1909
1886
completer.setCompletedTypeParams(completedTypeParams.asInstanceOf [List [TypeSymbol ]])
1910
- ddef.trailingParamss.foreach(completeParams )
1887
+ completeTrailingParamss(ddef, sym )
1911
1888
val paramSymss = normalizeIfConstructor(ddef.paramss.nestedMap(symbolOfTree), isConstructor)
1912
1889
sym.setParamss(paramSymss)
1913
1890
1914
- /** Under x.modularity, we add `tracked` to context bound witnesses
1915
- * that have abstract type members
1916
- */
1917
- def needsTracked (sym : Symbol , param : ValDef )(using Context ) =
1918
- ! sym.is(Tracked )
1919
- && param.hasAttachment(ContextBoundParam )
1920
- && sym.info.memberNames(abstractTypeNameFilter).nonEmpty
1921
-
1922
- /** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
1923
- * provided it has a type that has an abstract type member. Reset private and local flags
1924
- * so that the parameter becomes a `val`.
1925
- */
1926
- def setTracked (param : ValDef ): Unit =
1927
- val sym = symbolOfTree(param)
1928
- sym.maybeOwner.maybeOwner.infoOrCompleter match
1929
- case info : TempClassInfo if needsTracked(sym, param) =>
1930
- typr.println(i " set tracked $param, $sym: ${sym.info} containing ${sym.info.memberNames(abstractTypeNameFilter).toList}" )
1931
- for acc <- info.decls.lookupAll(sym.name) if acc.is(ParamAccessor ) do
1932
- acc.resetFlag(PrivateLocal )
1933
- acc.setFlag(Tracked )
1934
- sym.setFlag(Tracked )
1935
- case _ =>
1936
-
1937
1891
def wrapMethType (restpe : Type ): Type =
1938
1892
instantiateDependent(restpe, paramSymss)
1939
1893
methodType(paramSymss, restpe, ddef.mods.is(JavaDefined ))
@@ -1942,11 +1896,18 @@ class Namer { typer: Typer =>
1942
1896
wrapMethType(addParamRefinements(restpe, paramSymss))
1943
1897
1944
1898
if isConstructor then
1945
- if sym.isPrimaryConstructor && Feature .enabled(modularity) then
1946
- ddef.termParamss.foreach(_.foreach(setTracked))
1947
1899
// set result type tree to unit, but take the current class as result type of the symbol
1948
1900
typedAheadType(ddef.tpt, defn.UnitType )
1949
- wrapMethType(effectiveResultType(sym, paramSymss))
1901
+ val mt = wrapMethType(effectiveResultType(sym, paramSymss))
1902
+ if sym.isPrimaryConstructor then
1903
+ mt.stripPoly match
1904
+ case mt : MethodType if sym.owner.is(Case ) && mt.isParamDependent =>
1905
+ // See issue #8073 for background
1906
+ report.error(
1907
+ em """ Implementation restriction: case classes cannot have dependencies between parameters """ ,
1908
+ sym.owner.srcPos)
1909
+ case _ =>
1910
+ mt
1950
1911
else if sym.isAllOf(Given | Method ) && Feature .enabled(modularity) then
1951
1912
// set every context bound evidence parameter of a given companion method
1952
1913
// to be tracked, provided it has a type that has an abstract type member.
@@ -1959,6 +1920,74 @@ class Namer { typer: Typer =>
1959
1920
valOrDefDefSig(ddef, sym, paramSymss, wrapMethType)
1960
1921
end defDefSig
1961
1922
1923
+ def indexConstructor (constr : DefDef , sym : Symbol )(using Context ): Unit =
1924
+ index(constr.leadingTypeParams)
1925
+ sym.owner.typeParams.foreach(_.ensureCompleted())
1926
+ completeTrailingParamss(constr, sym, indexingCtor = true )
1927
+ if Feature .enabled(modularity) then
1928
+ constr.termParamss.foreach(_.foreach(setTracked))
1929
+
1930
+ def completeTrailingParamss (ddef : DefDef , sym : Symbol , indexingCtor : Boolean = false )(using Context ): Unit =
1931
+ // A map from context-bounded type parameters to associated evidence parameter names
1932
+ val witnessNamesOfParam = mutable.Map [TypeDef , List [TermName ]]()
1933
+ if ! ddef.name.is(DefaultGetterName ) && ! sym.is(Synthetic ) && (indexingCtor || ! sym.isPrimaryConstructor) then
1934
+ for params <- ddef.paramss; case tdef : TypeDef <- params do
1935
+ for case WitnessNamesAnnot (ws) <- tdef.mods.annotations do
1936
+ witnessNamesOfParam(tdef) = ws
1937
+
1938
+ /** Is each name in `wnames` defined somewhere in the previous parameters? */
1939
+ def allParamsSeen (wnames : List [TermName ], prevParams1 : List [Name ]) =
1940
+ (wnames.toSet[Name ] -- prevParams1).isEmpty
1941
+
1942
+ /** Enter and typecheck parameter list.
1943
+ * Once all witness parameters for a context bound are seen, create a
1944
+ * context bound companion for it.
1945
+ */
1946
+ def completeParams (params : List [MemberDef ])(using Context ): Unit =
1947
+ if indexingCtor || ! sym.isPrimaryConstructor then index(params)
1948
+ val paramSyms = params.map(symbolOfTree)
1949
+
1950
+ def loop (nextParams : List [MemberDef ], prevParams : List [Name ]): Unit = nextParams match
1951
+ case param :: nextParams1 =>
1952
+ if ! indexingCtor then
1953
+ typedAheadExpr(param)
1954
+
1955
+ val prevParams1 = param.name :: prevParams
1956
+ for (tdef, wnames) <- witnessNamesOfParam do
1957
+ if wnames.contains(param.name) && allParamsSeen(wnames, prevParams1) then
1958
+ addContextBoundCompanionFor(symbolOfTree(tdef), wnames, paramSyms)
1959
+
1960
+ loop(nextParams1, prevParams1)
1961
+ case _ =>
1962
+ loop(params, Nil )
1963
+ end completeParams
1964
+
1965
+ ddef.trailingParamss.foreach(completeParams)
1966
+ end completeTrailingParamss
1967
+
1968
+ /** Under x.modularity, we add `tracked` to context bound witnesses
1969
+ * that have abstract type members
1970
+ */
1971
+ def needsTracked (sym : Symbol , param : ValDef )(using Context ) =
1972
+ ! sym.is(Tracked )
1973
+ && param.hasAttachment(ContextBoundParam )
1974
+ && sym.info.memberNames(abstractTypeNameFilter).nonEmpty
1975
+
1976
+ /** Under x.modularity, set every context bound evidence parameter of a class to be tracked,
1977
+ * provided it has a type that has an abstract type member. Reset private and local flags
1978
+ * so that the parameter becomes a `val`.
1979
+ */
1980
+ def setTracked (param : ValDef )(using Context ): Unit =
1981
+ val sym = symbolOfTree(param)
1982
+ sym.maybeOwner.maybeOwner.infoOrCompleter match
1983
+ case info : ClassInfo if needsTracked(sym, param) =>
1984
+ typr.println(i " set tracked $param, $sym: ${sym.info} containing ${sym.info.memberNames(abstractTypeNameFilter).toList}" )
1985
+ for acc <- info.decls.lookupAll(sym.name) if acc.is(ParamAccessor ) do
1986
+ acc.resetFlag(PrivateLocal )
1987
+ acc.setFlag(Tracked )
1988
+ sym.setFlag(Tracked )
1989
+ case _ =>
1990
+
1962
1991
def inferredResultType (
1963
1992
mdef : ValOrDefDef ,
1964
1993
sym : Symbol ,
0 commit comments