Skip to content

Commit

Permalink
Add a run test for poly context bounds; cleanup typer changes
Browse files Browse the repository at this point in the history
  • Loading branch information
KacperFKorban committed Nov 15, 2024
1 parent f292ac5 commit f9db9fa
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 7 deletions.
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import parsing.Parsers

import scala.annotation.internal.sharable
import scala.annotation.threadUnsafe
import dotty.tools.dotc.quoted.QuoteUtils.treeOwner

object desugar {
import untpd.*
Expand Down
12 changes: 6 additions & 6 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1945,15 +1945,15 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
val resultTpt =
untpd.InLambdaTypeTree(isResult = true, (tsyms, vsyms) =>
mt.resultType.substParams(mt, vsyms.map(_.termRef)).substParams(poly, tsyms.map(_.typeRef)))
val desugared @ Block(List(defdef), _) = desugar.makeClosure(tparams, inferredVParams, body, resultTpt, tree.span)
val desugared = desugar.makeClosure(tparams, inferredVParams, body, resultTpt, tree.span)
typed(desugared, pt)
else
val msg =
em"""|Provided polymorphic function value doesn't match the expected type $dpt.
|Expected type should be a polymorphic function with the same number of type and value parameters."""
errorTree(EmptyTree, msg, tree.srcPos)
case _ =>
val desugared @ Block(List(defdef), _) = desugar.makeClosure(tparams, vparams, body, untpd.TypeTree(), tree.span)
val desugared = desugar.makeClosure(tparams, vparams, body, untpd.TypeTree(), tree.span)
typed(desugared, pt)
end typedPolyFunctionValue

Expand Down Expand Up @@ -3581,17 +3581,17 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
case xtree => typedUnnamed(xtree)

val unsimplifiedType = result.tpe
val result1 = simplify(result, pt, locked)
result1.tpe.stripTypeVar match
simplify(result, pt, locked)
result.tpe.stripTypeVar match
case e: ErrorType if !unsimplifiedType.isErroneous => errorTree(xtree, e.msg, xtree.srcPos)
case _ => result1
case _ => result
catch case ex: TypeError =>
handleTypeError(ex)
}
}

/** Interpolate and simplify the type of the given tree. */
protected def simplify(tree: Tree, pt: Type, locked: TypeVars)(using Context): Tree =
protected def simplify(tree: Tree, pt: Type, locked: TypeVars)(using Context): tree.type =
if !tree.denot.isOverloaded then // for overloaded trees: resolve overloading before simplifying
if !tree.tpe.widen.isInstanceOf[MethodOrPoly] // wait with simplifying until method is fully applied
|| tree.isDef // ... unless tree is a definition
Expand Down
6 changes: 6 additions & 0 deletions tests/run/contextbounds-for-poly-functions.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
42
a string
Kate is 27 years old
42 and a string
a string and Kate is 27 years old
Kate is 27 years old and 42
30 changes: 30 additions & 0 deletions tests/run/contextbounds-for-poly-functions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import scala.language.experimental.modularity
import scala.language.future

trait Show[X]:
def show(x: X): String

given Show[Int] with
def show(x: Int) = x.toString

given Show[String] with
def show(x: String) = x

case class Person(name: String, age: Int)

given Show[Person] with
def show(x: Person) = s"${x.name} is ${x.age} years old"

type Shower = [X: Show] => X => String
val shower: Shower = [X: {Show as show}] => (x: X) => show.show(x)

type DoubleShower = [X: Show] => X => [Y: Show] => Y => String
val doubleShower: DoubleShower = [X: {Show as show1}] => (x: X) => [Y: {Show as show2}] => (y: Y) => s"${show1.show(x)} and ${show2.show(y)}"

object Test extends App:
println(shower(42))
println(shower("a string"))
println(shower(Person("Kate", 27)))
println(doubleShower(42)("a string"))
println(doubleShower("a string")(Person("Kate", 27)))
println(doubleShower(Person("Kate", 27))(42))

0 comments on commit f9db9fa

Please sign in to comment.