@@ -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)
@@ -244,36 +246,32 @@ class Definitions {
244246 * - Have other methods exist only in Object.
245247 * To achieve this, we synthesize all Any and Object methods; Object methods no longer get
246248 * loaded from a classfile.
247- *
248- * There's a remaining question about `getClass`. In Scala2.x `getClass` was handled by compiler magic.
249- * This is deemed too cumersome for Dotty and therefore right now `getClass` gets no special treatment;
250- * it's just a method on `Any` which returns the raw type `java.lang.Class`. An alternative
251- * way to get better `getClass` typing would be to treat `getClass` as a method of a generic
252- * decorator which gets remapped in a later phase to Object#getClass. Then we could give it
253- * the right type without changing the typechecker:
254- *
255- * implicit class AnyGetClass[T](val x: T) extends AnyVal {
256- * def getClass: java.lang.Class[T] = ???
257- * }
258249 */
259250 @ tu lazy val AnyClass : ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass , tpnme.Any , Abstract , Nil ), ensureCtor = false )
260251 def AnyType : TypeRef = AnyClass .typeRef
261252 @ tu lazy val AnyValClass : ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass , tpnme.AnyVal , Abstract , List (AnyClass .typeRef)))
262253 def AnyValType : TypeRef = AnyValClass .typeRef
263254
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 )
255+ @ tu lazy val Any_== : TermSymbol = enterMethod(AnyClass , nme.EQ , methOfAny(BooleanType ), Final )
256+ @ tu lazy val Any_!= : TermSymbol = enterMethod(AnyClass , nme.NE , methOfAny(BooleanType ), Final )
257+ @ tu lazy val Any_equals : TermSymbol = enterMethod(AnyClass , nme.equals_, methOfAny(BooleanType ))
258+ @ tu lazy val Any_hashCode : TermSymbol = enterMethod(AnyClass , nme.hashCode_, MethodType (Nil , IntType ))
259+ @ tu lazy val Any_toString : TermSymbol = enterMethod(AnyClass , nme.toString_, MethodType (Nil , StringType ))
260+ @ tu lazy val Any_## : TermSymbol = enterMethod(AnyClass , nme.HASHHASH , ExprType (IntType ), Final )
271261 @ tu lazy val Any_isInstanceOf : TermSymbol = enterT1ParameterlessMethod(AnyClass , nme.isInstanceOf_, _ => BooleanType , Final )
272262 @ 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 )
263+ @ tu lazy val Any_typeTest : TermSymbol = enterT1ParameterlessMethod(AnyClass , nme.isInstanceOfPM, _ => BooleanType , Final | Synthetic | Artifact )
264+ @ tu lazy val Any_typeCast : TermSymbol = enterT1ParameterlessMethod(AnyClass , nme.asInstanceOfPM, _.paramRefs(0 ), Final | Synthetic | Artifact | StableRealizable )
275265 // generated by pattern matcher, eliminated by erasure
276266
267+ /** def getClass[A >: this.type](): Class[? <: A] */
268+ @ tu lazy val Any_getClass : TermSymbol =
269+ enterPolyMethod(
270+ AnyClass , nme.getClass_, 1 ,
271+ pt => MethodType (Nil , ClassClass .typeRef.appliedTo(TypeBounds .upper(pt.paramRefs(0 )))),
272+ Final ,
273+ bounds = TypeBounds .lower(AnyClass .thisType))
274+
277275 def AnyMethods : List [TermSymbol ] = List (Any_== , Any_!= , Any_equals , Any_hashCode ,
278276 Any_toString , Any_## , Any_getClass , Any_isInstanceOf , Any_asInstanceOf , Any_typeTest , Any_typeCast )
279277
0 commit comments