Skip to content

Commit e460be0

Browse files
committed
Improve type of getClass
The new assumed signature is def getClass[A >: this.type](): Class[? <: A] This matches what scalac does, without requiring special machinery in the type checker and inferencer.
1 parent 79fb64e commit e460be0

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,12 @@ class Definitions {
153153
tl => op(tl.paramRefs(0), tl.paramRefs(1))))
154154

155155
private def enterPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
156-
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags,
156+
resultTypeFn: PolyType => Type,
157+
flags: FlagSet = EmptyFlags,
158+
bounds: TypeBounds = TypeBounds.empty,
157159
useCompleter: Boolean = false) = {
158160
val tparamNames = PolyType.syntheticParamNames(typeParamCount)
159-
val tparamInfos = tparamNames map (_ => TypeBounds.empty)
161+
val tparamInfos = tparamNames map (_ => bounds)
160162
def ptype = PolyType(tparamNames)(_ => tparamInfos, resultTypeFn)
161163
val info =
162164
if (useCompleter)
@@ -261,19 +263,26 @@ class Definitions {
261263
@tu lazy val AnyValClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef)))
262264
def AnyValType: TypeRef = AnyValClass.typeRef
263265

264-
@tu lazy val Any_== : TermSymbol = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
265-
@tu lazy val Any_!= : TermSymbol = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
266-
@tu lazy val Any_equals: TermSymbol = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
267-
@tu lazy val Any_hashCode: TermSymbol = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
268-
@tu lazy val Any_toString: TermSymbol = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
269-
@tu lazy val Any_## : TermSymbol = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
270-
@tu lazy val Any_getClass: TermSymbol = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
266+
@tu lazy val Any_== : TermSymbol = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
267+
@tu lazy val Any_!= : TermSymbol = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
268+
@tu lazy val Any_equals: TermSymbol = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
269+
@tu lazy val Any_hashCode: TermSymbol = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
270+
@tu lazy val Any_toString: TermSymbol = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
271+
@tu lazy val Any_## : TermSymbol = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
271272
@tu lazy val Any_isInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
272273
@tu lazy val Any_asInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, _.paramRefs(0), Final)
273-
@tu lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact)
274-
@tu lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable)
274+
@tu lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact)
275+
@tu lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable)
275276
// generated by pattern matcher, eliminated by erasure
276277

278+
// def getClass[A >: this.type](): Class[? <: A]
279+
@tu lazy val Any_getClass: TermSymbol =
280+
enterPolyMethod(
281+
AnyClass, nme.getClass_, 1,
282+
pt => MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.upper(pt.paramRefs(0)))),
283+
Final,
284+
bounds = TypeBounds.lower(AnyClass.thisType))
285+
277286
def AnyMethods: List[TermSymbol] = List(Any_==, Any_!=, Any_equals, Any_hashCode,
278287
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf, Any_typeTest, Any_typeCast)
279288

tests/pos/i3495.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
class A
2+
3+
object Test {
4+
val x: A = new A()
5+
6+
def y = x.getClass
7+
8+
val z: Class[? <: A] = y
9+
10+
1.getClass
11+
12+
}
13+

tests/pos/t1107b/T.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ sealed trait Top
22
sealed trait Sub extends Top
33
trait C {
44
private object P extends Sub
5-
def bob() = P.getClass
5+
def bob(): Class[_] = P.getClass
66
def bob2() = O.d(P)
77
}

0 commit comments

Comments
 (0)