Skip to content

Fix calculation to drop transparent classes #16344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
Original file line number Diff line number Diff line change
Expand Up @@ -557,8 +557,10 @@ trait ConstraintHandling {
end approximation

private def isTransparent(tp: Type)(using Context): Boolean = tp match
case AndType(tp1, tp2) => isTransparent(tp1) && isTransparent(tp2)
case _ => tp.typeSymbol.isTransparentClass && !tp.isLambdaSub
case AndType(tp1, tp2) =>
isTransparent(tp1) && isTransparent(tp2)
case _ =>
tp.underlyingClassRef(refinementOK = false).typeSymbol.isTransparentClass

/** If `tp` is an intersection such that some operands are transparent trait instances
* and others are not, replace as many transparent trait instances as possible with Any
Expand All @@ -572,18 +574,17 @@ trait ConstraintHandling {
var dropped: List[Type] = List() // the types dropped so far, last one on top

def dropOneTransparentClass(tp: Type): Type =
val tpd = tp.dealias
if isTransparent(tpd) && !kept.contains(tpd) then
dropped = tpd :: dropped
if isTransparent(tp) && !kept.contains(tp) then
dropped = tp :: dropped
defn.AnyType
else tpd match
else tp match
case AndType(tp1, tp2) =>
val tp1w = dropOneTransparentClass(tp1)
if tp1w ne tp1 then tp1w & tp2
else
val tp2w = dropOneTransparentClass(tp2)
if tp2w ne tp2 then tp1 & tp2w
else tpd
else tp
case _ =>
tp

Expand Down
File renamed without changes.
File renamed without changes.
25 changes: 25 additions & 0 deletions tests/pos/i16338.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.sciss.kollflitz

import scala.collection.*

type Tagged[U] = { type Tag = U }
type @@ [+T, U] = T with Tagged[U]
private val anyTagger = new Tagger[Any]
final class Tagger[U] private[kollflitz] {
def apply[T](t : T): T @@ U = t.asInstanceOf[T @@ U]
}
def tag[U]: Tagger[U] = anyTagger.asInstanceOf[Tagger[U]]

sealed trait Sorted


/** Enrichment methods for random access collections. */
implicit final class KollFlitzSortedIndexedSeq[A, CC[_], Repr](val self: SeqOps[A, CC, Repr] @@ Sorted)
extends AnyVal {

/** Nearest percentile (rounded index, no interpolation). */
def percentile(n: Int): A = self((self.size * n - 50) / 100)

/** Median found by rounding the index (no interpolation). */
def median: A = percentile(50)
}
18 changes: 18 additions & 0 deletions tests/pos/i16342.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
type Opaque = Base with Tag

type Base = Any {
type Hack
}

trait Tag

object Opaque {
def apply(value: String): Opaque = value.asInstanceOf[Opaque]

def unapply(userId: Opaque): Option[String] = Option(userId).map(_.value)
def unappy2(userId: Base with Tag): Option[String] = Option(userId).map(_.value)
}

final implicit class Ops(private val userId: Opaque) extends AnyVal {
def value: String = userId.asInstanceOf[String]
}