Skip to content

Commit 66a3880

Browse files
committed
Support bindngs of polymorphic methods
Make Bindings Any-kinded and convert PolyTypes to HKTypes as part of (toFunctionType)
1 parent 01b95f5 commit 66a3880

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1978,8 +1978,11 @@ class Typer extends Namer
19781978
if (ddef.symbol.annotations.exists(_.symbol == defn.InternalQuoted_patternBindHoleAnnot)) {
19791979
val tpe = ddef.symbol.info match {
19801980
case t: ExprType => t.resType
1981-
case t: PolyType => t.resultType.toFunctionType()
19821981
case t: MethodType => t.toFunctionType()
1982+
case t: PolyType =>
1983+
HKTypeLambda(t.paramNames)(
1984+
x => t.paramInfos.mapConserve(_.subst(t, x).asInstanceOf[TypeBounds]),
1985+
x => t.resType.subst(t, x).toFunctionType())
19831986
case t => t
19841987
}
19851988
val exprTpe = AppliedType(defn.QuotedMatchingBindingType, tpe :: Nil)

library/src/scala/quoted/matching/Binding.scala renamed to library/src-bootstrapped/scala/quoted/matching/Binding.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import scala.tasty.Reflection // TODO do not depend on reflection directly
88
* @param name string name of this binding
99
* @param id unique id used for equality
1010
*/
11-
class Binding[+T] private[scala](val name: String, private[Binding] val id: Object) { self =>
11+
class Binding[T <: AnyKind] private[scala](val name: String, private[Binding] val id: Object) { self =>
1212

1313
override def equals(obj: Any): Boolean = obj match {
1414
case obj: Binding[_] => obj.id == id
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package scala.quoted
2+
package matching
3+
4+
import scala.tasty.Reflection // TODO do not depend on reflection directly
5+
6+
/** Binding of an Expr[T] used to know if some Expr[T] is a reference to the binding
7+
*
8+
* @param name string name of this binding
9+
* @param id unique id used for equality
10+
*/
11+
class Binding[T /*<: AnyKind*/] private[scala](val name: String, private[Binding] val id: Object) { self =>
12+
13+
override def equals(obj: Any): Boolean = obj match {
14+
case obj: Binding[_] => obj.id == id
15+
case _ => false
16+
}
17+
18+
override def hashCode(): Int = id.hashCode()
19+
20+
}
21+
22+
object Binding {
23+
24+
def unapply[T](expr: Expr[T])(implicit reflect: Reflection): Option[Binding[T]] = {
25+
import reflect._
26+
expr.unseal match {
27+
case IsIdent(ref) =>
28+
val sym = ref.symbol
29+
Some(new Binding[T](sym.name, sym))
30+
case _ => None
31+
}
32+
}
33+
34+
}

tests/pos/quotedPatterns.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@ object Test {
3131
case '{ def $ff(i: Int)(j: Int): Int = $z; 2 } =>
3232
val a: quoted.matching.Binding[Int => Int => Int] = ff
3333
z
34-
// FIXME
35-
// case '{ def `$ff`[T](i: T): Int = $z; 2 } =>
36-
// val a: quoted.matching.Binding[[T] => T => Int] = ff // TODO make Binding any-kinded
37-
// z
34+
case '{ def $ff[T](i: T): Int = $z; 2 } =>
35+
val a: quoted.matching.Binding[[T] => T => Int] = ff
36+
z
3837
case _ => '{1}
3938
}
4039
}

0 commit comments

Comments
 (0)