From 78ebe0ad20f9523bb479afffdb2247447a65ce2c Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 2 Jun 2020 14:46:36 +0200 Subject: [PATCH] Fix #8869: Make $isInstanceOf$ and $asInstanceOf$ semantic names --- compiler/src/dotty/tools/dotc/ast/TreeInfo.scala | 2 +- compiler/src/dotty/tools/dotc/core/Definitions.scala | 4 ++-- compiler/src/dotty/tools/dotc/core/NameKinds.scala | 4 ++++ compiler/src/dotty/tools/dotc/core/NameTags.scala | 1 + compiler/src/dotty/tools/dotc/core/StdNames.scala | 4 ++-- compiler/src/dotty/tools/dotc/transform/Splicer.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Dynamic.scala | 5 +++-- tasty/src/dotty/tools/tasty/TastyFormat.scala | 2 ++ tests/neg/i8869.check | 8 ++++++++ tests/neg/i8869.scala | 2 ++ 10 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 tests/neg/i8869.check create mode 100644 tests/neg/i8869.scala diff --git a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala index 7f4c93d8542e..fbfdb8fcd8fa 100644 --- a/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/compiler/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -881,7 +881,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => tree.select(defn.Any_typeCast).appliedToType(AndType(tree.tpe, tpnn)) def unapply(tree: tpd.TypeApply)(using Context): Option[tpd.Tree] = tree match - case TypeApply(Select(qual: RefTree, nme.asInstanceOfPM), arg :: Nil) => + case TypeApply(Select(qual: RefTree, _), arg :: Nil) if tree.symbol == defn.Any_typeCast => arg.tpe match case AndType(ref, _) if qual.tpe eq ref => Some(qual) case _ => None diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 6dba2ed925c4..a65cfe0efc88 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -276,8 +276,8 @@ class Definitions { @tu lazy val Any_## : TermSymbol = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final) @tu lazy val Any_isInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final) @tu lazy val Any_asInstanceOf: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, _.paramRefs(0), Final) - @tu lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOfPM, _ => BooleanType, Final | Synthetic | Artifact) - @tu lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOfPM, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable) + @tu lazy val Any_typeTest: TermSymbol = enterT1ParameterlessMethod(AnyClass, NameKinds.IsInstanceOf, _ => BooleanType, Final | Synthetic | Artifact) + @tu lazy val Any_typeCast: TermSymbol = enterT1ParameterlessMethod(AnyClass, NameKinds.AsInstanceOf, _.paramRefs(0), Final | Synthetic | Artifact | StableRealizable) // generated by pattern matcher and explicit nulls, eliminated by erasure /** def getClass[A >: this.type](): Class[? <: A] */ diff --git a/compiler/src/dotty/tools/dotc/core/NameKinds.scala b/compiler/src/dotty/tools/dotc/core/NameKinds.scala index f1e0cf68f5dd..94bf48cfafce 100644 --- a/compiler/src/dotty/tools/dotc/core/NameKinds.scala +++ b/compiler/src/dotty/tools/dotc/core/NameKinds.scala @@ -363,6 +363,10 @@ object NameKinds { val ImplMethName: SuffixNameKind = new SuffixNameKind(IMPLMETH, "$") val AdaptedClosureName: SuffixNameKind = new SuffixNameKind(ADAPTEDCLOSURE, "$adapted") { override def definesNewName = true } + val InstanceOf: SuffixNameKind = new SuffixNameKind(INSTANCEOF, "InstanceOf$") + val IsInstanceOf: TermName = InstanceOf(nme.isInstanceOfPM) + val AsInstanceOf: TermName = InstanceOf(nme.asInstanceOfPM) + /** A name together with a signature. Used in Tasty trees. */ object SignedName extends NameKind(SIGNED) { diff --git a/compiler/src/dotty/tools/dotc/core/NameTags.scala b/compiler/src/dotty/tools/dotc/core/NameTags.scala index 299cba7b6948..b6a09ad5aa53 100644 --- a/compiler/src/dotty/tools/dotc/core/NameTags.scala +++ b/compiler/src/dotty/tools/dotc/core/NameTags.scala @@ -36,6 +36,7 @@ object NameTags extends TastyFormat.NameTags { case EXPANDED => "EXPANDED" case EXPANDPREFIX => "EXPANDPREFIX" case TRAITSETTER => "TRAITSETTER" + case INSTANCEOF => "INSTANCEOF" case UNIQUE => "UNIQUE" case DEFAULTGETTER => "DEFAULTGETTER" case OUTERSELECT => "OUTERSELECT" diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index abbe43bf12df..b945f224b055 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -420,7 +420,7 @@ object StdNames { val asType: N = "asType" val asClass: N = "asClass" val asInstanceOf_ : N = "asInstanceOf" - val asInstanceOfPM: N = "$asInstanceOf$" + val asInstanceOfPM: N = "$as" val assert_ : N = "assert" val assume_ : N = "assume" val box: N = "box" @@ -499,7 +499,7 @@ object StdNames { val isDefined: N = "isDefined" val isEmpty: N = "isEmpty" val isInstanceOf_ : N = "isInstanceOf" - val isInstanceOfPM: N = "$isInstanceOf$" + val isInstanceOfPM: N = "$is" val java: N = "java" val key: N = "key" val lang: N = "lang" diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index d33038d2018a..ce6224029bea 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -248,7 +248,7 @@ object Splicer { assert(args.isEmpty) interpretedStaticFieldAccess(fn.symbol) else if (fn.qualifier.symbol.is(Module) && fn.qualifier.symbol.isStatic) - if (fn.name == nme.asInstanceOfPM) + if fn.name == NameKinds.AsInstanceOf then interpretModuleAccess(fn.qualifier.symbol) else { val staticMethodCall = interpretedStaticMethodCall(fn.qualifier.symbol.moduleClass, fn.symbol) diff --git a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala index 50fc5302dafd..1348128cc381 100644 --- a/compiler/src/dotty/tools/dotc/typer/Dynamic.scala +++ b/compiler/src/dotty/tools/dotc/typer/Dynamic.scala @@ -8,6 +8,7 @@ import dotty.tools.dotc.ast.untpd import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Names.{Name, TermName} +import dotty.tools.dotc.core.NameKinds import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.Decorators._ @@ -23,8 +24,8 @@ object Dynamic { } object DynamicUnapply { - def unapply(tree: tpd.Tree): Option[List[tpd.Tree]] = tree match - case TypeApply(Select(qual, name), _) if name == nme.asInstanceOfPM => + def unapply(tree: tpd.Tree)(using Context): Option[List[tpd.Tree]] = tree match + case TypeApply(Select(qual, _), _) if tree.symbol == defn.Any_typeCast => unapply(qual) case Apply(Apply(Select(selectable, fname), Literal(Constant(name)) :: ctag :: Nil), _ :: implicits) if fname == nme.applyDynamic && (name == "unapply" || name == "unapplySeq") => diff --git a/tasty/src/dotty/tools/tasty/TastyFormat.scala b/tasty/src/dotty/tools/tasty/TastyFormat.scala index 96ded6aa7df9..a42149ce7c41 100644 --- a/tasty/src/dotty/tools/tasty/TastyFormat.scala +++ b/tasty/src/dotty/tools/tasty/TastyFormat.scala @@ -263,6 +263,8 @@ object TastyFormat { final val EXPANDPREFIX = 4 // An expansion prefix `$`, // used by Scala-2 for private names. + final val INSTANCEOF = 7 // Type test of cast on Any `$isInsctanceOf$` and `$asInsctanceOf$` + final val UNIQUE = 10 // A unique name `$` where `` // is used only once for each ``. diff --git a/tests/neg/i8869.check b/tests/neg/i8869.check new file mode 100644 index 000000000000..f49a272e979f --- /dev/null +++ b/tests/neg/i8869.check @@ -0,0 +1,8 @@ +-- [E008] Not Found Error: tests/neg/i8869.scala:1:15 ------------------------------------------------------------------ +1 |val test1 = "".$asInstanceOf$[Int] // error + | ^^^^^^^^^^^^^^^^^ + | value $asInstanceOf$ is not a member of String - did you mean ("" : String).asInstanceOf? +-- [E008] Not Found Error: tests/neg/i8869.scala:2:15 ------------------------------------------------------------------ +2 |val test2 = "".$isInstanceOf$[Int] // error + | ^^^^^^^^^^^^^^^^^ + | value $isInstanceOf$ is not a member of String - did you mean ("" : String).isInstanceOf? diff --git a/tests/neg/i8869.scala b/tests/neg/i8869.scala new file mode 100644 index 000000000000..5a418ab4cd44 --- /dev/null +++ b/tests/neg/i8869.scala @@ -0,0 +1,2 @@ +val test1 = "".$asInstanceOf$[Int] // error +val test2 = "".$isInstanceOf$[Int] // error