Skip to content

Commit ec94ff5

Browse files
committed
Allow to reduce type member extractors when the member is a class.
1 parent 7ab7b0f commit ec94ff5

File tree

4 files changed

+45
-13
lines changed

4 files changed

+45
-13
lines changed

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

+9-13
Original file line numberDiff line numberDiff line change
@@ -3371,19 +3371,15 @@ class TrackingTypeComparer(initctx: Context) extends TypeComparer(initctx) {
33713371
stableScrut.member(typeMemberName) match
33723372
case denot: SingleDenotation if denot.exists =>
33733373
val info = denot.info match
3374-
case TypeAlias(alias) => alias
3375-
case info => info // Notably, RealTypeBounds, which will eventually give a MatchResult.NoInstances
3376-
if info.isInstanceOf[ClassInfo] then
3377-
/* The member is not an alias (we'll get Stuck instead of NoInstances,
3378-
* which is not ideal, but we cannot make a RealTypeBounds of ClassInfo).
3379-
*/
3380-
false
3381-
else
3382-
val infoRefersToSkolem = stableScrut.isInstanceOf[SkolemType] && stableScrut.occursIn(info)
3383-
val info1 =
3384-
if infoRefersToSkolem && !info.isInstanceOf[TypeBounds] then RealTypeBounds(info, info) // to trigger a MatchResult.NoInstances
3385-
else info
3386-
rec(capture, info1, variance = 0, scrutIsWidenedAbstract)
3374+
case TypeAlias(alias) => alias // Extract the alias
3375+
case ClassInfo(prefix, cls, _, _, _) => prefix.select(cls) // Re-select the class from the prefix
3376+
case info => info // Notably, RealTypeBounds, which will eventually give a MatchResult.NoInstances
3377+
val infoRefersToSkolem = stableScrut.isInstanceOf[SkolemType] && stableScrut.occursIn(info)
3378+
val info1 = info match
3379+
case info: TypeBounds => info // Will already trigger a MatchResult.NoInstances
3380+
case _ if infoRefersToSkolem => RealTypeBounds(info, info) // Explicitly trigger a MatchResult.NoInstances
3381+
case _ => info // We have a match
3382+
rec(capture, info1, variance = 0, scrutIsWidenedAbstract)
33873383
case _ =>
33883384
false
33893385
end rec
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- [E172] Type Error: tests/neg/match-type-enumeration-value-hack.scala:11:40 ------------------------------------------
2+
11 | summon[Suit#Value =:= EnumValue[Suit]] // error
3+
| ^
4+
| Cannot prove that Suit#Value =:= EnumValue[Suit].
5+
|
6+
| Note: a match type could not be fully reduced:
7+
|
8+
| trying to reduce EnumValue[Suit]
9+
| failed since selector Suit
10+
| does not uniquely determine parameter t in
11+
| case EnumValueAux[t] => t
12+
| The computed bounds for the parameter are:
13+
| t >: ?1.Value <: ?1.Value
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type EnumValueAux[A] = ({ type Value }) { type Value = A }
2+
3+
type EnumValue[E <: Enumeration] = E match
4+
case EnumValueAux[t] => t
5+
6+
// A class extending Enumeration does not yet define a concrete enumeration
7+
class Suit extends Enumeration:
8+
val Hearts, Diamonds, Clubs, Spades = Val()
9+
10+
object Test:
11+
summon[Suit#Value =:= EnumValue[Suit]] // error
12+
end Test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
type EnumValueAux[A] = ({ type Value }) { type Value = A }
2+
3+
type EnumValue[E <: Enumeration] = E match
4+
case EnumValueAux[t] => t
5+
6+
object Suit extends Enumeration:
7+
val Hearts, Diamonds, Clubs, Spades = Val()
8+
9+
object Test:
10+
summon[Suit.Value =:= EnumValue[Suit.type]]
11+
end Test

0 commit comments

Comments
 (0)