Skip to content

Commit 45a4cb7

Browse files
authored
Merge pull request #6243 from dotty-staging/fix/i6236
Fix #6236: drop @Repeated when inferring type args, return types
2 parents 63aab40 + 1ed5d3c commit 45a4cb7

File tree

6 files changed

+64
-5
lines changed

6 files changed

+64
-5
lines changed

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ trait ConstraintHandling[AbstractContext] {
277277
* of `scala.Singleton`, widen `tp`.
278278
* 2. If `tp` is a union type, yet upper bound is not a union type,
279279
* approximate the union type from above by an intersection of all common base types.
280+
*
281+
* At this point we also drop the @Repeated annotation to avoid inferring type arguments with it,
282+
* as those could leak the annotation to users (see run/inferred-repeated-result).
280283
*/
281284
def widenInferred(tp: Type, bound: Type)(implicit actx: AbstractContext): Type = {
282285
def isMultiSingleton(tp: Type): Boolean = tp.stripAnnots match {
@@ -302,7 +305,7 @@ trait ConstraintHandling[AbstractContext] {
302305
if (isMultiSingleton(tp) && !isMultiSingleton(bound) &&
303306
!isSubTypeWhenFrozen(bound, defn.SingletonType)) tp.widen
304307
else tp
305-
widenOr(widenSingle(tp))
308+
widenOr(widenSingle(tp)).dropRepeatedAnnot
306309
}
307310

308311
/** The instance type of `param` in the current constraint (which contains `param`).

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,6 +1485,13 @@ object Types {
14851485
*/
14861486
def signature(implicit ctx: Context): Signature = Signature.NotAMethod
14871487

1488+
def dropRepeatedAnnot(implicit ctx: Context): Type = this match {
1489+
case AnnotatedType(parent, annot) if annot.symbol eq defn.RepeatedAnnot => parent
1490+
case tp @ AnnotatedType(parent, annot) =>
1491+
tp.derivedAnnotatedType(parent.dropRepeatedAnnot, annot)
1492+
case tp => tp
1493+
}
1494+
14881495
def annotatedToRepeated(implicit ctx: Context): Type = this match {
14891496
case tp @ ExprType(tp1) => tp.derivedExprType(tp1.annotatedToRepeated)
14901497
case AnnotatedType(tp, annot) if annot matches defn.RepeatedAnnot =>

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,10 +1320,15 @@ class Namer { typer: Typer =>
13201320
// Widen rhs type and eliminate `|' but keep ConstantTypes if
13211321
// definition is inline (i.e. final in Scala2) and keep module singleton types
13221322
// instead of widening to the underlying module class types.
1323-
def widenRhs(tp: Type): Type = tp.widenTermRefExpr match {
1324-
case ctp: ConstantType if isInlineVal => ctp
1325-
case ref: TypeRef if ref.symbol.is(ModuleClass) => tp
1326-
case _ => tp.widen.widenUnion
1323+
// We also drop the @Repeated annotation here to avoid leaking it in method result types
1324+
// (see run/inferred-repeated-result).
1325+
def widenRhs(tp: Type): Type = {
1326+
val tp1 = tp.widenTermRefExpr match {
1327+
case ctp: ConstantType if isInlineVal => ctp
1328+
case ref: TypeRef if ref.symbol.is(ModuleClass) => tp
1329+
case _ => tp.widen.widenUnion
1330+
}
1331+
tp1.dropRepeatedAnnot
13271332
}
13281333

13291334
// Replace aliases to Unit by Unit itself. If we leave the alias in
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
C.bar1 : scala.Option[scala.collection.Seq[scala.Predef.String]]
2+
C.bar2 : scala.Option[scala.collection.Seq[scala.Predef.String]]
3+
C.foo1 : scala.collection.Seq[scala.Predef.String]
4+
C.foo2 : scala.collection.Seq[scala.Predef.String]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
object Macros {
2+
import scala.quoted._
3+
import scala.quoted.autolift._
4+
import scala.tasty._
5+
6+
inline def go[T](t: => T) = ${ impl('t) }
7+
def impl[T](expr: Expr[T])(implicit reflect: Reflection): Expr[Unit] = {
8+
import reflect._
9+
10+
val tree = expr.unseal
11+
12+
val methods =
13+
tree.tpe.classSymbol.get.classMethods.map { m =>
14+
val name = m.showCode
15+
val returnType = m.tree.returnTpt.tpe.showCode
16+
s"$name : $returnType"
17+
}.sorted
18+
19+
methods.foldLeft('{}) { (res, m) => '{ $res; println(${m}) } }
20+
}
21+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class C {
2+
def foo1(s: String*) = s
3+
def foo2(s: String*) = {
4+
val s1 = s
5+
s
6+
}
7+
8+
def bar1(s: String*) = Option(s)
9+
def bar2(s: String*) = {
10+
val o = Option(s)
11+
o
12+
}
13+
}
14+
15+
object Test {
16+
def main(args: Array[String]): Unit = {
17+
Macros.go(new C)
18+
}
19+
}

0 commit comments

Comments
 (0)