Skip to content

Commit 35a8f93

Browse files
committed
Make Matchable an empty marker trait
1 parent bb3b5a7 commit 35a8f93

File tree

13 files changed

+35
-31
lines changed

13 files changed

+35
-31
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ trait BCodeBodyBuilder extends BCodeSkelBuilder {
625625

626626
val sym = fun.symbol
627627
val cast =
628-
if (sym == defn.Matchable_isInstanceOf) false
628+
if (sym == defn.Any_isInstanceOf) false
629629
else if (sym == defn.Any_asInstanceOf) true
630630
else abort(s"Unexpected type application $fun[sym: ${sym.showFullName}] in: $t")
631631
val l = tpeTK(obj)

compiler/src/dotty/tools/backend/jvm/scalaPrimitives.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ class DottyPrimitives(ictx: Context) {
149149
// scala.Any
150150
addPrimitive(defn.Any_==, EQ)
151151
addPrimitive(defn.Any_!=, NE)
152-
addPrimitive(defn.Matchable_isInstanceOf, IS)
152+
addPrimitive(defn.Any_isInstanceOf, IS)
153153
addPrimitive(defn.Any_asInstanceOf, AS)
154154
addPrimitive(defn.Any_##, HASH)
155155

@@ -159,7 +159,7 @@ class DottyPrimitives(ictx: Context) {
159159
/* addPrimitive(defn.Any_==, EQ)
160160
addPrimitive(defn.Any_!=, NE)*/
161161
addPrimitive(defn.Object_synchronized, SYNCHRONIZED)
162-
/*addPrimitive(defn.Matchable_isInstanceOf, IS)
162+
/*addPrimitive(defn.Any_isInstanceOf, IS)
163163
addPrimitive(defn.Any_asInstanceOf, AS)*/
164164

165165
// java.lang.String

compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2867,7 +2867,7 @@ class JSCodeGen()(using genCtx: Context) {
28672867

28682868
if (sym == defn.Any_asInstanceOf) {
28692869
genAsInstanceOf(genReceiver, to)
2870-
} else if (sym == defn.Matchable_isInstanceOf) {
2870+
} else if (sym == defn.Any_isInstanceOf) {
28712871
genIsInstanceOf(genReceiver, to)
28722872
} else {
28732873
throw new FatalError(

compiler/src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
957957
singleton(tp).equal(tree)
958958
case _ =>
959959
tree.ensureConforms(defn.MatchableType)
960-
.select(defn.Matchable_isInstanceOf)
960+
.select(defn.Any_isInstanceOf)
961961
.appliedToType(tp)
962962
}
963963

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,12 @@ class Definitions {
287287
@tu lazy val Any_hashCode: TermSymbol = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
288288
@tu lazy val Any_toString: TermSymbol = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
289289
@tu lazy val Any_## : TermSymbol = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
290+
@tu lazy val Any_isInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
290291
@tu lazy val Any_asInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, _.paramRefs(0), Final)
291292
@tu lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact)
292293
@tu lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable)
293294
// generated by pattern matcher and explicit nulls, eliminated by erasure
294295

295-
@tu lazy val Matchable_isInstanceOf: TermSymbol = enterT1ParameterlessMethod(MatchableClass, nme.isInstanceOf_, _ => BooleanType, Final)
296-
297296
/** def getClass[A >: this.type](): Class[? <: A] */
298297
@tu lazy val Any_getClass: TermSymbol =
299298
enterPolyMethod(
@@ -303,11 +302,7 @@ class Definitions {
303302
bounds = TypeBounds.lower(AnyClass.thisType))
304303

305304
def AnyMethods: List[TermSymbol] = List(Any_==, Any_!=, Any_equals, Any_hashCode, Any_getClass,
306-
Any_toString, Any_##, Matchable_isInstanceOf, Any_asInstanceOf, Any_typeTest, Any_typeCast)
307-
308-
def MatchableMethods: List[TermSymbol] = List(Matchable_isInstanceOf)
309-
310-
@tu lazy val MatchableMethodNames = MatchableMethods.map(_.name)
305+
Any_toString, Any_##, Any_isInstanceOf, Any_asInstanceOf, Any_typeTest, Any_typeCast)
311306

312307
@tu lazy val ObjectClass: ClassSymbol = {
313308
val cls = requiredClass("java.lang.Object")
@@ -443,7 +438,7 @@ class Definitions {
443438

444439
/** Methods in Object, Matchable, and Any that do not have a side effect */
445440
@tu lazy val pureMethods: List[TermSymbol] = List(Any_==, Any_!=, Any_equals, Any_hashCode,
446-
Any_toString, Any_##, Any_getClass, Matchable_isInstanceOf, Any_typeTest, Object_eq, Object_ne)
441+
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_typeTest, Object_eq, Object_ne)
447442

448443
@tu lazy val AnyKindClass: ClassSymbol = {
449444
val cls = newCompleteClassSymbol(ScalaPackageClass, tpnme.AnyKind, AbstractFinal | Permanent, Nil)
@@ -1432,7 +1427,7 @@ class Definitions {
14321427
@tu lazy val NoInitClasses: Set[Symbol] = NotRuntimeClasses + FunctionXXLClass
14331428

14341429
def isPolymorphicAfterErasure(sym: Symbol): Boolean =
1435-
(sym eq Matchable_isInstanceOf) || (sym eq Any_asInstanceOf) || (sym eq Object_synchronized)
1430+
(sym eq Any_isInstanceOf) || (sym eq Any_asInstanceOf) || (sym eq Object_synchronized)
14361431

14371432
def isTupleType(tp: Type)(using Context): Boolean = {
14381433
val arity = tp.dealias.argInfos.length
@@ -1748,7 +1743,7 @@ class Definitions {
17481743

17491744
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
17501745
@tu lazy val syntheticCoreMethods: List[TermSymbol] =
1751-
AnyMethods ++ MatchableMethods ++ ObjectMethods ++ List(String_+, throwMethod)
1746+
AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod)
17521747

17531748
@tu lazy val reservedScalaClassNames: Set[Name] = syntheticScalaClasses.map(_.name).toSet
17541749

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ object Types {
207207

208208
def isAny(using Context): Boolean = isRef(defn.AnyClass, skipRefined = false)
209209
def isAnyRef(using Context): Boolean = isRef(defn.ObjectClass, skipRefined = false)
210-
def isMatchable(using Context): Boolean = isRef(defn.MatchableClass, skipRefined = false)
211210
def isAnyKind(using Context): Boolean = isRef(defn.AnyKindClass, skipRefined = false)
212211

213212
def isTopType(using Context): Boolean = dealias match
@@ -517,6 +516,20 @@ object Types {
517516
case _ =>
518517
false
519518

519+
/** Same as hasClassSmbol(MatchableClass), except that we also follow the constraint
520+
* bounds of type variables in the constraint.
521+
*/
522+
def isMatchableBound(using Context): Boolean = dealias match
523+
case tp: TypeRef => tp.symbol == defn.MatchableClass
524+
case tp: TypeParamRef =>
525+
ctx.typerState.constraint.entry(tp) match
526+
case bounds: TypeBounds => bounds.hi.isMatchableBound
527+
case _ => false
528+
case tp: TypeProxy => tp.underlying.isMatchableBound
529+
case tp: AndType => tp.tp1.isMatchableBound || tp.tp2.isMatchableBound
530+
case tp: OrType => tp.tp1.isMatchableBound && tp.tp2.isMatchableBound
531+
case _ => false
532+
520533
/** The term symbol associated with the type */
521534
@tailrec final def termSymbol(using Context): Symbol = this match {
522535
case tp: TermRef => tp.symbol

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ object SymUtils:
4949
else directlyInheritedTraits
5050

5151
def isTypeTest(using Context): Boolean =
52-
self == defn.Matchable_isInstanceOf || self == defn.Any_typeTest
52+
self == defn.Any_isInstanceOf || self == defn.Any_typeTest
5353

5454
def isTypeCast(using Context): Boolean =
5555
self == defn.Any_asInstanceOf || self == defn.Any_typeCast

compiler/src/dotty/tools/dotc/transform/TypeTestsCasts.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ object TypeTestsCasts {
274274
transformIsInstanceOf(
275275
expr, defn.boxedType(testCls.typeRef), testCls.typeRef, flagUnrelated)
276276
else
277-
derivedTree(expr, defn.Matchable_isInstanceOf, testType)
277+
derivedTree(expr, defn.Any_isInstanceOf, testType)
278278
}
279279
}
280280

@@ -339,7 +339,7 @@ object TypeTestsCasts {
339339
ref(defn.runtimeMethodRef(nme.isArray)).appliedTo(arg, Literal(Constant(ndims)))
340340
if (ndims == 1) isArrayTest(expr)
341341
else evalOnce(expr) { e =>
342-
derivedTree(e, defn.Matchable_isInstanceOf, e.tpe)
342+
derivedTree(e, defn.Any_isInstanceOf, e.tpe)
343343
.and(isArrayTest(e))
344344
}
345345
case tref: TypeRef if tref.symbol == defn.TupleClass =>

compiler/src/dotty/tools/dotc/transform/init/Env.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ case class Env(ctx: Context) {
2626
// Methods that should be ignored in the checking
2727
lazy val ignoredMethods: Set[Symbol] = Set(
2828
defn.Any_getClass,
29-
defn.Matchable_isInstanceOf,
29+
defn.Any_isInstanceOf,
3030
defn.Object_eq,
3131
defn.Object_ne,
3232
defn.Object_synchronized

compiler/src/dotty/tools/dotc/transform/sjs/ExplicitJSClasses.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ class ExplicitJSClasses extends MiniPhase with InfoTransformer { thisPhase =>
604604

605605
// Translate x.isInstanceOf[T] for inner and local JS classes
606606
case TypeApply(fun @ Select(obj, _), tpeArg :: Nil)
607-
if sym == defn.Matchable_isInstanceOf && isTypeTreeForInnerOrLocalJSClass(tpeArg) =>
607+
if sym == defn.Any_isInstanceOf && isTypeTreeForInnerOrLocalJSClass(tpeArg) =>
608608
val jsCtorOf = genJSConstructorOf(tree, tpeArg.tpe)
609609
ref(jsdefn.Special_instanceof).appliedTo(obj, jsCtorOf)
610610

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3524,11 +3524,7 @@ class Typer extends Namer
35243524
}
35253525

35263526
// try an Any -> Matchable conversion
3527-
def isMatchableTarget = pt match
3528-
case SelectionProto(selName, _, _, _) => defn.MatchableMethodNames.contains(selName)
3529-
case _ => pt.isMatchable
3530-
3531-
if isMatchableTarget && !wtp.derivesFrom(defn.MatchableClass) then
3527+
if pt.isMatchableBound && !wtp.derivesFrom(defn.MatchableClass) then
35323528
checkMatchable(wtp, tree.srcPos, pattern = false)
35333529
val target = AndType(tree.tpe.widenExpr, defn.MatchableType)
35343530
if target <:< pt then

tests/new/test.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1+
object Test:
12

2-
type Curried = [X] =>> [Y] =>> String
3-
type PartialApplication[X] = Curried[String][X]
4-
val test1 = PartialApplication[String]
5-
val test2 = Curried[String][String]
3+
def test = ???

tests/run/scrutable.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ def foo[T](x: T): Matchable =
1818
case List(y :: Nil) =>
1919
y :: Nil
2020
case _ =>
21-
x
21+
g(x)
22+
23+
def g[T <: Matchable](x: T) = x
2224

2325
@main def Test =
2426
val x: Matchable = foo(1)

0 commit comments

Comments
 (0)