diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 1c48887b63a..e5c457e218d 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -134,22 +134,17 @@ filter { problemName=MissingMethodProblem }, { - matchName="scala.reflect.api.Mirror.symbolOf" + matchName="scala.reflect.api.Trees#SingletonTypeTreeApi.isLiteral" problemName=MissingMethodProblem }, { - matchName="scala.reflect.api.Mirror.typeOf" + matchName="scala.reflect.api.Trees#SingletonTypeTreeApi.scala$reflect$api$Trees$SingletonTypeTreeApi$$$outer" problemName=MissingMethodProblem }, { - matchName="scala.reflect.api.Mirror.weakTypeOf" + matchName="scala.reflect.api.Mirror.symbolOf" problemName=MissingMethodProblem }, - // see SI-8388 - { - matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticIdentExtractor" - problemName=MissingClassProblem - }, { matchName="scala.reflect.api.Internals#ReificationSupportApi.SyntacticIdent" problemName=MissingMethodProblem @@ -194,6 +189,10 @@ filter { { matchName="scala.collection.immutable.Stream.filteredTail" problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Internals$ReificationSupportApi$SyntacticIdentExtractor" + problemName=MissingClassProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index ec80e7cce95..6a3406fe946 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -368,6 +368,18 @@ filter { { matchName="scala.reflect.io.AbstractFile.filterImpl" problemName=MissingMethodProblem + }, + { + matchName="scala.Predef.inhabitant" + problemName=MissingMethodProblem + }, + { + matchName="scala.SingleInhabitant$" + problemName=MissingClassProblem + }, + { + matchName="scala.SingleInhabitant" + problemName=MissingClassProblem } ] } diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index d007df75e38..0bd131bacb3 100644 --- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala +++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala @@ -52,7 +52,8 @@ trait GenTypes { reifyBuildCall(nme.SuperType, thistpe, supertpe) case tpe @ SingleType(pre, sym) => reifyBuildCall(nme.SingleType, pre, sym) - case tpe @ ConstantType(value) => + // TODO (folone): ConstantType folding? + case tpe @ ConstantType(value) if !tpe.isDeclaredSingleton => mirrorBuildCall(nme.ConstantType, reifyProduct(value)) case tpe @ TypeRef(pre, sym, args) => reifyBuildCall(nme.TypeRef, pre, sym, args) diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 8d810d456e6..ed0b110e315 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -674,11 +674,11 @@ self => def isExprIntro: Boolean = isExprIntroToken(in.token) - def isTypeIntroToken(token: Token): Boolean = token match { + def isTypeIntroToken(token: Token): Boolean = isLiteralToken(token) || (token match { case IDENTIFIER | BACKQUOTED_IDENT | THIS | - SUPER | USCORE | LPAREN | AT => true + SUPER | USCORE | LPAREN | AT | NULL => true case _ => false - } + }) def isStatSeqEnd = in.token == RBRACE || in.token == EOF @@ -861,7 +861,13 @@ self => in.nextToken() if (in.token == RPAREN) { in.nextToken() - atPos(start, accept(ARROW)) { makeFunctionTypeTree(Nil, typ()) } + if (in.token == DOT && lookingAhead { in.token == TYPE }) { + accept(DOT) + accept(TYPE) + atPos(start)(new SingletonTypeTree(Literal(Constant(()))) { override val isLiteral = true }) + } else { + atPos(start, accept(ARROW)) { makeFunctionTypeTree(Nil, typ()) } + } } else { val ts = functionTypes() @@ -1090,6 +1096,14 @@ self => if (in.token == DOT) t = selectors(t, typeOK, in.skipToken()) } else { val tok = in.token + if (tok != BACKQUOTED_IDENT && tok != IDENTIFIER) { + val lit = literal(false) + if (in.token == DOT && lookingAhead { in.token == TYPE }) { + accept(DOT) + accept(TYPE) + } + return atPos(start)(new SingletonTypeTree(lit) { override val isLiteral = true }) + } val name = ident() t = atPos(start) { if (tok == BACKQUOTED_IDENT) Ident(name) updateAttachment BackquotedIdentifierAttachment diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index f471440293a..6ba7188d5fe 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -640,6 +640,7 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { // methods with constant result type get literals as their body // all methods except the primary constructor go into template stat.symbol.tpe match { + // TODO (folone): inlining of defs with literal-based singleton type results? case MethodType(List(), tp @ ConstantType(c)) => defBuf += deriveDefDef(stat)(Literal(c) setPos _.pos setType tp) case _ => diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 3d8b2f02f3a..3fe0224c2ae 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -535,7 +535,8 @@ abstract class Erasure extends AddInterfaces } else bridgingCall } val rhs = member.tpe match { - case MethodType(Nil, ConstantType(c)) => Literal(c) + // TODO (folone): inlining of defs with literal-based singleton type results? + case MethodType(Nil, tp @ ConstantType(c)) if !tp.isDeclaredSingleton => Literal(c) case _ => val sel: Tree = Select(This(root), member) val bridgingCall = (sel /: bridge.paramss)((fun, vparams) => Apply(fun, vparams map Ident)) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala index e9c81f47289..3319ff44b34 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchOptimization.scala @@ -496,6 +496,7 @@ trait MatchOptimization extends MatchTreeMaking with MatchAnalysis { val alternativesSupported = true val canJump = true + // TODO (folone): ConstantType folding? // Constant folding sets the type of a constant tree to `ConstantType(Constant(folded))` // The tree itself can be a literal, an ident, a selection, ... object SwitchablePattern { def unapply(pat: Tree): Option[Tree] = pat.tpe match { diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala index 56ed0ee16ca..e02e5e59d51 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala @@ -14,6 +14,7 @@ import java.lang.ArithmeticException * @author Martin Odersky * @version 1.0 */ +// TODO (folone): ConstantType folding? abstract class ConstantFolder { val global: Global @@ -30,7 +31,7 @@ abstract class ConstantFolder { * the conversion. */ def apply(tree: Tree, pt: Type): Tree = fold(apply(tree), tree.tpe match { - case ConstantType(x) => x convertTo pt + case t @ ConstantType(x) if !t.isDeclaredSingleton => x convertTo pt case _ => null }) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index fb7651ffd6e..3fb529a3174 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -477,6 +477,7 @@ trait Infer extends Checkable { else Some( if (targ.typeSymbol == RepeatedParamClass) targ.baseType(SeqClass) else if (targ.typeSymbol == JavaRepeatedParamClass) targ.baseType(ArrayClass) + else if (targ.isDeclaredSingleton) targ // this infers Foo.type instead of "object Foo" (see also widenIfNecessary) else if (targ.typeSymbol.isModuleClass || tvar.constr.avoidWiden) targ else targ.widen diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index fdff2f3076d..16d64892429 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -25,6 +25,8 @@ trait Namers extends MethodSynthesis { var _lockedCount = 0 def lockedCount = this._lockedCount + private var inferDependentTypes = false + /** Replaces any Idents for which cond is true with fresh TypeTrees(). * Does the same for any trees containing EmptyTrees. */ @@ -838,7 +840,7 @@ trait Namers extends MethodSynthesis { * value should not be widened, so it has a use even in situations * whether it is otherwise redundant (such as in a singleton.) */ - private def widenIfNecessary(sym: Symbol, tpe: Type, pt: Type): Type = { + private def widenIfNecessary(sym: Symbol, tpe: Type, pt: Type, isLiteral: Boolean): Type = { val getter = if (sym.isValue && sym.owner.isClass && sym.isPrivate) sym.getter(sym.owner) @@ -863,7 +865,7 @@ trait Namers extends MethodSynthesis { ) dropIllegalStarTypes( if (shouldWiden) tpe.widen - else if (sym.isFinal) tpe // "final val" allowed to retain constant type + else if (sym.isFinal || (isLiteral && inferDependentTypes)) tpe // "final val" allowed to retain constant type else tpe.deconst ) } @@ -876,7 +878,7 @@ trait Namers extends MethodSynthesis { case _ => defnTyper.computeType(tree.rhs, pt) } - val defnTpe = widenIfNecessary(tree.symbol, rhsTpe, pt) + val defnTpe = widenIfNecessary(tree.symbol, rhsTpe, pt, tree.rhs.isInstanceOf[Literal]) tree.tpt defineType defnTpe setPos tree.pos.focus tree.tpt.tpe } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 8d29d28908e..de9f793bd29 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -504,6 +504,7 @@ trait TypeDiagnostics { && !targets(m) && !(m.name == nme.WILDCARD) // e.g. val _ = foo && !ignoreNames(m.name.toTermName) // serialization methods + // TODO (folone): inlining of defs with literal-based singleton type results? && !isConstantType(m.info.resultType) // subject to constant inlining && !treeTypes.exists(_ contains m) // e.g. val a = new Foo ; new a.Bar ) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 422b940cd34..153a4808e1b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -744,7 +744,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper /** Perform the following adaptations of expression, pattern or type `tree` wrt to * given mode `mode` and given prototype `pt`: * (-1) For expressions with annotated types, let AnnotationCheckers decide what to do - * (0) Convert expressions with constant types to literals (unless in interactive/scaladoc mode) + * (0) Convert expressions with constant types to literals (unless in interactive/scaladoc mode or dealing with a singleton type) * (1) Resolve overloading, unless mode contains FUNmode * (2) Apply parameterless functions * (3) Apply polymorphic types to fresh instances of their type parameters and @@ -996,6 +996,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper if (mode.inPatternMode && isPopulatedPattern) return tree + // TODO (folone): ConstantType folding? val tree1 = constfold(tree, pt) // (10) (11) if (tree1.tpe <:< pt) return adapt(tree1, mode, pt, original) @@ -1096,7 +1097,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } else tree.tpe match { case atp @ AnnotatedType(_, _) if canAdaptAnnotations(tree, this, mode, pt) => // (-1) adaptAnnotations(tree, this, mode, pt) - case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && canAdaptConstantTypeToLiteral => // (0) + case ct @ ConstantType(value) if mode.inNone(TYPEmode | FUNmode) && (ct <:< pt) && canAdaptConstantTypeToLiteral && !ct.isDeclaredSingleton => // (0) adaptConstant(value) case OverloadedType(pre, alts) if !mode.inFunMode => // (1) inferExprAlternative(tree, pt) @@ -3478,6 +3479,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper ErroneousAnnotation } + // TODO (folone): ConstantType folding? /* Calling constfold right here is necessary because some trees (negated * floats and literals in particular) are not yet folded. */ @@ -3541,6 +3543,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper case Typed(t, _) => tree2ConstArg(t, pt) + // TODO (folone): ConstantType folding? case tree => tryConst(tree, pt) } @@ -5107,11 +5110,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } def typedSingletonTypeTree(tree: SingletonTypeTree) = { - val refTyped = - context.withImplicitsDisabled { - typed(tree.ref, MonoQualifierModes | mode.onlyTypePat, AnyRefTpe) - } - + val refTyped = context.withImplicitsDisabled { + typed(tree.ref, MonoQualifierModes | mode.onlyTypePat, AnyClass.tpe) + } + tree setType { + if (tree.isLiteral) refTyped.tpe.resultType.asDeclaredSingleton + else refTyped.tpe.resultType + } if (!refTyped.isErrorTyped) tree setType refTyped.tpe.resultType diff --git a/src/compiler/scala/tools/reflect/FastTrack.scala b/src/compiler/scala/tools/reflect/FastTrack.scala index 64cf3d0847f..c8320a03dee 100644 --- a/src/compiler/scala/tools/reflect/FastTrack.scala +++ b/src/compiler/scala/tools/reflect/FastTrack.scala @@ -24,8 +24,8 @@ class FastTrack[MacrosAndAnalyzer <: Macros with Analyzer](val macros: MacrosAnd private implicit def context2taggers(c0: MacroContext): Taggers { val c: c0.type } = new { val c: c0.type = c0 } with Taggers - private implicit def context2macroimplementations(c0: MacroContext): FormatInterpolator { val c: c0.type } = - new { val c: c0.type = c0 } with FormatInterpolator + private implicit def context2macroimplementations(c0: MacroContext): FormatInterpolator with SingleInhabitantMacro { val c: c0.type } = + new { val c: c0.type = c0 } with FormatInterpolator with SingleInhabitantMacro private implicit def context2quasiquote(c0: MacroContext): QuasiquoteImpls { val c: c0.type } = new { val c: c0.type = c0 } with QuasiquoteImpls private def makeBlackbox(sym: Symbol)(pf: PartialFunction[Applied, MacroContext => Tree]) = @@ -51,6 +51,7 @@ class FastTrack[MacrosAndAnalyzer <: Macros with Analyzer](val macros: MacrosAnd makeBlackbox( materializeWeakTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = false) }, makeBlackbox( materializeTypeTag) { case Applied(_, ttag :: Nil, (u :: _) :: _) => _.materializeTypeTag(u, EmptyTree, ttag.tpe, concrete = true) }, makeBlackbox( ApiUniverseReify) { case Applied(_, ttag :: Nil, (expr :: _) :: _) => c => c.materializeExpr(c.prefix.tree, EmptyTree, expr) }, + makeBlackbox( SingleInhabitant_witness) { case Applied(_, ttag :: Nil, _) => _.materialize(ttag.tpe) }, makeBlackbox( StringContext_f) { case _ => _.interpolate }, makeBlackbox(ReflectRuntimeCurrentMirror) { case _ => c => currentMirror(c).tree }, makeWhitebox( QuasiquoteClass_api_apply) { case _ => _.expandQuasiquote }, diff --git a/src/compiler/scala/tools/reflect/SingleInhabitantMacro.scala b/src/compiler/scala/tools/reflect/SingleInhabitantMacro.scala new file mode 100644 index 00000000000..8c4ed9c741b --- /dev/null +++ b/src/compiler/scala/tools/reflect/SingleInhabitantMacro.scala @@ -0,0 +1,26 @@ +package scala.tools.reflect + +import scala.reflect.macros.runtime.Context + + +trait SingleInhabitantMacro { self: FormatInterpolator => + val c: Context + + import c.universe._ + + def materialize(tpe: Type): Tree = { + val value = tpe match { + case ConstantType(const) => Literal(const) + case SingleType(pre, sym) => Select(TypeTree(pre), sym) + case _ => + c.abort(c.enclosingPosition, tpe + " is not a singleton type!") + } + Apply( + TypeApply( + Select(reify(SingleInhabitant).tree, newTermName("apply")), + TypeTree(tpe) :: Nil + ), + value :: Nil + ) + } +} diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 7f717aa6e4c..0706cf4635c 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -125,6 +125,8 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef { // @deprecated("This notion doesn't have a corresponding concept in 2.10, because scala.reflect.runtime.universe.TypeTag can capture arbitrary types. Use type tags instead of manifests, and there will be no need in opt manifests.", "2.10.0") def optManifest[T](implicit m: OptManifest[T]) = m + def inhabitant[A](implicit h: SingleInhabitant[A]) = h.a + // Minor variations on identity functions def identity[A](x: A): A = x // @see `conforms` for the implicit version @inline def implicitly[T](implicit e: T) = e // for summoning implicit values from the nether world -- TODO: when dependent method types are on by default, give this result type `e.type`, so that inliner has better chance of knowing which method to inline in calls like `implicitly[MatchingStrategy[Option]].zero` diff --git a/src/library/scala/SingleInhabitant.scala b/src/library/scala/SingleInhabitant.scala new file mode 100644 index 00000000000..f2b5a21f73d --- /dev/null +++ b/src/library/scala/SingleInhabitant.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +import scala.language.experimental.macros + + +case class SingleInhabitant[A](a: A) + +object SingleInhabitant { + implicit def witness[A]: SingleInhabitant[A] = macro ??? +} diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index ff8926651b9..3e49f41001a 100644 --- a/src/reflect/scala/reflect/api/Trees.scala +++ b/src/reflect/scala/reflect/api/Trees.scala @@ -1872,6 +1872,7 @@ trait Trees { self: Universe => trait SingletonTypeTreeApi extends TypTreeApi { this: SingletonTypeTree => /** The underlying reference. */ def ref: Tree + def isLiteral = false // TODO: какое-то стремное имя как на мой вкус } /** Type selection # , eliminated by RefCheck diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index f6995dd5dea..cba1d8f560a 100644 --- a/src/reflect/scala/reflect/api/Types.scala +++ b/src/reflect/scala/reflect/api/Types.scala @@ -528,8 +528,8 @@ trait Types { */ def supertpe: Type } - /** The `ConstantType` type is not directly written in user programs, but arises as the type of a constant. - * The REPL expresses constant types like `Int(11)`. Here are some constants with their types: + /** The `ConstantType` type is not directly written in user programs (now it is), but arises as the type of a constant. + * The REPL expresses constant types like `11.type`. Here are some constants with their types: * {{{ * 1 ConstantType(Constant(1)) * "abc" ConstantType(Constant("abc")) diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 02578e20386..52f15519a7b 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -504,6 +504,8 @@ trait Definitions extends api.StandardDefinitions { lazy val StringContextClass = requiredClass[scala.StringContext] + lazy val SingleInhabitantModule = requiredModule[scala.SingleInhabitant.type] + // SI-8392 a reflection universe on classpath may not have // quasiquotes, if e.g. crosstyping with -Xsource on lazy val QuasiquoteClass = if (ApiUniverseClass != NoSymbol) getMemberIfDefined(ApiUniverseClass, tpnme.Quasiquote) else NoSymbol @@ -1411,6 +1413,8 @@ trait Definitions extends api.StandardDefinitions { lazy val StringContext_f = getMemberMethod(StringContextClass, nme.f) + lazy val SingleInhabitant_witness = getMemberMethod(SingleInhabitantModule, nme.witness) + lazy val ArrowAssocClass = getMemberClass(PredefModule, TypeName("ArrowAssoc")) // SI-5731 def isArrowAssoc(sym: Symbol) = sym.owner == ArrowAssocClass diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala index 6848c357c5e..49472fb3540 100644 --- a/src/reflect/scala/reflect/internal/StdNames.scala +++ b/src/reflect/scala/reflect/internal/StdNames.scala @@ -776,6 +776,7 @@ trait StdNames { val values : NameType = "values" val wait_ : NameType = "wait" val withFilter: NameType = "withFilter" + val witness: NameType = "witness" val zero: NameType = "zero" // quasiquote interpolators: diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index f26315c5389..1c9a8ac9a74 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -258,6 +258,12 @@ trait Types /** The base class for all types */ abstract class Type extends TypeApiImpl with Annotatable[Type] { + var isDeclaredSingleton: Boolean = false + def asDeclaredSingleton: this.type = { + isDeclaredSingleton = true + this + } + /** Types for which asSeenFrom always is the identity, no matter what * prefix or owner. */ @@ -1817,9 +1823,10 @@ trait Types override def underlying: Type = value.tpe assert(underlying.typeSymbol != UnitClass) override def isTrivial: Boolean = true - override def deconst: Type = underlying.deconst - override def safeToString: String = - underlying.toString + "(" + value.escapedStringValue + ")" + override def deconst: Type = + if (isDeclaredSingleton) this + else underlying + override def safeToString: String = value.escapedStringValue + ".type" override def kind = "ConstantType" } @@ -2421,7 +2428,7 @@ trait Types if (isTrivial || phase.erasedTypes) resultType else if (/*isDependentMethodType &&*/ sameLength(actuals, params)) { val idm = new InstantiateDependentMap(params, actuals) - val res = idm(resultType) + val res = idm(resultType).deconst existentialAbstraction(idm.existentialsNeeded, res) } else existentialAbstraction(params, resultType) diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index dcd262c288c..88415bd283d 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -303,6 +303,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => definitions.WhiteboxContextClass definitions.MacroImplAnnotation definitions.StringContextClass + definitions.SingleInhabitantModule definitions.QuasiquoteClass definitions.QuasiquoteClass_api definitions.QuasiquoteClass_api_apply diff --git a/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index d03edb638c7..7b2a11fdbce 100644 --- a/test/files/jvm/interpreter.check +++ b/test/files/jvm/interpreter.check @@ -33,7 +33,7 @@ four: anotherint = 4 scala> val bogus: anotherint = "hello" :8: error: type mismatch; - found : String("hello") + found : "hello".type (with underlying type String) required: anotherint (which expands to) Int val bogus: anotherint = "hello" diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check index 2cb2e7f095e..44ecaef7104 100644 --- a/test/files/neg/applydynamic_sip.check +++ b/test/files/neg/applydynamic_sip.check @@ -17,21 +17,21 @@ applydynamic_sip.scala:9: error: not found: value arg2 qual.sel(arg, arg2 = "a2", a2: _*) ^ applydynamic_sip.scala:18: error: type mismatch; - found : String("sel") + found : "sel".type (with underlying type String) required: Int error after rewriting to Test.this.bad1.selectDynamic("sel") possible cause: maybe a wrong Dynamic method signature? bad1.sel ^ applydynamic_sip.scala:19: error: type mismatch; - found : String("sel") + found : "sel".type (with underlying type String) required: Int error after rewriting to Test.this.bad1.applyDynamic("sel") possible cause: maybe a wrong Dynamic method signature? bad1.sel(1) ^ applydynamic_sip.scala:20: error: type mismatch; - found : String("sel") + found : "sel".type (with underlying type String) required: Int error after rewriting to Test.this.bad1.applyDynamicNamed("sel") possible cause: maybe a wrong Dynamic method signature? @@ -41,7 +41,7 @@ applydynamic_sip.scala:20: error: reassignment to val bad1.sel(a = 1) ^ applydynamic_sip.scala:21: error: type mismatch; - found : String("sel") + found : "sel".type (with underlying type String) required: Int error after rewriting to Test.this.bad1.updateDynamic("sel") possible cause: maybe a wrong Dynamic method signature? diff --git a/test/files/neg/class-of-double-targs.check b/test/files/neg/class-of-double-targs.check index f7e2094f977..5fe89bcb98f 100644 --- a/test/files/neg/class-of-double-targs.check +++ b/test/files/neg/class-of-double-targs.check @@ -1,4 +1,4 @@ -class-of-double-targs.scala:2: error: expression of type Class[Int](classOf[scala.Int]) does not take type parameters. +class-of-double-targs.scala:2: error: expression of type classOf[scala.Int].type does not take type parameters. classOf[Int][Int] ^ one error found diff --git a/test/files/neg/constrs.check b/test/files/neg/constrs.check index 4f4a12bc13e..5f3285bdc94 100644 --- a/test/files/neg/constrs.check +++ b/test/files/neg/constrs.check @@ -11,7 +11,7 @@ constrs.scala:12: error: called constructor's definition must precede calling co def this(x: Boolean) = this(x) ^ constrs.scala:16: error: type mismatch; - found : Int(1) + found : 1.type (with underlying type Int) required: a def this() = this(1) ^ diff --git a/test/files/neg/divergent-implicit.check b/test/files/neg/divergent-implicit.check index d4a3ddfc71c..8e291336cb8 100644 --- a/test/files/neg/divergent-implicit.check +++ b/test/files/neg/divergent-implicit.check @@ -1,5 +1,5 @@ divergent-implicit.scala:4: error: type mismatch; - found : Int(1) + found : 1.type (with underlying type Int) required: String val x1: String = 1 ^ diff --git a/test/files/neg/gadts1.check b/test/files/neg/gadts1.check index 9b7ea5556a8..5562815bd4a 100644 --- a/test/files/neg/gadts1.check +++ b/test/files/neg/gadts1.check @@ -2,7 +2,7 @@ gadts1.scala:20: error: Test.Cell[a] does not take parameters case Cell[a](x: Int) => c.x = 5 ^ gadts1.scala:20: error: type mismatch; - found : Int(5) + found : 5.type (with underlying type Int) required: a case Cell[a](x: Int) => c.x = 5 ^ diff --git a/test/files/neg/gadts2.check b/test/files/neg/gadts2.check index dc21f3f52c8..323333a1d62 100644 --- a/test/files/neg/gadts2.check +++ b/test/files/neg/gadts2.check @@ -1,5 +1,5 @@ gadts2.scala:7: error: type mismatch; - found : String("abc") + found : "abc".type (with underlying type String) required: B (s1: Super[Any]) match { case Sub(f) => f("abc") } ^ diff --git a/test/files/neg/implicit-shadow.check b/test/files/neg/implicit-shadow.check index 042fca867a0..11470a3786d 100644 --- a/test/files/neg/implicit-shadow.check +++ b/test/files/neg/implicit-shadow.check @@ -1,4 +1,4 @@ -implicit-shadow.scala:4: is not a valid implicit value for Int(1) => ?{def isEmpty: ?} because: +implicit-shadow.scala:4: is not a valid implicit value for 1.type => ?{def isEmpty: ?} because: reference to i2s is ambiguous; it is imported twice in the same scope by import C._ diff --git a/test/files/neg/logImplicits.check b/test/files/neg/logImplicits.check index 270882b71a0..e3229603072 100644 --- a/test/files/neg/logImplicits.check +++ b/test/files/neg/logImplicits.check @@ -1,13 +1,13 @@ logImplicits.scala:2: applied implicit conversion from xs.type to ?{def size: ?} = implicit def byteArrayOps(xs: Array[Byte]): scala.collection.mutable.ArrayOps[Byte] def f(xs: Array[Byte]) = xs.size ^ -logImplicits.scala:7: applied implicit conversion from String("abc") to ?{def map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps +logImplicits.scala:7: applied implicit conversion from "abc".type to ?{def map: ?} = implicit def augmentString(x: String): scala.collection.immutable.StringOps def f = "abc" map (_ + 1) ^ -logImplicits.scala:15: inferred view from String("abc") to Int = C.this.convert:(p: String("abc"))Int +logImplicits.scala:15: inferred view from "abc".type to Int = C.this.convert:(p: "abc".type)Int math.max(122, x: Int) ^ -logImplicits.scala:19: applied implicit conversion from Int(1) to ?{def ->: ?} = implicit def ArrowAssoc[A](self: A): ArrowAssoc[A] +logImplicits.scala:19: applied implicit conversion from 1.type to ?{def ->: ?} = implicit def ArrowAssoc[A](self: A): ArrowAssoc[A] def f = (1 -> 2) + "c" ^ logImplicits.scala:19: applied implicit conversion from (Int, Int) to ?{def +: ?} = implicit def any2stringadd[A](self: A): any2stringadd[A] diff --git a/test/files/neg/macro-invalidret.check b/test/files/neg/macro-invalidret.check index 568cc7c570d..99f29e57ce7 100644 --- a/test/files/neg/macro-invalidret.check +++ b/test/files/neg/macro-invalidret.check @@ -20,7 +20,7 @@ Macros_Test_2.scala:7: warning: macro defs must have explicitly specified return ^ Macros_Test_2.scala:14: error: exception during macro expansion: scala.NotImplementedError: an implementation is missing - at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225) + at scala.Predef$.$qmark$qmark$qmark(Predef.scala:227) at Impls$.foo3(Impls_1.scala:7) foo3 diff --git a/test/files/neg/macro-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check index 4c1115418b5..28873f8bfe2 100644 --- a/test/files/neg/macro-invalidusage-badargs.check +++ b/test/files/neg/macro-invalidusage-badargs.check @@ -1,5 +1,5 @@ Macros_Test_2.scala:5: error: type mismatch; - found : String("42") + found : "42".type (with underlying type String) required: Int foo("42") ^ diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check index 20ddd55f1fd..eba171c0864 100644 --- a/test/files/neg/names-defaults-neg.check +++ b/test/files/neg/names-defaults-neg.check @@ -3,12 +3,12 @@ Unspecified value parameter b. val fac = Fact(1)(2, 3) ^ names-defaults-neg.scala:5: error: type mismatch; - found : String("#") + found : "#".type (with underlying type String) required: Int test1(b = 2, a = "#") ^ names-defaults-neg.scala:5: error: type mismatch; - found : Int(2) + found : 2.type (with underlying type Int) required: String test1(b = 2, a = "#") ^ diff --git a/test/files/neg/nested-fn-print.check b/test/files/neg/nested-fn-print.check index ea278554d42..6ddb60d7e08 100644 --- a/test/files/neg/nested-fn-print.check +++ b/test/files/neg/nested-fn-print.check @@ -3,17 +3,17 @@ nested-fn-print.scala:4: error: only classes can have declared but undefined mem var x3: Int => Double ^ nested-fn-print.scala:7: error: type mismatch; - found : String("a") + found : "a".type (with underlying type String) required: Int => (Float => Double) x1 = "a" ^ nested-fn-print.scala:8: error: type mismatch; - found : String("b") + found : "b".type (with underlying type String) required: (Int => Float) => Double x2 = "b" ^ nested-fn-print.scala:9: error: type mismatch; - found : String("c") + found : "c".type (with underlying type String) required: Int => Double x3 = "c" ^ diff --git a/test/files/neg/no-predef.check b/test/files/neg/no-predef.check index a63d8c5ba5c..5432e17c384 100644 --- a/test/files/neg/no-predef.check +++ b/test/files/neg/no-predef.check @@ -1,5 +1,5 @@ no-predef.scala:2: error: type mismatch; - found : scala.Long(5L) + found : 5L.type (with underlying type scala.Long) required: java.lang.Long def f1 = 5L: java.lang.Long ^ diff --git a/test/files/neg/quasiquotes-syntax-error-position.check b/test/files/neg/quasiquotes-syntax-error-position.check index 9fd6ce04176..dcd6d6c5326 100644 --- a/test/files/neg/quasiquotes-syntax-error-position.check +++ b/test/files/neg/quasiquotes-syntax-error-position.check @@ -20,7 +20,7 @@ quasiquotes-syntax-error-position.scala:11: error: case classes without a parame use either case objects or case classes with an explicit `()' as a parameter list. q"case class A" ^ -quasiquotes-syntax-error-position.scala:12: error: identifier expected but ']' found. +quasiquotes-syntax-error-position.scala:12: error: illegal literal tq"$t => $t $t]" ^ quasiquotes-syntax-error-position.scala:13: error: end of quote expected but 'case' found. diff --git a/test/files/neg/reflection-names-neg.check b/test/files/neg/reflection-names-neg.check index f941ec8dc1b..91dbc99f66b 100644 --- a/test/files/neg/reflection-names-neg.check +++ b/test/files/neg/reflection-names-neg.check @@ -1,10 +1,10 @@ reflection-names-neg.scala:5: error: type mismatch; - found : String("abc") + found : "abc".type (with underlying type String) required: reflect.runtime.universe.Name Note that implicit conversions are not applicable because they are ambiguous: both method stringToTermName in trait Names of type (s: String)reflect.runtime.universe.TermName and method stringToTypeName in trait Names of type (s: String)reflect.runtime.universe.TypeName - are possible conversion functions from String("abc") to reflect.runtime.universe.Name + are possible conversion functions from "abc".type to reflect.runtime.universe.Name val x2 = ("abc": Name) drop 1 // error ^ reflection-names-neg.scala:5: error: value drop is not a member of reflect.runtime.universe.Name diff --git a/test/files/neg/saferJavaConversions.check b/test/files/neg/saferJavaConversions.check index 0e53d2c4379..2649fa3334c 100644 --- a/test/files/neg/saferJavaConversions.check +++ b/test/files/neg/saferJavaConversions.check @@ -1,5 +1,5 @@ saferJavaConversions.scala:13: error: type mismatch; - found : String("a") + found : "a".type (with underlying type String) required: Foo val v = map.get("a") // now this is a type error ^ diff --git a/test/files/neg/sensitive2.check b/test/files/neg/sensitive2.check index 19152fe1884..1eb6c7d4ba6 100644 --- a/test/files/neg/sensitive2.check +++ b/test/files/neg/sensitive2.check @@ -1,10 +1,10 @@ sensitive2.scala:6: error: type mismatch; - found : String("abc") + found : "abc".type (with underlying type String) required: Test.Foo[_] Note that implicit conversions are not applicable because they are ambiguous: both method foo1 in object Test of type [A](a: A)Test.Foo[A] and method foo2 in object Test of type (a: Any)Test.Foo[String] - are possible conversion functions from String("abc") to Test.Foo[_] + are possible conversion functions from "abc".type to Test.Foo[_] val a: Foo[_] = "abc" ^ one error found diff --git a/test/files/neg/t0590.check b/test/files/neg/t0590.check index a3ef70c6cdf..16e4d989ae1 100644 --- a/test/files/neg/t0590.check +++ b/test/files/neg/t0590.check @@ -1,5 +1,5 @@ t0590.scala:2: error: type mismatch; - found : Null(null) + found : null.type (with underlying type Null) required: T implicit def foo[T] : T = null ^ diff --git a/test/files/neg/t1041.check b/test/files/neg/t1041.check index d82f3a8586b..161add5d248 100644 --- a/test/files/neg/t1041.check +++ b/test/files/neg/t1041.check @@ -1,5 +1,5 @@ t1041.scala:3: error: type mismatch; - found : Int(1) + found : 1.type (with underlying type Int) required: List[Int] case 1 => 4 ^ diff --git a/test/files/neg/t2139.check b/test/files/neg/t2139.check index e26f2907617..085243143cc 100644 --- a/test/files/neg/t2139.check +++ b/test/files/neg/t2139.check @@ -1,5 +1,5 @@ t2139.scala:13: error: type mismatch; - found : Int(4) + found : 4.type (with underlying type Int) required: Nothing val z:Int=(u.f _)(4) ^ diff --git a/test/files/neg/t2801.check b/test/files/neg/t2801.check index 25320de5bc4..b57e9255f15 100644 --- a/test/files/neg/t2801.check +++ b/test/files/neg/t2801.check @@ -1,5 +1,5 @@ t2801.scala:2: error: type mismatch; - found : Null(null) + found : null.type (with underlying type Null) required: A def f[A <: AnyRef] = { val a: A = null ; a } ^ diff --git a/test/files/neg/t3006.check b/test/files/neg/t3006.check index 2447eebc9cb..578d93ed131 100644 --- a/test/files/neg/t3006.check +++ b/test/files/neg/t3006.check @@ -1,5 +1,5 @@ t3006.scala:8: error: type mismatch; - found : String("H") + found : "H".type (with underlying type String) required: Int println(A(3) + "H") ^ diff --git a/test/files/neg/t3481.check b/test/files/neg/t3481.check index debe07275be..fa22668c965 100644 --- a/test/files/neg/t3481.check +++ b/test/files/neg/t3481.check @@ -1,5 +1,5 @@ t3481.scala:5: error: type mismatch; - found : String("hello") + found : "hello".type (with underlying type String) required: _$1 f[A[Int]]("hello") ^ @@ -10,18 +10,18 @@ t3481.scala:11: error: type mismatch; def f[T <: B[_]](a: T#T, b: T) = b.m(a) ^ t3481.scala:12: error: type mismatch; - found : String("Hello") + found : "Hello".type (with underlying type String) required: _$2 f("Hello", new B[Int]) ^ t3481.scala:18: error: type mismatch; - found : String("Hello") + found : "Hello".type (with underlying type String) required: t3481.ex3.b.T2 (which expands to) _$3 b.m("Hello") ^ t3481.scala:25: error: type mismatch; - found : String("Hello") + found : "Hello".type (with underlying type String) required: t3481.ex4.Test.b.T2 (which expands to) _$4 b.m("Hello") diff --git a/test/files/neg/t391.check b/test/files/neg/t391.check index 879d9af71fe..6095fb2b312 100644 --- a/test/files/neg/t391.check +++ b/test/files/neg/t391.check @@ -4,10 +4,13 @@ t391.scala:2: error: identifier expected but 'def' found. t391.scala:4: error: ':' expected but '}' found. } ^ +t391.scala:6: error: '.' expected but ';' found. +class E(def x: Int); // the "def x" is illegal +^ t391.scala:6: error: identifier expected but 'def' found. class E(def x: Int); // the "def x" is illegal ^ t391.scala:6: error: ':' expected but eof found. class E(def x: Int); // the "def x" is illegal ^ -four errors found +5 errors found diff --git a/test/files/neg/t3971.check b/test/files/neg/t3971.check index 8685119876e..89a0afb02bb 100644 --- a/test/files/neg/t3971.check +++ b/test/files/neg/t3971.check @@ -4,7 +4,7 @@ t3971.scala:6: error: type mismatch; f(g("abc")("def")) // g returns Int, needs String ^ t3971.scala:7: error: type mismatch; - found : Int(5) + found : 5.type (with underlying type Int) required: String f(5) ^ diff --git a/test/files/neg/t3995.check b/test/files/neg/t3995.check index 00ecf4ca5b6..91f8ab6c730 100644 --- a/test/files/neg/t3995.check +++ b/test/files/neg/t3995.check @@ -1,5 +1,5 @@ t3995.scala:31: error: type mismatch; - found : String("") + found : "".type (with underlying type String) required: _1.F0 where val _1: Lift (new Lift).apply("") ^ diff --git a/test/files/neg/t4818.check b/test/files/neg/t4818.check index a5e15e456b8..cdf011df54a 100644 --- a/test/files/neg/t4818.check +++ b/test/files/neg/t4818.check @@ -1,5 +1,5 @@ t4818.scala:4: error: type mismatch; - found : Int(5) + found : 5.type (with underlying type Int) required: Nothing def f(x: Any) = x match { case Fn(f) => f(5) } ^ diff --git a/test/files/neg/t5106.check b/test/files/neg/t5106.check index ac16041cf7a..dff4443ca4d 100644 --- a/test/files/neg/t5106.check +++ b/test/files/neg/t5106.check @@ -1,10 +1,10 @@ t5106.scala:3: error: type mismatch; - found : Int(4) + found : 4.type (with underlying type Int) required: String val (n, l): (String, Int) = (4, "") ^ t5106.scala:3: error: type mismatch; - found : String("") + found : "".type (with underlying type String) required: Int val (n, l): (String, Int) = (4, "") ^ diff --git a/test/files/neg/t5376.check b/test/files/neg/t5376.check index 0376163c35e..eab8ee4fc9e 100644 --- a/test/files/neg/t5376.check +++ b/test/files/neg/t5376.check @@ -1,10 +1,10 @@ t5376.scala:12: error: type mismatch; - found : String("a") + found : "a".type (with underlying type String) required: Int "a": Int ^ t5376.scala:22: error: type mismatch; - found : String("a") + found : "a".type (with underlying type String) required: Int "a": Int ^ diff --git a/test/files/neg/t5892.check b/test/files/neg/t5892.check index 839bf9de230..dbed15acfc7 100644 --- a/test/files/neg/t5892.check +++ b/test/files/neg/t5892.check @@ -1,5 +1,5 @@ t5892.scala:5: error: type mismatch; - found : Boolean(false) + found : false.type (with underlying type Boolean) required: String class C[@annot(false) X] { ^ @@ -7,7 +7,7 @@ t5892.scala:9: error: not found: value b2s class D[@annot(b2s(false)) X] { ^ t5892.scala:13: error: type mismatch; - found : Boolean(false) + found : false.type (with underlying type Boolean) required: String @annot(false) class E { ^ diff --git a/test/files/neg/t6680a.check b/test/files/neg/t6680a.check index 03e4df10c12..f11983a6630 100644 --- a/test/files/neg/t6680a.check +++ b/test/files/neg/t6680a.check @@ -1,10 +1,10 @@ t6680a.scala:10: error: type mismatch; - found : String("abc") + found : "abc".type (with underlying type String) required: A y.x = "abc" ^ t6680a.scala:17: error: type mismatch; - found : String("") + found : "".type (with underlying type String) required: A case class C[A](f:A=>A);def f(x:Any)=x match { case C(f)=>f("") };f(C[Int](x=>x)) ^ diff --git a/test/files/neg/t7509.check b/test/files/neg/t7509.check index eaa6303cf52..794f5878a5b 100644 --- a/test/files/neg/t7509.check +++ b/test/files/neg/t7509.check @@ -2,7 +2,7 @@ t7509.scala:3: error: inferred type arguments [Int] do not conform to method cra crash(42) ^ t7509.scala:3: error: type mismatch; - found : Int(42) + found : 42.type (with underlying type Int) required: R crash(42) ^ diff --git a/test/files/neg/t7519.check b/test/files/neg/t7519.check index df54abaa3e2..f4249e36c7b 100644 --- a/test/files/neg/t7519.check +++ b/test/files/neg/t7519.check @@ -1,10 +1,10 @@ t7519.scala:5: error: type mismatch; - found : Int(0) + found : 0.type (with underlying type Int) required: String locally(0 : String) // was: "value conversion is not a member of C.this.C" ^ t7519.scala:15: error: type mismatch; - found : Int(0) + found : 0.type (with underlying type Int) required: String locally(0 : String) // was: "value conversion is not a member of U" ^ diff --git a/test/files/neg/t8015-ffa.check b/test/files/neg/t8015-ffa.check index 0f28be7fe7b..a619dadd797 100644 --- a/test/files/neg/t8015-ffa.check +++ b/test/files/neg/t8015-ffa.check @@ -1,5 +1,5 @@ t8015-ffa.scala:7: error: type mismatch; - found : String("3") + found : "3".type (with underlying type String) required: Int val i: Int = "3" // error line 7 (was 8) ^ diff --git a/test/files/neg/t8325.check b/test/files/neg/t8325.check index 175a0db4151..b4a298880f7 100644 --- a/test/files/neg/t8325.check +++ b/test/files/neg/t8325.check @@ -5,7 +5,7 @@ t8325.scala:7: error: *-parameter must come last def h(is: Int * String *, s: String) = ??? ^ t8325.scala:10: error: type mismatch; - found : Int(5) + found : 5.type (with underlying type Int) required: Int* def j(is: Int* = 5) = ??? ^ diff --git a/test/files/neg/t846.check b/test/files/neg/t846.check index 242a8001ff3..05f189407ba 100644 --- a/test/files/neg/t846.check +++ b/test/files/neg/t846.check @@ -1,5 +1,5 @@ t846.scala:9: error: type mismatch; - found : Null(null) + found : null.type (with underlying type Null) required: B if (a != null) f(a) else null ^ diff --git a/test/files/neg/t909.check b/test/files/neg/t909.check index e7a42bd246b..ce704f37f36 100644 --- a/test/files/neg/t909.check +++ b/test/files/neg/t909.check @@ -1,5 +1,5 @@ t909.scala:6: error: type mismatch; - found : String("Hello") + found : "Hello".type (with underlying type String) required: Int case Foo("Hello") => ^ diff --git a/test/files/presentation/t5708.check b/test/files/presentation/t5708.check index 4b33893e980..ea3eb248478 100644 --- a/test/files/presentation/t5708.check +++ b/test/files/presentation/t5708.check @@ -34,7 +34,7 @@ final def synchronized[T0](x$1: T0): T0 final def wait(): Unit final def wait(x$1: Long): Unit final def wait(x$1: Long,x$2: Int): Unit -final private[this] val CONST_STRING: String("constant") +final private[this] val CONST_STRING: "constant".type lazy private[this] var foo: Int private[package test] def pkgPrivateM: String private[this] val pkgPrivateV: String diff --git a/test/files/run/42.type.check b/test/files/run/42.type.check new file mode 100644 index 00000000000..0bf4d0c457c --- /dev/null +++ b/test/files/run/42.type.check @@ -0,0 +1,7 @@ +2 +(2,0,1) +Residue(9) +(true,true) +(true,true) +got 1 +got PANDA! diff --git a/test/files/run/42.type.scala b/test/files/run/42.type.scala new file mode 100644 index 00000000000..b988e1ec95f --- /dev/null +++ b/test/files/run/42.type.scala @@ -0,0 +1,147 @@ +object Test { + // type _1 = + // Succ[_1] = _2 + // etc... + + type _1 = 1.type + // (1+1).type + /* + scala> type _2 = (1+1).type + :1: error: '.' expected but identifier found. + type _2 = (1+1).type + ^ + */ + + type Unt = ().type + + type Null = null.type + + var x: 3.type = 3 + /* + scala> x = 42 + :8: error: type mismatch; + found : 42.type (with underlying type Int) + required: 3.type + x = 42 + ^ + */ + + val y: 5.type = 5 + + val z: 7 = 7 + + final val `( •_•) ( •_•)>⌐■-■ (⌐■_■)` = -10 + val unicode: `( •_•) ( •_•)>⌐■-■ (⌐■_■)`.type = `( •_•) ( •_•)>⌐■-■ (⌐■_■)` + + def g(x: Int) = x match { + case _: y.type => 0 + case _: 7.type => 1 + case _ => 2 + } + + trait Succ[T] { + type Out + def apply(x: T): Out + } + + implicit object One extends Succ[1.type] { + type Out = 2.type + def apply(x: 1.type) = 2 + } + + def f[T](x: T)(implicit succ: Succ[T]) = succ(x) + + case class Residue[N <: Int : SingleInhabitant](n: Long) { lhs => + def +(rhs: Residue[N]): Residue[N] = + Residue((lhs.n + rhs.n) % inhabitant[N]) + } + + class Ranged[From <: Int : SingleInhabitant, To <: Int : SingleInhabitant] { + def value = { + val rnd = new scala.util.Random + val from = inhabitant[From] + val to = inhabitant[To] + (from + rnd.nextInt(to - from + 1)) + } + } + + class IntegralRanged[N, From <: N : SingleInhabitant, To <: N : SingleInhabitant](implicit ev: Integral[N]) { + def value = { + val from = ev.toInt(inhabitant[From]) + val to = ev.toInt(inhabitant[To]) + val rnd = from + scala.util.Random.nextInt(to - from) + ev.fromInt(rnd) + } + } + + val range = new Ranged[10.type, 20.type] + val integral = new IntegralRanged[Int, 1.type, 50.type] + + def noisyIdentity(x: Any): x.type = { + println("got " + x) + x + } + + def main(args: Array[String]): Unit = { + println(f(1)) + // println(f(5)) + println((g(1), g(5), g(7))) + println(Residue[13.type](15) + Residue[13.type](20)) + println(range.value <= 20, range.value >= 10) + println(integral.value <= 50, integral.value >= 1) + + noisyIdentity(1) + noisyIdentity("PANDA!") + } + + // Inlining functions with singleton result type + /* +scala> def ok(): 7.type = { + | println("PANDA!") + | 7 + | } +ok: ()7.type + +scala> ok() +res0: 7.type = 7 + +// Expected: +scala> ok() +PANDA! +res0: 7.type = 7 + */ + + // Parser problem: + /* +scala> val t: -1.type = -1 +:1: error: ';' expected but integer literal found. + val t: -1.type = -1 + ^ + +scala> final val t = -1 +t: -1.type = -1 + */ + + // Not sure if this is a problem (I guess it is a special case of (2+3).type): + /* +scala> def test: 5.type = { + | val t = 3 + | val p = 2 + | t + p + | } +:10: error: type mismatch; + found : Int + required: 5.type + t + p + ^ + */ + + // Recursive weirdness (ConstantType folding?): + /* +scala> val t: 1.type = t +:9: warning: value t does nothing other than call itself recursively + val t: 1.type = t + ^ +t: 1.type = 1 + */ +} diff --git a/test/files/run/analyzerPlugins.check b/test/files/run/analyzerPlugins.check index 9803465ddc2..68a49acccef 100644 --- a/test/files/run/analyzerPlugins.check +++ b/test/files/run/analyzerPlugins.check @@ -1,13 +1,13 @@ adaptBoundsToAnnots(List( <: Int), List(type T), List(Int @testAnn)) [2] +annotationsConform(1.type @testAnn, Int) [1] +annotationsConform(1.type, Int @testAnn) [1] annotationsConform(Boolean @testAnn, Boolean) [1] -annotationsConform(Boolean(false), Boolean @testAnn) [1] annotationsConform(Int @testAnn, ?A) [1] annotationsConform(Int @testAnn, Any) [1] annotationsConform(Int @testAnn, Int) [2] -annotationsConform(Int(1) @testAnn, Int) [1] -annotationsConform(Int(1), Int @testAnn) [1] annotationsConform(Nothing, Int @testAnn) [2] annotationsConform(String @testAnn, String) [2] +annotationsConform(false.type, Boolean @testAnn) [1] canAdaptAnnotations(Trees$Ident, String) [1] canAdaptAnnotations(Trees$Select, ?) [1] canAdaptAnnotations(Trees$Select, Boolean @testAnn) [1] @@ -93,6 +93,13 @@ pluginsTypeSigAccessor(value x) [1] pluginsTypeSigAccessor(value y) [1] pluginsTypeSigAccessor(variable count) [2] pluginsTyped( <: Int, Trees$TypeBoundsTree) [2] +pluginsTyped("".type, Trees$Literal) [2] +pluginsTyped("huhu".type, Trees$Literal) [1] +pluginsTyped("str".type @testAnn, Trees$Typed) [1] +pluginsTyped("str".type, Trees$Literal) [1] +pluginsTyped("str".type, Trees$Typed) [1] +pluginsTyped("two".type, Trees$Literal) [2] +pluginsTyped('c'.type, Trees$Literal) [2] pluginsTyped(()Object, Trees$Select) [1] pluginsTyped(()String, Trees$Ident) [1] pluginsTyped(()String, Trees$TypeApply) [1] @@ -104,6 +111,10 @@ pluginsTyped((x$1: Int)Unit, Trees$Select) [1] pluginsTyped((x: Double)Double (x: Float)Float (x: Long)Long (x: Int)Int (x: Char)Int (x: Short)Int (x: Byte)Int (x: String)String, Trees$Select) [1] pluginsTyped((x: String)scala.collection.immutable.StringOps, Trees$Select) [2] pluginsTyped((xs: Array[Any])scala.collection.mutable.WrappedArray[Any], Trees$TypeApply) [1] +pluginsTyped(0.type, Trees$Literal) [3] +pluginsTyped(1.type @testAnn, Trees$Typed) [1] +pluginsTyped(1.type, Trees$Literal) [8] +pluginsTyped(2.type, Trees$Literal) [1] pluginsTyped(.type, Trees$Ident) [1] pluginsTyped(, Trees$Select) [1] pluginsTyped(, Trees$ClassDef) [2] @@ -127,17 +138,11 @@ pluginsTyped(AnyRef, Trees$Select) [4] pluginsTyped(Array[Any], Trees$ArrayValue) [1] pluginsTyped(Boolean @testAnn, Trees$Select) [1] pluginsTyped(Boolean @testAnn, Trees$TypeTree) [4] -pluginsTyped(Boolean(false), Trees$Literal) [2] pluginsTyped(Boolean, Trees$Apply) [1] pluginsTyped(Boolean, Trees$Select) [4] -pluginsTyped(Char('c'), Trees$Literal) [2] pluginsTyped(Double, Trees$Select) [6] pluginsTyped(Int @testAnn, Trees$TypeTree) [2] pluginsTyped(Int @testAnn, Trees$Typed) [2] -pluginsTyped(Int(0), Trees$Literal) [3] -pluginsTyped(Int(1) @testAnn, Trees$Typed) [1] -pluginsTyped(Int(1), Trees$Literal) [8] -pluginsTyped(Int(2), Trees$Literal) [1] pluginsTyped(Int, Trees$Apply) [1] pluginsTyped(Int, Trees$Ident) [2] pluginsTyped(Int, Trees$If) [2] @@ -153,12 +158,6 @@ pluginsTyped(Object, Trees$Apply) [1] pluginsTyped(String @testAnn, Trees$Ident) [1] pluginsTyped(String @testAnn, Trees$Select) [1] pluginsTyped(String @testAnn, Trees$TypeTree) [4] -pluginsTyped(String(""), Trees$Literal) [2] -pluginsTyped(String("huhu"), Trees$Literal) [1] -pluginsTyped(String("str") @testAnn, Trees$Typed) [1] -pluginsTyped(String("str"), Trees$Literal) [1] -pluginsTyped(String("str"), Trees$Typed) [1] -pluginsTyped(String("two"), Trees$Literal) [2] pluginsTyped(String, Trees$Apply) [2] pluginsTyped(String, Trees$Block) [2] pluginsTyped(String, Trees$Ident) [1] @@ -175,6 +174,7 @@ pluginsTyped([T <: Int]=> Int, Trees$Select) [1] pluginsTyped([T0]()T0, Trees$Select) [1] pluginsTyped([T](xs: Array[T])scala.collection.mutable.WrappedArray[T], Trees$Select) [1] pluginsTyped(annotation.type, Trees$Select) [4] +pluginsTyped(false.type, Trees$Literal) [2] pluginsTyped(math.type, Trees$Select) [9] pluginsTyped(scala.annotation.Annotation, Trees$Apply) [1] pluginsTyped(scala.annotation.TypeConstraint, Trees$Select) [4] diff --git a/test/files/run/constant-type.check b/test/files/run/constant-type.check index a7ba5a46c2a..2a7c5000222 100644 --- a/test/files/run/constant-type.check +++ b/test/files/run/constant-type.check @@ -12,15 +12,15 @@ scala> val s = transformedType(StringClass.toType).asInstanceOf[Type] s: $r.intp.global.Type = String scala> { println(exitingPhase(currentRun.erasurePhase)(ConstantType(Constant(s)))) } -Class[String](classOf[java.lang.String]) +classOf[java.lang.String].type scala> { exitingPhase(currentRun.erasurePhase)(println(ConstantType(Constant(s)))) } -Class(classOf[java.lang.String]) +classOf[java.lang.String].type scala> { ConstantType(Constant(s)); println(exitingPhase(currentRun.erasurePhase)(ConstantType(Constant(s)))); } -Class[String](classOf[java.lang.String]) +classOf[java.lang.String].type scala> { ConstantType(Constant(s)); exitingPhase(currentRun.erasurePhase)(println(ConstantType(Constant(s)))); } -Class(classOf[java.lang.String]) +classOf[java.lang.String].type scala> :quit diff --git a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check index 1d531f6d867..6147fea690f 100644 --- a/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check +++ b/test/files/run/macro-invalidret-doesnt-conform-to-def-rettype.check @@ -1,5 +1,5 @@ reflective compilation has failed: type mismatch; - found : String("42") + found : "42".type (with underlying type String) required: Int diff --git a/test/files/run/macro-reify-unreify.check b/test/files/run/macro-reify-unreify.check index 7a6d53c47e8..4df1e9c8c73 100644 --- a/test/files/run/macro-reify-unreify.check +++ b/test/files/run/macro-reify-unreify.check @@ -1 +1 @@ -hello world = Expr[java.lang.String("hello world")]("hello world") +hello world = Expr["hello world".type]("hello world") diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check index c618d22d8d6..fed7f239384 100644 --- a/test/files/run/macro-typecheck-macrosdisabled.check +++ b/test/files/run/macro-typecheck-macrosdisabled.check @@ -1,7 +1,7 @@ ({ val $u: reflect.runtime.universe.type = scala.reflect.runtime.`package`.universe; val $m: $u.Mirror = scala.reflect.runtime.`package`.universe.runtimeMirror(this.getClass().getClassLoader()); - $u.Expr.apply[Int(2)]($m, { + $u.Expr.apply[2.type]($m, { final class $treecreator1 extends TreeCreator { def (): $treecreator1 = { $treecreator1.super.(); @@ -14,7 +14,7 @@ } }; new $treecreator1() - })($u.TypeTag.apply[Int(2)]($m, { + })($u.TypeTag.apply[2.type]($m, { final class $typecreator2 extends TypeCreator { def (): $typecreator2 = { $typecreator2.super.(); diff --git a/test/files/run/reify_classfileann_b.check b/test/files/run/reify_classfileann_b.check index 05f2e5bfc6d..3bd1863228b 100644 --- a/test/files/run/reify_classfileann_b.check +++ b/test/files/run/reify_classfileann_b.check @@ -19,7 +19,7 @@ class ann(bar: String, quux: Array[String] = Array(), baz: ann = null) extends a C.super.(); () }; - def x: Int = (2: Int(2) @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4"))) + def x: Int = (2: 2.type @ann(bar = "1", quux = ["2", "3"], baz = ann(bar = "4"))) }; () } diff --git a/test/files/run/repl-colon-type.check b/test/files/run/repl-colon-type.check index 9898027c1dd..c73aece7c19 100644 --- a/test/files/run/repl-colon-type.check +++ b/test/files/run/repl-colon-type.check @@ -2,9 +2,9 @@ Type in expressions to have them evaluated. Type :help for more information. scala> :type List[1, 2, 3] -:1: error: identifier expected but integer literal found. +:1: error: '.' expected but ',' found. List[1, 2, 3] - ^ + ^ scala> :type List(1, 2, 3) List[Int] diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index e2318c93f2c..c3eb9de95b5 100644 --- a/test/files/run/repl-power.check +++ b/test/files/run/repl-power.check @@ -25,6 +25,6 @@ scala> val m = LIT(10) // treedsl m: $r.treedsl.global.Literal = 10 scala> typed(m).tpe // typed is in scope -res2: $r.treedsl.global.Type = Int(10) +res2: $r.treedsl.global.Type = 10.type scala> :quit diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check index 62de3758264..13376860136 100644 --- a/test/files/run/toolbox_typecheck_macrosdisabled.check +++ b/test/files/run/toolbox_typecheck_macrosdisabled.check @@ -10,7 +10,7 @@ }; new $anon() }.getClass().getClassLoader()); - $u.Expr.apply[Int(2)]($m, { + $u.Expr.apply[2.type]($m, { final class $treecreator1 extends TreeCreator { def (): $treecreator1 = { $treecreator1.super.(); @@ -23,7 +23,7 @@ } }; new $treecreator1() - })($u.TypeTag.apply[Int(2)]($m, { + })($u.TypeTag.apply[2.type]($m, { final class $typecreator2 extends TypeCreator { def (): $typecreator2 = { $typecreator2.super.();