Skip to content

Commit

Permalink
FIX: Fix typing of RefinedTypes with watching parents
Browse files Browse the repository at this point in the history
If a refined type has a parent type watching some other type, the parent
should not be mapped to Object. Previously, the parent counted as `isEmpty`
which caused this mapping.

Fixes scala#10929
  • Loading branch information
odersky committed Apr 2, 2024
1 parent 02d32ed commit 72bab91
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2221,7 +2221,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
}

def typedRefinedTypeTree(tree: untpd.RefinedTypeTree)(using Context): TypTree = {
val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt)
val tpt1 = if tree.tpt == EmptyTree then TypeTree(defn.ObjectType) else typedAheadType(tree.tpt)
val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements).withSpan(tree.span)
val refineCls = createSymbol(refineClsDef).asClass
val TypeDef(_, impl: Template) = typed(refineClsDef): @unchecked
Expand Down
1 change: 1 addition & 0 deletions tests/pos/hylolib-deferred-given/Hasher.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//> using options -language:experimental.modularity -source future
package hylo

import scala.util.Random
Expand Down
21 changes: 21 additions & 0 deletions tests/pos/i10929.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//> using options -language:experimental.modularity -source future
infix abstract class TupleOf[T, +A]:
type Mapped[+A] <: Tuple
def map[B](x: T)(f: A => B): Mapped[B]

object TupleOf:

given TupleOf[EmptyTuple, Nothing] with
type Mapped[+A] = EmptyTuple
def map[B](x: EmptyTuple)(f: Nothing => B): Mapped[B] = x

given [A, Rest <: Tuple](using tracked val tup: Rest TupleOf A): TupleOf[A *: Rest, A] with
type Mapped[+A] = A *: tup.Mapped[A]
def map[B](x: A *: Rest)(f: A => B): Mapped[B] =
(f(x.head) *: tup.map(x.tail)(f))

def foo[T](xs: T)(using tup: T TupleOf Int): tup.Mapped[Int] = tup.map(xs)(_ + 1)

@main def test =
foo(EmptyTuple): EmptyTuple // ok
foo(1 *: EmptyTuple): Int *: EmptyTuple // now also ok
13 changes: 13 additions & 0 deletions tests/pos/i13580.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//> using options -language:experimental.modularity -source future
trait IntWidth:
type Out
given IntWidth:
type Out = 155

trait IntCandidate:
type Out
given (using tracked val w: IntWidth) => IntCandidate:
type Out = w.Out

val x = summon[IntCandidate]
val xx = summon[x.Out =:= 155]

0 comments on commit 72bab91

Please sign in to comment.