Skip to content

Commit 79fae19

Browse files
authored
Merge pull request #12980 from dotty-staging/fix-12953
Let annotations on parameters see preceding type parameters
2 parents f34a3bb + 278adf1 commit 79fae19

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

compiler/src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ class Namer { typer: Typer =>
700700
case original: DefDef =>
701701
val typer1 = ctx.typer.newLikeThis
702702
nestedTyper(sym) = typer1
703-
typer1.defDefSig(original, sym)(using localContext(sym).setTyper(typer1))
703+
typer1.defDefSig(original, sym, this)(using localContext(sym).setTyper(typer1))
704704
case imp: Import =>
705705
try
706706
val expr1 = typedImportQualifier(imp, typedAheadExpr(_, _)(using ctx.withOwner(sym)))
@@ -733,6 +733,15 @@ class Namer { typer: Typer =>
733733
completer.complete(denot)
734734
}
735735

736+
private var completedTypeParamSyms: List[TypeSymbol] = null
737+
738+
def setCompletedTypeParams(tparams: List[TypeSymbol]) =
739+
completedTypeParamSyms = tparams
740+
741+
override def completerTypeParams(sym: Symbol)(using Context): List[TypeSymbol] =
742+
if completedTypeParamSyms != null then completedTypeParamSyms
743+
else Nil
744+
736745
protected def addAnnotations(sym: Symbol): Unit = original match {
737746
case original: untpd.MemberDef =>
738747
lazy val annotCtx = annotContext(original, sym)
@@ -1639,7 +1648,7 @@ class Namer { typer: Typer =>
16391648
}
16401649

16411650
/** The type signature of a DefDef with given symbol */
1642-
def defDefSig(ddef: DefDef, sym: Symbol)(using Context): Type = {
1651+
def defDefSig(ddef: DefDef, sym: Symbol, completer: Namer#Completer)(using Context): Type = {
16431652
// Beware: ddef.name need not match sym.name if sym was freshened!
16441653
val isConstructor = sym.name == nme.CONSTRUCTOR
16451654

@@ -1668,8 +1677,10 @@ class Namer { typer: Typer =>
16681677
// 5. Info of CP is copied to DP and DP is completed.
16691678
index(ddef.leadingTypeParams)
16701679
if (isConstructor) sym.owner.typeParams.foreach(_.ensureCompleted())
1671-
for (tparam <- ddef.leadingTypeParams) typedAheadExpr(tparam)
1672-
1680+
val completedTypeParams =
1681+
for tparam <- ddef.leadingTypeParams yield typedAheadExpr(tparam).symbol
1682+
if completedTypeParams.forall(_.isType) then
1683+
completer.setCompletedTypeParams(completedTypeParams.asInstanceOf[List[TypeSymbol]])
16731684
ddef.trailingParamss.foreach(completeParams)
16741685
val paramSymss = normalizeIfConstructor(ddef.paramss.nestedMap(symbolOfTree), isConstructor)
16751686
sym.setParamss(paramSymss)

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2081,10 +2081,21 @@ class Typer extends Namer
20812081
def annotContext(mdef: untpd.Tree, sym: Symbol)(using Context): Context = {
20822082
def isInner(owner: Symbol) = owner == sym || sym.is(Param) && owner == sym.owner
20832083
val outer = ctx.outersIterator.dropWhile(c => isInner(c.owner)).next()
2084-
outer.property(ExprOwner) match {
2084+
var adjusted = outer.property(ExprOwner) match {
20852085
case Some(exprOwner) if outer.owner.isClass => outer.exprContext(mdef, exprOwner)
20862086
case _ => outer
20872087
}
2088+
sym.owner.infoOrCompleter match
2089+
case completer: Namer#Completer if sym.is(Param) =>
2090+
val tparams = completer.completerTypeParams(sym)
2091+
if tparams.nonEmpty then
2092+
// Create a new local context with a dummy owner and a scope containing the
2093+
// type parameters of the enclosing method or class. Thus annotations can see
2094+
// these type parameters. See i12953.scala for a test case.
2095+
val dummyOwner = newLocalDummy(sym.owner)
2096+
adjusted = adjusted.fresh.setOwner(dummyOwner).setScope(newScopeWith(tparams*))
2097+
case _ =>
2098+
adjusted
20882099
}
20892100

20902101
def completeAnnotations(mdef: untpd.MemberDef, sym: Symbol)(using Context): Unit = {

tests/pos/i12953.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Schema(impl: Class[_]) extends scala.annotation.StaticAnnotation
2+
3+
class Ann[A] extends scala.annotation.StaticAnnotation
4+
5+
case class Foo[A](@Schema(classOf[List[A]]) foo: String)
6+
case class Bar[A](@Ann[A] foo: String)
7+
def baz[A](@Ann[A] foo: String) = ()

0 commit comments

Comments
 (0)