Skip to content

Commit 2bfb5c1

Browse files
committed
Address review comments
1 parent 05c812f commit 2bfb5c1

File tree

2 files changed

+52
-31
lines changed

2 files changed

+52
-31
lines changed

compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -85,37 +85,35 @@ class ExpandSAMs extends MiniPhase:
8585
}
8686
case _ => false
8787

88-
val forwarderSym =
89-
if needsArrayAdaptation then
90-
// Create a wrapper method with SAM's signature that casts args to impl's types
91-
val wrapperSym = newSymbol(
92-
implSym.owner, implSym.name.asTermName, Synthetic | Method,
93-
samInfo, coord = implSym.span).entered.asTerm
94-
val wrapperDef = DefDef(wrapperSym, paramss => {
95-
val implMt = implInfo.asInstanceOf[MethodType]
96-
val adaptedArgs = paramss.head.lazyZip(implMt.paramInfos).map { (arg, implPt) =>
97-
if arg.tpe =:= implPt then arg else arg.cast(implPt)
98-
}
99-
ref(implSym).appliedToTermArgs(adaptedArgs)
100-
})
101-
cpy.Block(tree)(fn :: wrapperDef :: Nil,
102-
transformFollowingDeep:
103-
AnonClass(List(tpe1),
104-
List(samDenot.symbol.asTerm.name -> wrapperSym),
105-
refinements.toList,
106-
adaptVarargs = true
107-
)
108-
)
109-
else
110-
cpy.Block(tree)(stats,
111-
transformFollowingDeep:
112-
AnonClass(List(tpe1),
113-
List(samDenot.symbol.asTerm.name -> implSym),
114-
refinements.toList,
115-
adaptVarargs = true
116-
)
117-
)
118-
forwarderSym
88+
if needsArrayAdaptation then
89+
// Create a wrapper method with SAM's signature that casts args to impl's types
90+
val wrapperSym = newSymbol(
91+
implSym.owner, implSym.name.asTermName, Synthetic | Method,
92+
samInfo, coord = implSym.span).entered.asTerm
93+
val wrapperDef = DefDef(wrapperSym, paramss => {
94+
val implMt = implInfo.stripPoly.asInstanceOf[MethodType]
95+
val adaptedArgs = paramss.head.lazyZip(implMt.paramInfos).map { (arg, implPt) =>
96+
if arg.tpe =:= implPt then arg else arg.cast(implPt)
97+
}
98+
ref(implSym).appliedToTermArgs(adaptedArgs)
99+
})
100+
cpy.Block(tree)(fn :: wrapperDef :: Nil,
101+
transformFollowingDeep:
102+
AnonClass(List(tpe1),
103+
List(samDenot.symbol.asTerm.name -> wrapperSym),
104+
refinements.toList,
105+
adaptVarargs = true
106+
)
107+
)
108+
else
109+
cpy.Block(tree)(stats,
110+
transformFollowingDeep:
111+
AnonClass(List(tpe1),
112+
List(samDenot.symbol.asTerm.name -> implSym),
113+
refinements.toList,
114+
adaptVarargs = true
115+
)
116+
)
119117
}
120118
case _ =>
121119
tree

tests/run/i23179.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
11
object Test {
2+
// Basic case: SAM expects Array[AnyRef], impl has Array[? >: AnyRef]
23
trait A { def f(a: Array[AnyRef]): Any }
34
def g(a: A) = a.f(Array.empty[AnyRef])
45

6+
// Multiple array parameters
7+
trait MultiParam { def f(a: Array[AnyRef], b: Array[AnyRef]): Any }
8+
def gMulti(a: MultiParam) = a.f(Array.empty[AnyRef], Array.empty[AnyRef])
9+
10+
// Mixed parameters: only some need adaptation
11+
trait MixedParam { def f(a: Array[AnyRef], b: Int): Any }
12+
def gMixed(a: MixedParam) = a.f(Array.empty[AnyRef], 42)
13+
14+
// Generic return type
15+
trait GenericReturn[T] { def f(a: Array[AnyRef]): T }
16+
def gGeneric[T](a: GenericReturn[T]): T = a.f(Array.empty[AnyRef])
17+
518
def main(args: Array[String]): Unit = {
19+
// Basic case
620
g((x: Array[? >: AnyRef]) => x.headOption)
21+
22+
// Multiple array parameters - both need adaptation
23+
gMulti((x: Array[? >: AnyRef], y: Array[? >: AnyRef]) => (x.headOption, y.headOption))
24+
25+
// Mixed - only first param needs adaptation
26+
gMixed((x: Array[? >: AnyRef], n: Int) => (x.headOption, n))
27+
28+
// Generic return type
29+
val result: Option[?] = gGeneric((x: Array[? >: AnyRef]) => x.headOption)
730
}
831
}

0 commit comments

Comments
 (0)