From b11d7bab46156fec88326cfd192410e151dbe0df Mon Sep 17 00:00:00 2001 From: George Leontiev Date: Fri, 12 Sep 2014 14:41:26 +0200 Subject: [PATCH 1/3] Basic implementation of 42.type: - Implements mandatory `.type` for identifiers - Implements optional `.type` for literals - Fixes a few problems with it, updates .check files --- bincompat-backward.whitelist.conf | 11 +- bincompat-forward.whitelist.conf | 12 +- .../reflect/reify/codegen/GenTypes.scala | 3 +- .../scala/tools/nsc/ast/parser/Parsers.scala | 22 +++- .../tools/nsc/transform/Constructors.scala | 1 + .../scala/tools/nsc/transform/Erasure.scala | 3 +- .../transform/patmat/MatchOptimization.scala | 1 + .../nsc/typechecker/ConstantFolder.scala | 3 +- .../scala/tools/nsc/typechecker/Infer.scala | 1 + .../scala/tools/nsc/typechecker/Namers.scala | 8 +- .../nsc/typechecker/TypeDiagnostics.scala | 1 + .../scala/tools/nsc/typechecker/Typers.scala | 19 +-- src/reflect/scala/reflect/api/Trees.scala | 1 + src/reflect/scala/reflect/api/Types.scala | 4 +- .../scala/reflect/internal/Types.scala | 15 ++- test/files/jvm/interpreter.check | 2 +- test/files/neg/any-vs-anyref.check | 34 +---- test/files/neg/applydynamic_sip.check | 8 +- test/files/neg/class-of-double-targs.check | 2 +- test/files/neg/constrs.check | 2 +- test/files/neg/divergent-implicit.check | 2 +- test/files/neg/gadts1.check | 2 +- test/files/neg/gadts2.check | 2 +- test/files/neg/implicit-shadow.check | 2 +- test/files/neg/logImplicits.check | 6 +- .../neg/macro-invalidusage-badargs.check | 2 +- test/files/neg/names-defaults-neg.check | 4 +- test/files/neg/nested-fn-print.check | 6 +- test/files/neg/no-predef.check | 2 +- test/files/neg/not-possible-cause.check | 9 -- test/files/neg/not-possible-cause.scala | 3 - .../quasiquotes-syntax-error-position.check | 2 +- test/files/neg/reflection-names-neg.check | 4 +- test/files/neg/saferJavaConversions.check | 2 +- test/files/neg/sensitive2.check | 4 +- test/files/neg/t0590.check | 2 +- test/files/neg/t1041.check | 2 +- test/files/neg/t2139.check | 2 +- test/files/neg/t2801.check | 2 +- test/files/neg/t3006.check | 2 +- test/files/neg/t3481.check | 8 +- test/files/neg/t391.check | 5 +- test/files/neg/t3971.check | 2 +- test/files/neg/t3995.check | 2 +- test/files/neg/t4818.check | 2 +- test/files/neg/t5106.check | 4 +- test/files/neg/t5376.check | 4 +- test/files/neg/t5892.check | 4 +- test/files/neg/t6263.check | 9 -- test/files/neg/t6263.scala | 6 - test/files/neg/t6680a.check | 4 +- test/files/neg/t7509.check | 2 +- test/files/neg/t7519.check | 4 +- test/files/neg/t8015-ffa.check | 2 +- test/files/neg/t8325-c.check | 6 +- test/files/neg/t8325.check | 2 +- test/files/neg/t846.check | 2 +- test/files/neg/t8675.check | 4 +- test/files/neg/t900.check | 9 -- test/files/neg/t900.scala | 5 - test/files/neg/t909.check | 2 +- test/files/presentation/t5708.check | 2 +- test/files/run/42.type.check | 4 + test/files/run/42.type.scala | 117 ++++++++++++++++++ test/files/run/analyzerPlugins.check | 30 ++--- test/files/run/constant-type.check | 8 +- test/files/run/exprs_serialize.check | 2 +- ...lidret-doesnt-conform-to-def-rettype.check | 2 +- test/files/run/macro-reify-unreify.check | 2 +- .../run/macro-typecheck-macrosdisabled.check | 4 +- test/files/run/reify_classfileann_b.check | 2 +- test/files/run/repl-colon-type.check | 8 +- test/files/run/repl-power.check | 2 +- .../toolbox_typecheck_macrosdisabled.check | 4 +- 74 files changed, 290 insertions(+), 200 deletions(-) delete mode 100644 test/files/neg/not-possible-cause.check delete mode 100644 test/files/neg/not-possible-cause.scala delete mode 100644 test/files/neg/t6263.check delete mode 100644 test/files/neg/t6263.scala delete mode 100644 test/files/neg/t900.check delete mode 100644 test/files/neg/t900.scala create mode 100644 test/files/run/42.type.check create mode 100644 test/files/run/42.type.scala diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 6c98dc62a18f..07543239fa05 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 diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index cfaeadcad33c..d76559e38824 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -228,7 +228,11 @@ filter { problemName=MissingClassProblem }, { - matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$followStatic" + matchName="scala.reflect.api.Trees#SingletonTypeTreeApi.scala$reflect$api$Trees$SingletonTypeTreeApi$$$outer" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.api.Trees#SingletonTypeTreeApi.isLiteral" problemName=MissingMethodProblem }, { @@ -393,6 +397,10 @@ filter { { matchName="scala.reflect.runtime.Settings.ZirrefutableGeneratorPatterns" problemName=MissingMethodProblem - } + }, + { + matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$followStatic" + problemName=MissingMethodProblem + } ] } diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala index d007df75e38c..0bd131bacb36 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 6a00a8c6f94b..18f85c7f5d07 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -675,11 +675,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 @@ -862,7 +862,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() @@ -1108,6 +1114,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 f471440293a6..6ba7188d5fe6 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 3d8b2f02f3ac..3fe0224c2aeb 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 e9c81f47289d..3319ff44b34a 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 56ed0ee16ca7..e02e5e59d51d 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 ee2775ee26e3..6c7d568c8022 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 fdff2f3076dc..16d64892429f 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 1dac27639c50..68ac472c8960 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 08d929450f05..4c87ee7ce4b0 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -738,7 +738,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 @@ -990,6 +990,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) @@ -1090,7 +1091,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) @@ -3464,6 +3465,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. */ @@ -3527,6 +3529,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) } @@ -5093,11 +5096,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/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala index ff8926651b97..3b91a10800fc 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 } /** Type selection # , eliminated by RefCheck diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala index f6995dd5dea7..cba1d8f560a5 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/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 8087cda4b321..7e2f2b7955ce 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/test/files/jvm/interpreter.check b/test/files/jvm/interpreter.check index 42f5f7af70bf..89214b95070f 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/any-vs-anyref.check b/test/files/neg/any-vs-anyref.check index 7378f0495fec..29cd791e554e 100644 --- a/test/files/neg/any-vs-anyref.check +++ b/test/files/neg/any-vs-anyref.check @@ -1,35 +1,3 @@ -any-vs-anyref.scala:6: error: type mismatch; - found : a.type (with underlying type A) - required: AnyRef -Note that A is bounded only by Equals, which means AnyRef is not a known parent. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - def foo1[A <: Product](a: A) = { type X = a.type } - ^ -any-vs-anyref.scala:7: error: type mismatch; - found : a.type (with underlying type A) - required: AnyRef -Note that A is bounded only by Product, Quux, which means AnyRef is not a known parent. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - def foo2[A <: Product with Quux](a: A) = { type X = a.type } - ^ -any-vs-anyref.scala:8: error: type mismatch; - found : a.type (with underlying type Product) - required: AnyRef -Note that Product extends Any, not AnyRef. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - def foo3(a: Product) = { type X = a.type } - ^ -any-vs-anyref.scala:9: error: type mismatch; - found : Product with Quux - required: AnyRef -Note that the parents of this type (Product, Quux) extend Any, not AnyRef. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - def foo4(a: Product with Quux) = { type X = a.type } - ^ any-vs-anyref.scala:10: error: value eq is not a member of Quux with Product Note that the parents of this type (Quux, Product) extend Any, not AnyRef. Such types can participate in value classes, but instances @@ -77,4 +45,4 @@ any-vs-anyref.scala:27: error: type mismatch; required: Quux{def g(x: Int): Int} f(new Quux { def g(x: String) = x }) ^ -11 errors found +7 errors found diff --git a/test/files/neg/applydynamic_sip.check b/test/files/neg/applydynamic_sip.check index 2cb2e7f095ee..44ecaef71040 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 f7e2094f9778..5fe89bcb98f0 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 4f4a12bc13ed..5f3285bdc946 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 d4a3ddfc71c0..8e291336cb86 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 9b7ea5556a80..5562815bd4af 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 dc21f3f52c88..323333a1d622 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 042fca867a03..11470a3786d4 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 270882b71a09..e3229603072d 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-invalidusage-badargs.check b/test/files/neg/macro-invalidusage-badargs.check index 4c1115418b57..28873f8bfe2e 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 20ddd55f1fde..eba171c08643 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 ea278554d42e..6ddb60d7e08c 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 a63d8c5ba5c6..5432e17c384c 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/not-possible-cause.check b/test/files/neg/not-possible-cause.check deleted file mode 100644 index 5c09fa154568..000000000000 --- a/test/files/neg/not-possible-cause.check +++ /dev/null @@ -1,9 +0,0 @@ -not-possible-cause.scala:2: error: type mismatch; - found : a.type (with underlying type A) - required: AnyRef -Note that A is bounded only by Equals, which means AnyRef is not a known parent. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - def foo[A <: Product](a: A) { type X = a.type } - ^ -one error found diff --git a/test/files/neg/not-possible-cause.scala b/test/files/neg/not-possible-cause.scala deleted file mode 100644 index 83ec24dec863..000000000000 --- a/test/files/neg/not-possible-cause.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Foo { - def foo[A <: Product](a: A) { type X = a.type } -} diff --git a/test/files/neg/quasiquotes-syntax-error-position.check b/test/files/neg/quasiquotes-syntax-error-position.check index 9fd6ce041761..dcd6d6c5326e 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 f941ec8dc1b2..91dbc99f66b6 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 0e53d2c4379b..2649fa3334cc 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 19152fe18846..1eb6c7d4ba6c 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 a3ef70c6cdf8..16e4d989ae1f 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 d82f3a8586be..161add5d2480 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 e26f2907617f..085243143ccb 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 25320de5bc4e..b57e9255f15a 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 2447eebc9cba..578d93ed131f 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 debe07275be6..fa22668c965d 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 879d9af71fe1..bc85c892c5cf 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 8685119876ec..89a0afb02bb7 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 00ecf4ca5b6e..91f8ab6c7307 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 a5e15e456b82..cdf011df54a0 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 ac16041cf7a8..dff4443ca4dd 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 0376163c35e5..eab8ee4fc9e7 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 839bf9de2302..dbed15acfc74 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/t6263.check b/test/files/neg/t6263.check deleted file mode 100644 index 9e9c7c615b99..000000000000 --- a/test/files/neg/t6263.check +++ /dev/null @@ -1,9 +0,0 @@ -t6263.scala:5: error: type mismatch; - found : A.this.c.type (with underlying type C) - required: AnyRef -Note that C extends Any, not AnyRef. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - type t = c.type - ^ -one error found diff --git a/test/files/neg/t6263.scala b/test/files/neg/t6263.scala deleted file mode 100644 index 6575185b5ce4..000000000000 --- a/test/files/neg/t6263.scala +++ /dev/null @@ -1,6 +0,0 @@ -class C(val a: Any) extends AnyVal -class A { - implicit def c2AnyRef(c: C): AnyRef = new {} - val c = new C(0) - type t = c.type -} diff --git a/test/files/neg/t6680a.check b/test/files/neg/t6680a.check index 03e4df10c121..f11983a6630e 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 eaa6303cf520..794f5878a5bb 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 df54abaa3e23..f4249e36c7be 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 0f28be7fe7b7..a619dadd7978 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-c.check b/test/files/neg/t8325-c.check index 51ea4988a649..b5e2b596f285 100644 --- a/test/files/neg/t8325-c.check +++ b/test/files/neg/t8325-c.check @@ -1,7 +1,7 @@ -t8325-c.scala:3: error: identifier expected but ')' found. +t8325-c.scala:3: error: illegal literal def k(xx: Int`*`) = ??? ^ -t8325-c.scala:4: error: ')' expected but '}' found. +t8325-c.scala:4: error: ')' expected but eof found. } -^ + ^ two errors found diff --git a/test/files/neg/t8325.check b/test/files/neg/t8325.check index 175a0db41511..b4a298880f72 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 242a8001ff3c..05f189407ba0 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/t8675.check b/test/files/neg/t8675.check index 4e44fba91867..5d60f267b6ec 100644 --- a/test/files/neg/t8675.check +++ b/test/files/neg/t8675.check @@ -1,10 +1,10 @@ t8675.scala:13: error: type mismatch; - found : Boolean(true) + found : true.type (with underlying type Boolean) required: String a.update(0, x[A]({new isString(true)})) // !!! allowed ^ t8675.scala:22: error: type mismatch; - found : Boolean(true) + found : true.type (with underlying type Boolean) required: String new X().m(x[A]({new isString(true)})) // !!! allowed ^ diff --git a/test/files/neg/t900.check b/test/files/neg/t900.check deleted file mode 100644 index 6fe26a31acdc..000000000000 --- a/test/files/neg/t900.check +++ /dev/null @@ -1,9 +0,0 @@ -t900.scala:4: error: type mismatch; - found : Foo.this.x.type (with underlying type Foo.this.bar) - required: AnyRef -Note that bar is unbounded, which means AnyRef is not a known parent. -Such types can participate in value classes, but instances -cannot appear in singleton types or in reference comparisons. - def break(): x.type - ^ -one error found diff --git a/test/files/neg/t900.scala b/test/files/neg/t900.scala deleted file mode 100644 index 2d2c85757523..000000000000 --- a/test/files/neg/t900.scala +++ /dev/null @@ -1,5 +0,0 @@ -trait Foo { - type bar - val x : bar - def break(): x.type -} diff --git a/test/files/neg/t909.check b/test/files/neg/t909.check index e7a42bd246b7..ce704f37f368 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 4b33893e9800..ea3eb2484786 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 000000000000..196ce8001abb --- /dev/null +++ b/test/files/run/42.type.check @@ -0,0 +1,4 @@ +2 +(2,0,1) +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 000000000000..8a01d40c1607 --- /dev/null +++ b/test/files/run/42.type.scala @@ -0,0 +1,117 @@ +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) + + 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))) + 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 9803465ddc23..68a49accceff 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 a7ba5a46c2a3..2a7c5000222b 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/exprs_serialize.check b/test/files/run/exprs_serialize.check index 551823ccdc70..ee5bf157536b 100644 --- a/test/files/run/exprs_serialize.check +++ b/test/files/run/exprs_serialize.check @@ -1,4 +1,4 @@ -Expr[Int(2)](2) +Expr[2.type](2) Expr[java.lang.String]({ def foo = "hello"; foo.$plus("world!") 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 1d531f6d867a..6147fea690fc 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 7a6d53c47e80..4df1e9c8c73a 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 c618d22d8d6a..fed7f2393843 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 05f2e5bfc6da..3bd1863228b5 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 9898027c1dd2..8ed4c72bf1ce 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. - List[1, 2, 3] - ^ +:8: error: wrong number of type parameters for method apply: [A](xs: A*)List[A] in object List + List[1, 2, 3] + ^ scala> :type List(1, 2, 3) List[Int] @@ -38,7 +38,7 @@ Int scala> :type protected lazy val f = 5 :5: error: lazy value f cannot be accessed in object $iw Access to protected value f not permitted because - enclosing object $eval in package $line13 is not a subclass of + enclosing object $eval in package $line16 is not a subclass of object $iw where target is defined lazy val $result = f ^ diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check index e2318c93f2ca..c3eb9de95b5e 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 62de3758264a..13376860136a 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.(); From 0c521ca8308c5221cf0e10bed1102679f11e4c8b Mon Sep 17 00:00:00 2001 From: George Leontiev Date: Sat, 13 Sep 2014 11:54:40 +0200 Subject: [PATCH 2/3] Get rid of unneeded var. --- src/compiler/scala/tools/nsc/typechecker/Namers.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 16d64892429f..100975d1e13c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -25,8 +25,6 @@ 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. */ @@ -865,7 +863,7 @@ trait Namers extends MethodSynthesis { ) dropIllegalStarTypes( if (shouldWiden) tpe.widen - else if (sym.isFinal || (isLiteral && inferDependentTypes)) tpe // "final val" allowed to retain constant type + else if (sym.isFinal) tpe // "final val" allowed to retain constant type else tpe.deconst ) } From 0c0cd8afc2fd99d5ab543419e8c0a02fea4b148d Mon Sep 17 00:00:00 2001 From: George Leontiev Date: Mon, 6 Oct 2014 16:39:14 +0200 Subject: [PATCH 3/3] Address the review: - Remove mutable state by introducing `DeclaredSingletonType` - Update the spec --- spec/03-types.md | 9 +++--- .../scala/tools/nsc/typechecker/Typers.scala | 3 +- .../scala/reflect/internal/Types.scala | 22 ++++++++----- .../reflect/runtime/JavaUniverseForce.scala | 1 + test/files/run/42.type.check | 1 - test/files/run/42.type.scala | 32 +++++++++++-------- 6 files changed, 39 insertions(+), 29 deletions(-) diff --git a/spec/03-types.md b/spec/03-types.md index 80200cdf33a4..66c7d19584b4 100644 --- a/spec/03-types.md +++ b/spec/03-types.md @@ -103,12 +103,13 @@ forms. ```ebnf SimpleType ::= Path ‘.’ type + | Literal [‘.’ type] ``` -A singleton type is of the form $p.$`type`, where $p$ is a -path pointing to a value expected to [conform](06-expressions.html#expression-typing) -to `scala.AnyRef`. The type denotes the set of values -consisting of `null` and the value denoted by $p$. +A singleton type is of the form $p.$`type`, where $p$ is a path, +or $42$, with `.type` being optional for literals. +The type denotes the set of values consisting of `null` and the +value denoted by $p$. A _stable type_ is either a singleton type or a type which is declared to be a subtype of trait `scala.Singleton`. diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 4c87ee7ce4b0..5c05f83a7c16 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -5100,8 +5100,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper typed(tree.ref, MonoQualifierModes | mode.onlyTypePat, AnyClass.tpe) } tree setType { - if (tree.isLiteral) refTyped.tpe.resultType.asDeclaredSingleton - else refTyped.tpe.resultType + refTyped.tpe.resultType.asDeclaredSingleton.getOrElse(refTyped.tpe.resultType) } if (!refTyped.isErrorTyped) tree setType refTyped.tpe.resultType diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 7e2f2b7955ce..314344c50df4 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -258,11 +258,8 @@ 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 - } + val isDeclaredSingleton: Boolean = false + def asDeclaredSingleton: Option[DeclaredSingletonType] = None /** Types for which asSeenFrom always is the identity, no matter what * prefix or owner. @@ -1817,15 +1814,24 @@ trait Types class PackageClassInfoType(decls: Scope, clazz: Symbol) extends ClassInfoType(List(), decls, clazz) + final case class DeclaredSingletonType(value: Constant) extends SingletonType with SingletonTypeApi { + override val isDeclaredSingleton = true + override def asDeclaredSingleton = Some(this) + override def underlying: Type = value.tpe + override def isTrivial: Boolean = true + override def deconst = underlying + override def safeToString: String = value.escapedStringValue + ".type" + override def kind = "DeclaredSingletonType" + } + /** A class representing a constant type. */ abstract case class ConstantType(value: Constant) extends SingletonType with ConstantTypeApi { + override def asDeclaredSingleton = Some(DeclaredSingletonType(value)) override def underlying: Type = value.tpe assert(underlying.typeSymbol != UnitClass) override def isTrivial: Boolean = true - override def deconst: Type = - if (isDeclaredSingleton) this - else underlying + override def deconst: Type = underlying override def safeToString: String = value.escapedStringValue + ".type" override def kind = "ConstantType" } diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala index 28f11de91cfa..bd8cc27e0f2c 100644 --- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala +++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala @@ -143,6 +143,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse => this.baseClassesCycleMonitor this.RefinedType this.ClassInfoType + this.DeclaredSingletonType this.ConstantType this.TypeRef this.MethodType diff --git a/test/files/run/42.type.check b/test/files/run/42.type.check index 196ce8001abb..a28c6f0775a1 100644 --- a/test/files/run/42.type.check +++ b/test/files/run/42.type.check @@ -1,4 +1,3 @@ -2 (2,0,1) got 1 got PANDA! diff --git a/test/files/run/42.type.scala b/test/files/run/42.type.scala index 8a01d40c1607..e034f484aa49 100644 --- a/test/files/run/42.type.scala +++ b/test/files/run/42.type.scala @@ -16,7 +16,7 @@ object Test { type Null = null.type - var x: 3.type = 3 + //var x: 3.type = 3 /* scala> x = 42 :8: error: type mismatch; @@ -46,7 +46,7 @@ object Test { implicit object One extends Succ[1.type] { type Out = 2.type - def apply(x: 1.type) = 2 + def apply(x: 1.type): 2 = 2 } def f[T](x: T)(implicit succ: Succ[T]) = succ(x) @@ -57,28 +57,32 @@ object Test { } def main(args: Array[String]): Unit = { - println(f(1)) + //println(f(1)) // println(f(5)) println((g(1), g(5), g(7))) noisyIdentity(1) noisyIdentity("PANDA!") } - // Inlining functions with singleton result type + // vars don't play well with singleton types: +/* +scala> var test: 3.type = 3 +:7: error: assignment to non variable + var test: 3.type = 3 + ^ + */ + + // No inlining of functions with singleton result type anymore, but then this: /* -scala> def ok(): 7.type = { +scala> def test(): 7.type = { | println("PANDA!") | 7 | } -ok: ()7.type - -scala> ok() -res0: 7.type = 7 - -// Expected: -scala> ok() -PANDA! -res0: 7.type = 7 +:7: error: type mismatch; + found : Int + required: 7.type + def test(): 7.type = { + ^ */ // Parser problem: