Skip to content

Normalize match types before computing implicit scopes #20081

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all 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
9 changes: 4 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -615,9 +615,9 @@ trait ImplicitRunInfo:
if migrateTo3 then false else sym.is(Package) || sym.isPackageObject

/** Is `sym` an anchor type for which givens may exist? Anchor types are classes,
* opaque type aliases, match aliases and abstract types, but not type parameters
* or package objects.
*/
* abstract types, opaque type aliases, and unreducible match aliases, but not type parameters
* or package objects.
*/
private def isAnchor(sym: Symbol) =
sym.isClass && !isExcluded(sym)
|| sym.isOpaqueAlias
Expand All @@ -636,7 +636,7 @@ trait ImplicitRunInfo:
else if implicitScopeCache.contains(t) then parts += t
else
partSeen += t
t.dealias match
t.dealias.normalized match
case t: TypeRef =>
if isAnchor(t.symbol) then
parts += t
Expand All @@ -663,7 +663,6 @@ trait ImplicitRunInfo:
traverseChildren(t)
case t =>
traverseChildren(t)
traverse(t.normalized)
catch case ex: Throwable => handleRecursive("collectParts of", t.show, ex)

def apply(tp: Type): collection.Set[Type] =
Expand Down
2 changes: 0 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/ImportInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ class ImportInfo(symf: Context ?=> Symbol,
assert(myUnimported != null)
myUnimported.uncheckedNN

private val isLanguageImport: Boolean = untpd.languageImport(qualifier).isDefined

private var myUnimported: Symbol | Null = uninitialized

private var featureCache: SimpleIdentityMap[TermName, java.lang.Boolean] = SimpleIdentityMap.empty
Expand Down
96 changes: 96 additions & 0 deletions tests/neg/i15183.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@

-- [E172] Type Error: tests/neg/i15183/test_2.scala:2:17 ---------------------------------------------------------------
2 |enum Env derives Decoder: // error
| ^
|No given instance of type Tuple.Map[m.MirroredElemTypes, Decoder] was found for parameter d of given instance derived in object Decoder.
|I found:
|
| Decoder.summonTuple[(Env.Local : Env), ((Env.Sit : Env), (Env.Prod : Env))](
| Decoder.derived[(Env.Local : Env)](
| Env.Local.$asInstanceOf[
| scala.deriving.Mirror.Singleton{
| type MirroredMonoType = (Env.Local : Env); type MirroredType = (Env.Local : Env);
| type MirroredLabel = ("Local" : String)
| }
| ],
| /* missing */summon[Tuple.Map[?1.MirroredElemTypes, Decoder]]),
| ???)
|
|But no implicit values were found that match type Tuple.Map[?1.MirroredElemTypes, Decoder]
|
|where: ?1 is an unknown value of type scala.deriving.Mirror.Singleton{
| type MirroredMonoType = (Env.Local : Env); type MirroredType = (Env.Local : Env);
| type MirroredLabel = ("Local" : String)
|}
|.
|
|Note: a match type could not be fully reduced:
|
| trying to reduce Tuple.Map[m.MirroredElemTypes, Decoder]
| failed since selector m.MirroredElemTypes
| does not match case EmptyTuple => EmptyTuple
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case h *: t => Decoder[h] *: Tuple.Map[t, Decoder]
-- [E172] Type Error: tests/neg/i15183/test_2.scala:5:18 ---------------------------------------------------------------
5 |enum Env2 derives Decoder: // error
| ^
|No given instance of type Tuple.Map[m.MirroredElemTypes, Decoder] was found for parameter d of given instance derived in object Decoder.
|I found:
|
| Decoder.summonTuple[Env2.Local, (Env2.Sit, Env2.Prod)](
| Decoder.derived[Env2.Local](
| Env2.Local.$asInstanceOf[
| scala.deriving.Mirror.Product{
| type MirroredMonoType = Env2.Local; type MirroredType = Env2.Local; type MirroredLabel = ("Local" : String);
| type MirroredElemTypes = EmptyTuple.type; type MirroredElemLabels = EmptyTuple.type
| }
| ],
| /* missing */summon[Tuple.Map[EmptyTuple.type, Decoder]]),
| ???)
|
|But no implicit values were found that match type Tuple.Map[EmptyTuple.type, Decoder].
|
|Note: a match type could not be fully reduced:
|
| trying to reduce Tuple.Map[m.MirroredElemTypes, Decoder]
| failed since selector m.MirroredElemTypes
| does not match case EmptyTuple => EmptyTuple
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case h *: t => Decoder[h] *: Tuple.Map[t, Decoder]
-- [E172] Type Error: tests/neg/i15183/test_2.scala:10:19 --------------------------------------------------------------
10 |enum Shape derives Decoder: // error
| ^
|No given instance of type Tuple.Map[m.MirroredElemTypes, Decoder] was found for parameter d of given instance derived in object Decoder.
|I found:
|
| Decoder.summonTuple[Shape.Rectangle, Shape.Circle *: EmptyTuple.type](
| Decoder.derived[Shape.Rectangle](
| Shape.Rectangle.$asInstanceOf[
| scala.deriving.Mirror.Product{
| type MirroredMonoType = Shape.Rectangle; type MirroredType = Shape.Rectangle;
| type MirroredLabel = ("Rectangle" : String); type MirroredElemTypes = (Double, Double);
| type MirroredElemLabels = (("width" : String), ("height" : String))
| }
| ],
| Decoder.summonTuple[Double, Double *: EmptyTuple.type](Decoder.given_Decoder_Double,
| Decoder.summonTuple[Double, EmptyTuple.type](Decoder.given_Decoder_Double,
| /* missing */summon[Tuple.Map[EmptyTuple.type, Decoder]])
| )
| ),
| ???)
|
|But no implicit values were found that match type Tuple.Map[EmptyTuple.type, Decoder].
|
|Note: a match type could not be fully reduced:
|
| trying to reduce Tuple.Map[m.MirroredElemTypes, Decoder]
| failed since selector m.MirroredElemTypes
| does not match case EmptyTuple => EmptyTuple
| and cannot be shown to be disjoint from it either.
| Therefore, reduction cannot advance to the remaining case
|
| case h *: t => Decoder[h] *: Tuple.Map[t, Decoder]
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Fails in each cases below
enum Env derives Decoder:
enum Env derives Decoder: // error
case Local,Sit,Prod

enum Env2 derives Decoder:
enum Env2 derives Decoder: // error
case Local()
case Sit()
case Prod()

enum Shape derives Decoder:
enum Shape derives Decoder: // error
case Rectangle(width: Double, height: Double)
case Circle(radius: Double)
5 changes: 5 additions & 0 deletions tests/neg/i20071.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

-- [E172] Type Error: tests/neg/i20071/test_2.scala:3:20 ---------------------------------------------------------------
3 |def test: Unit = bar // error
| ^
| No given instance of type M[Decoder] was found for parameter d of method bar
9 changes: 9 additions & 0 deletions tests/neg/i20071/decoder_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// decoder_1.scala
trait Decoder
object Decoder:
given foo: Int = ???

def bar(using d: M[Decoder]): Any = ???

type M[Y] = Y match
case Decoder => Int
3 changes: 3 additions & 0 deletions tests/neg/i20071/test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// test_2.scala
// should fail, does when compiling at the same time as decoder_2.scala
def test: Unit = bar // error
8 changes: 8 additions & 0 deletions tests/pos/i20071.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
trait Decoder
object Decoder:
given foo: Int = ???

type DecoderToInt[Why] >: Int <: Int

def bar[T](using d: DecoderToInt[T]): Any = ???
def test: Unit = bar[Decoder]