From 658d90ace0068547d89ed398c6775d8cc8264ee0 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Thu, 9 May 2013 12:55:15 +0200 Subject: c.typeCheck(silent = true) now suppresses ambiguous errors Otherwise use cases like the one shown in the attached test (trying to typecheck something, which leads to an ambiguous overload error) will mysteriously fail compilation. --- test/files/pos/t7461.check | 0 test/files/pos/t7461/Macros_1.scala | 13 +++++++++++++ test/files/pos/t7461/Test_2.scala | 3 +++ 3 files changed, 16 insertions(+) create mode 100644 test/files/pos/t7461.check create mode 100644 test/files/pos/t7461/Macros_1.scala create mode 100644 test/files/pos/t7461/Test_2.scala (limited to 'test') diff --git a/test/files/pos/t7461.check b/test/files/pos/t7461.check new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/files/pos/t7461/Macros_1.scala b/test/files/pos/t7461/Macros_1.scala new file mode 100644 index 0000000000..353dec66d7 --- /dev/null +++ b/test/files/pos/t7461/Macros_1.scala @@ -0,0 +1,13 @@ +import scala.reflect.macros.Context +import language.experimental.macros + +object Macros { + def impl(c: Context) = { + import c.universe._ + val wut = c.typeCheck(Select(Literal(Constant(10)), newTermName("$minus")), silent = true) + // println(showRaw(wut, printIds = true, printTypes = true)) + c.literalUnit + } + + def foo = macro impl +} \ No newline at end of file diff --git a/test/files/pos/t7461/Test_2.scala b/test/files/pos/t7461/Test_2.scala new file mode 100644 index 0000000000..3839659c9a --- /dev/null +++ b/test/files/pos/t7461/Test_2.scala @@ -0,0 +1,3 @@ +class C { + def foo = Macros.foo +} \ No newline at end of file -- cgit v1.2.3 From 5b54681d0360616efdb2a561ce9201fbd67e7288 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 23 May 2013 00:28:45 -0700 Subject: SI-7473 Bad for expr crashes postfix This commit makes building PostfixSelect robust against a bad pos on its operand, which can happen if a bad for expression results in an EmptyTree. --- src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 9 ++++----- src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 6 ++++++ test/files/neg/t7473.check | 7 +++++++ test/files/neg/t7473.scala | 7 +++++++ 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 test/files/neg/t7473.check create mode 100644 test/files/neg/t7473.scala (limited to 'test') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index b8791c15dc..50398824e1 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1474,8 +1474,9 @@ self => * }}} */ def postfixExpr(): Tree = { - val base = opstack - var top = prefixExpr() + val start = in.offset + val base = opstack + var top = prefixExpr() while (isIdent) { top = reduceStack(isExpr = true, base, top, precedence(in.name), leftAssoc = treeInfo.isLeftAssoc(in.name)) @@ -1493,9 +1494,7 @@ self => val topinfo = opstack.head opstack = opstack.tail val od = stripParens(reduceStack(isExpr = true, base, topinfo.operand, 0, leftAssoc = true)) - return atPos(od.pos.startOrPoint, topinfo.offset) { - new PostfixSelect(od, topinfo.operator.encode) - } + return makePostfixSelect(start, topinfo.offset, od, topinfo.operator) } } reduceStack(isExpr = true, base, top, 0, leftAssoc = true) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index b5771454f8..e92c3e1654 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -245,6 +245,12 @@ abstract class TreeBuilder { Assign(lhs, rhs) } + /** Tree for `od op`, start is start0 if od.pos is borked. */ + def makePostfixSelect(start0: Int, end: Int, od: Tree, op: Name): Tree = { + val start = if (od.pos.isDefined) od.pos.startOrPoint else start0 + atPos(r2p(start, end, end)) { new PostfixSelect(od, op.encode) } + } + /** A type tree corresponding to (possibly unary) intersection type */ def makeIntersectionTypeTree(tps: List[Tree]): Tree = if (tps.tail.isEmpty) tps.head diff --git a/test/files/neg/t7473.check b/test/files/neg/t7473.check new file mode 100644 index 0000000000..bc8c29d463 --- /dev/null +++ b/test/files/neg/t7473.check @@ -0,0 +1,7 @@ +t7473.scala:6: error: '<-' expected but '=' found. + (for (x = Option(i); if x == j) yield 42) toList + ^ +t7473.scala:6: error: illegal start of simple expression + (for (x = Option(i); if x == j) yield 42) toList + ^ +two errors found diff --git a/test/files/neg/t7473.scala b/test/files/neg/t7473.scala new file mode 100644 index 0000000000..593231d5f2 --- /dev/null +++ b/test/files/neg/t7473.scala @@ -0,0 +1,7 @@ + +object Foo { + val i,j = 3 + //for (x = Option(i); if x == j) yield 42 //t7473.scala:4: error: '<-' expected but '=' found. + // evil postfix! + (for (x = Option(i); if x == j) yield 42) toList +} -- cgit v1.2.3 From b941551529e40fc7d71cf25e1ad904ab7badd14c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 22 May 2013 15:51:18 +0200 Subject: SI-6138 Centralize and refine detection of `getClass` calls `getClass` is special cased in the compiler; this is described in in the comments on `Definitions.Any_getClass`. Part of this happens in `Typer#stabilize`. This was trying to determine if an Ident or Select node was a call to `getClass` by merits of the name of the tree's symbol and by checking that the its type (if it was a MethodType or PolyType) had no parameters in the primary parameter list. Overloaded user defined `getClass` methods confused this check. In the enclosed test case, the tree `definitions.this.getClass` had an `OverloadedType`, and such types always report an empty list of `params`. This commit: - changes `stabilize` to use `isGetClass`, rather than the homebrew check - changes `isGetClass` to consider a `Set[Symbol]` containing all `getClass` variants. This moves some similar code from `Erasure` to `Definitions` - keeps a fast negative path in `isGetClass` based on the symbol's name --- bincompat-backward.whitelist.conf | 8 ++++++++ bincompat-forward.whitelist.conf | 8 ++++++++ src/compiler/scala/tools/nsc/transform/Erasure.scala | 5 ----- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 3 +-- src/reflect/scala/reflect/internal/Definitions.scala | 12 ++++++++++-- test/files/neg/t6138.check | 7 +++++++ test/files/neg/t6138.scala | 5 +++++ 7 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 test/files/neg/t6138.check create mode 100644 test/files/neg/t6138.scala (limited to 'test') diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf index 904e9477a2..2ef4ae1cc1 100644 --- a/bincompat-backward.whitelist.conf +++ b/bincompat-backward.whitelist.conf @@ -219,6 +219,14 @@ filter { { matchName="scala.concurrent.forkjoin.ForkJoinPool.helpJoinOnce" problemName=IncompatibleResultTypeProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.getClassMethods" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods" + problemName=MissingMethodProblem } ] } diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf index 83864f48ee..284e0809a8 100644 --- a/bincompat-forward.whitelist.conf +++ b/bincompat-forward.whitelist.conf @@ -471,6 +471,14 @@ filter { { matchName="scala.concurrent.impl.Promise$CompletionLatch" problemName=MissingClassProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.getClassMethods" + problemName=MissingMethodProblem + }, + { + matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods" + problemName=MissingMethodProblem } ] } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ead6ef288c..76249974ac 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -341,11 +341,6 @@ abstract class Erasure extends AddInterfaces } } - // Each primitive value class has its own getClass for ultra-precise class object typing. - private lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( - ScalaValueClasses map (_.tpe member nme.getClass_) - ) - // ## requires a little translation private lazy val poundPoundMethods = Set[Symbol](Any_##, Object_##) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c59ef4ebda..29cd3d4bfa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -656,8 +656,7 @@ trait Typers extends Modes with Adaptations with Tags { // To fully benefit from special casing the return type of // getClass, we have to catch it immediately so expressions // like x.getClass().newInstance() are typed with the type of x. - else if ( tree.symbol.name == nme.getClass_ - && tree.tpe.params.isEmpty + else if ( isGetClass(tree.symbol) // TODO: If the type of the qualifier is inaccessible, we can cause private types // to escape scope here, e.g. pos/t1107. I'm not sure how to properly handle this // so for now it requires the type symbol be public. diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index e5d9e54a16..629d82d254 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -110,8 +110,10 @@ trait Definitions extends api.StandardDefinitions { /** Is symbol a numeric value class? */ def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym - def isGetClass(sym: Symbol) = - (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss) + def isGetClass(sym: Symbol) = ( + sym.name == nme.getClass_ // this condition is for performance only, this is called from `Typer#stabliize`. + && getClassMethods(sym) + ) lazy val UnitClass = valueClassSymbol(tpnme.Unit) lazy val ByteClass = valueClassSymbol(tpnme.Byte) @@ -805,6 +807,12 @@ trait Definitions extends api.StandardDefinitions { lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype) lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor) + lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ ( + ScalaValueClasses map (_.tpe member nme.getClass_) + ) + + lazy val getClassMethods: Set[Symbol] = primitiveGetClassMethods + Object_getClass + // A type function from T => Class[U], used to determine the return // type of getClass calls. The returned type is: // diff --git a/test/files/neg/t6138.check b/test/files/neg/t6138.check new file mode 100644 index 0000000000..8fd9978248 --- /dev/null +++ b/test/files/neg/t6138.check @@ -0,0 +1,7 @@ +t6138.scala:4: error: ambiguous reference to overloaded definition, +both method getClass in object definitions of type (s: Int)Any +and method getClass in object definitions of type (s: String)Any +match argument types (Nothing) + getClass(???): String + ^ +one error found diff --git a/test/files/neg/t6138.scala b/test/files/neg/t6138.scala new file mode 100644 index 0000000000..2f45a46b1c --- /dev/null +++ b/test/files/neg/t6138.scala @@ -0,0 +1,5 @@ +object definitions { + def getClass(s: String): Any = ??? + def getClass(s: Int): Any = ??? + getClass(???): String +} -- cgit v1.2.3 From d9c8ccce14bdd4f9364af4941cd47edbfec0c8ce Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 23 May 2013 21:23:25 +0200 Subject: SI-7509 Avoid crasher as erronous args flow through NamesDefaults The fix for SI-7238 caused this regression. This commit marks taints whole Apply with an ErrorType if it has an erroneous argument, so as to stop a later crash trying to further process the tree. --- src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala | 9 ++++++--- test/files/neg/t7509.check | 12 ++++++++++++ test/files/neg/t7509.scala | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 test/files/neg/t7509.check create mode 100644 test/files/neg/t7509.scala (limited to 'test') diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index f3736f1519..802df39f01 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -333,9 +333,12 @@ trait NamesDefaults { self: Analyzer => // type the application without names; put the arguments in definition-site order val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt) typedApp match { - // Extract the typed arguments, restore the call-site evaluation order (using - // ValDef's in the block), change the arguments to these local values. - case Apply(expr, typedArgs) if !(typedApp :: typedArgs).exists(_.isErrorTyped) => // bail out with erroneous args, see SI-7238 + case Apply(expr, typedArgs) if (typedApp :: typedArgs).exists(_.isErrorTyped) => + setError(tree) // bail out with and erroneous Apply *or* erroneous arguments, see SI-7238, SI-7509 + case Apply(expr, typedArgs) => + // Extract the typed arguments, restore the call-site evaluation order (using + // ValDef's in the block), change the arguments to these local values. + // typedArgs: definition-site order val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false) // valDefs: call-site order diff --git a/test/files/neg/t7509.check b/test/files/neg/t7509.check new file mode 100644 index 0000000000..eaa6303cf5 --- /dev/null +++ b/test/files/neg/t7509.check @@ -0,0 +1,12 @@ +t7509.scala:3: error: inferred type arguments [Int] do not conform to method crash's type parameter bounds [R <: AnyRef] + crash(42) + ^ +t7509.scala:3: error: type mismatch; + found : Int(42) + required: R + crash(42) + ^ +t7509.scala:3: error: could not find implicit value for parameter ev: R + crash(42) + ^ +three errors found diff --git a/test/files/neg/t7509.scala b/test/files/neg/t7509.scala new file mode 100644 index 0000000000..3cba801ea7 --- /dev/null +++ b/test/files/neg/t7509.scala @@ -0,0 +1,4 @@ +object NMWE { + def crash[R <: AnyRef](f: R)(implicit ev: R): Any = ??? + crash(42) +} -- cgit v1.2.3 From de12ca6ef8071820c6b2a9403ccab9aa6ed51c0b Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 23 May 2013 16:50:45 -0700 Subject: SI-7486 Regressions in implicit search. Revert e86832d7e8 and dd33e280e2. --- .../scala/tools/nsc/typechecker/Implicits.scala | 17 +++-------------- test/files/neg/t7441.check | 6 ------ test/files/neg/t7441.scala | 7 ------- test/files/pos/t7486.scala | 8 -------- test/pending/neg/t7441.check | 6 ++++++ test/pending/neg/t7441.scala | 7 +++++++ test/pending/pos/t7486.scala | 8 ++++++++ 7 files changed, 24 insertions(+), 35 deletions(-) delete mode 100644 test/files/neg/t7441.check delete mode 100644 test/files/neg/t7441.scala delete mode 100644 test/files/pos/t7486.scala create mode 100644 test/pending/neg/t7441.check create mode 100644 test/pending/neg/t7441.scala create mode 100644 test/pending/pos/t7486.scala (limited to 'test') diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index ef87a32c1d..35a4461ccc 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -997,22 +997,11 @@ trait Implicits { if (settings.Xdivergence211.value) DivergingImplicitExpansionError(tree, pt, DivergentImplicitRecovery.sym)(context) else throw DivergentImplicit } - else if (invalidImplicits.nonEmpty) { - val sym = invalidImplicits.head - // We don't even dare look if errors are being buffered - // !sym.hasFlag(LOCKED) is a hail mary between SI-2206 and SI-7486 - def isSensibleAddendum = !sym.hasFlag(LOCKED) && (pt match { - case Function1(_, out) => out <:< sym.tpe.finalResultType - case _ => pt <:< sym.tpe.finalResultType - }) - // Don't pitch in with this theory unless it looks plausible that the - // implicit would have helped + + if (invalidImplicits.nonEmpty) setAddendum(pos, () => - if (isSensibleAddendum) - s"\n Note: implicit $sym is not applicable here because it comes after the application point and it lacks an explicit result type" - else "" + s"\n Note: implicit ${invalidImplicits.head} is not applicable here because it comes after the application point and it lacks an explicit result type" ) - } } best diff --git a/test/files/neg/t7441.check b/test/files/neg/t7441.check deleted file mode 100644 index f259457197..0000000000 --- a/test/files/neg/t7441.check +++ /dev/null @@ -1,6 +0,0 @@ -t7441.scala:4: error: type mismatch; - found : Int(1) - required: List[Any] - def test = apply(1) - ^ -one error found diff --git a/test/files/neg/t7441.scala b/test/files/neg/t7441.scala deleted file mode 100644 index dad7421e3f..0000000000 --- a/test/files/neg/t7441.scala +++ /dev/null @@ -1,7 +0,0 @@ -object Test { - object Bar { - def apply(xs: List[Any]): Int = 0 - def test = apply(1) - } - implicit def foo = 1 -} diff --git a/test/files/pos/t7486.scala b/test/files/pos/t7486.scala deleted file mode 100644 index 6dd7f4c4ac..0000000000 --- a/test/files/pos/t7486.scala +++ /dev/null @@ -1,8 +0,0 @@ -object Test{ - var locker = 0 - // remove implicit, or change to `locker = locker + 1` to make it compile. - implicit val davyJones0 = { - locker += 0 - 0 - } -} diff --git a/test/pending/neg/t7441.check b/test/pending/neg/t7441.check new file mode 100644 index 0000000000..f259457197 --- /dev/null +++ b/test/pending/neg/t7441.check @@ -0,0 +1,6 @@ +t7441.scala:4: error: type mismatch; + found : Int(1) + required: List[Any] + def test = apply(1) + ^ +one error found diff --git a/test/pending/neg/t7441.scala b/test/pending/neg/t7441.scala new file mode 100644 index 0000000000..dad7421e3f --- /dev/null +++ b/test/pending/neg/t7441.scala @@ -0,0 +1,7 @@ +object Test { + object Bar { + def apply(xs: List[Any]): Int = 0 + def test = apply(1) + } + implicit def foo = 1 +} diff --git a/test/pending/pos/t7486.scala b/test/pending/pos/t7486.scala new file mode 100644 index 0000000000..6dd7f4c4ac --- /dev/null +++ b/test/pending/pos/t7486.scala @@ -0,0 +1,8 @@ +object Test{ + var locker = 0 + // remove implicit, or change to `locker = locker + 1` to make it compile. + implicit val davyJones0 = { + locker += 0 + 0 + } +} -- cgit v1.2.3 From bae4196b74981927c3d52dff9a4b0c3789baf733 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 27 May 2013 10:15:21 +0200 Subject: A test case for a recent LUB progression. A test distilled from a Lift example that compiles correctly under 2.10.1, but not under 2.10.0. I pinpointed the progression to: https://github.com/scala/scala/commit/a06d31f6#L0R6611 Chalk up another win for `dealiasWiden`. --- test/files/pos/lub-dealias-widen.scala | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 test/files/pos/lub-dealias-widen.scala (limited to 'test') diff --git a/test/files/pos/lub-dealias-widen.scala b/test/files/pos/lub-dealias-widen.scala new file mode 100644 index 0000000000..38854fbc5c --- /dev/null +++ b/test/files/pos/lub-dealias-widen.scala @@ -0,0 +1,34 @@ +import scala.language.higherKinds + +sealed trait Path { + type EncodeFunc + type Route[R] = List[String] => R + + def >>(f: Route[Int]): Sitelet[EncodeFunc] = ??? +} + +case object PAny extends Path { + type EncodeFunc = List[String] => String +} + +case class PLit[Next <: Path]() extends Path { + type EncodeFunc = Next#EncodeFunc +} + +trait Sitelet[EncodeFunc] { self => + def &[G <: H, H >: EncodeFunc](that: Sitelet[G]): Sitelet[H] = ??? +} + +object Test { + val r: Sitelet[Int => (Int => String)] = ??? + + val p2: PLit[PAny.type] = ??? + val r2 /*: Sitelet[List[String] => String] */ // annotate type and it compiles with 2.10.0 + = p2 >> { (xs: List[String]) => 0 } + + // This works after https://github.com/scala/scala/commit/a06d31f6a + // Before: error: inferred type arguments [List[String] => String,List[String] => String] + // do not conform to method &'s type parameter bounds + // [G <: H,H >: Int => (Int => String)] + val s = r & r2 +} \ No newline at end of file -- cgit v1.2.3 From 851e39991e7a929e1d83d5e35a024d5b9bd0b75f Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 27 May 2013 13:36:48 +0200 Subject: SI-7516 Revert "SI-7234 Make named args play nice w. depmet types" This reverts commit 83c9c764b528a7a1c1d39c480d22c8e3a71d5a58. The tests are shunted to 'pending'. Why revert this seemingly innocous commit? 83c9c764 generates a ValDef whose tpt TypeTree has no original; this contains a reference to the symbol for `d`. resetAttrs and the retypecheck assigns a new symbol for d and leaves a the reference to the prior symbol dangling. The real bug is the resetAttrs concept. --- .../scala/tools/nsc/typechecker/NamesDefaults.scala | 12 +++++++----- test/files/pos/t7234.scala | 15 --------------- test/files/pos/t7234b.scala | 20 -------------------- test/files/pos/t7516/A_1.scala | 9 +++++++++ test/files/pos/t7516/B_2.scala | 4 ++++ test/pending/pos/t7234.scala | 15 +++++++++++++++ test/pending/pos/t7234b.scala | 20 ++++++++++++++++++++ 7 files changed, 55 insertions(+), 40 deletions(-) delete mode 100644 test/files/pos/t7234.scala delete mode 100644 test/files/pos/t7234b.scala create mode 100644 test/files/pos/t7516/A_1.scala create mode 100644 test/files/pos/t7516/B_2.scala create mode 100644 test/pending/pos/t7234.scala create mode 100644 test/pending/pos/t7234b.scala (limited to 'test') diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 802df39f01..d54f894c62 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -284,11 +284,13 @@ trait NamesDefaults { self: Analyzer => case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe case _ => seqType(arg.tpe) } - else - // Note stabilizing can lead to a non-conformant argument when existentials are involved, e.g. neg/t3507-old.scala, hence the filter. - // We have to deconst or types inferred from literal arguments will be Constant(_), e.g. pos/z1730.scala. - gen.stableTypeFor(arg).filter(_ <:< paramTpe).getOrElse(arg.tpe).deconst - ) + else { + // TODO In 83c9c764b, we tried to a stable type here to fix SI-7234. But the resulting TypeTree over a + // singleton type without an original TypeTree fails to retypecheck after a resetLocalAttrs (SI-7516), + // which is important for (at least) macros. + arg.tpe + } + ).widen // have to widen or types inferred from literal defaults will be singletons val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos) setInfo ( if (byName) functionType(Nil, argTpe) else argTpe ) diff --git a/test/files/pos/t7234.scala b/test/files/pos/t7234.scala deleted file mode 100644 index 59a233d835..0000000000 --- a/test/files/pos/t7234.scala +++ /dev/null @@ -1,15 +0,0 @@ -trait Main { - trait A { - type B - } - trait C { - def c(a: A, x: Int = 0)(b: a.B) - } - def c: C - def d(a: A, x: Int = 0)(b: a.B) - - def ok1(a: A)(b: a.B) = c.c(a, 42)(b) - def ok2(a: A)(b: a.B) = d(a)(b) - - def fail(a: A)(b: a.B) = c.c(a)(b) -} diff --git a/test/files/pos/t7234b.scala b/test/files/pos/t7234b.scala deleted file mode 100644 index fee98e87a8..0000000000 --- a/test/files/pos/t7234b.scala +++ /dev/null @@ -1,20 +0,0 @@ -trait Main { - trait A { - type B - def b: B - } - trait C { - def c(a: A, x: Int = 0)(b: => a.B, bs: a.B*) - def d(a: A = null, x: Int = 0)(b1: => a.B = a.b, b2: a.B = a.b) - } - def c: C - def ok(a: A)(b: a.B) = c.c(a, 42)(b) - def fail(a: A)(b: a.B) = c.c(a)(b) - def fail2(a: A)(b: a.B) = c.c(a)(b, b) - def fail3(a: A)(b: a.B) = c.c(a)(b, Seq[a.B](b): _*) - - def fail4(a: A)(b: a.B) = c.d(a)() - def fail5(a: A)(b: a.B) = c.d(a)(b1 = a.b) - def fail6(a: A)(b: a.B) = c.d(a)(b2 = a.b) - def fail7(a: A)(b: a.B) = c.d()() -} diff --git a/test/files/pos/t7516/A_1.scala b/test/files/pos/t7516/A_1.scala new file mode 100644 index 0000000000..3bba19966d --- /dev/null +++ b/test/files/pos/t7516/A_1.scala @@ -0,0 +1,9 @@ +import scala.reflect._,macros._, scala.language.experimental.macros + +object A { + def impl[T: c.WeakTypeTag](c: Context)(t: c.Expr[T]): c.Expr[List[T]] = { + val r = c.universe.reify { List(t.splice) } + c.Expr[List[T]]( c.resetLocalAttrs(r.tree) ) + } + def demo[T](t: T): List[T] = macro impl[T] +} diff --git a/test/files/pos/t7516/B_2.scala b/test/files/pos/t7516/B_2.scala new file mode 100644 index 0000000000..1b8531bc85 --- /dev/null +++ b/test/files/pos/t7516/B_2.scala @@ -0,0 +1,4 @@ +object B { + final case class CV(p: Int = 3, g: Int = 2) + A.demo { val d = 4; CV(g = d); "a" } +} diff --git a/test/pending/pos/t7234.scala b/test/pending/pos/t7234.scala new file mode 100644 index 0000000000..59a233d835 --- /dev/null +++ b/test/pending/pos/t7234.scala @@ -0,0 +1,15 @@ +trait Main { + trait A { + type B + } + trait C { + def c(a: A, x: Int = 0)(b: a.B) + } + def c: C + def d(a: A, x: Int = 0)(b: a.B) + + def ok1(a: A)(b: a.B) = c.c(a, 42)(b) + def ok2(a: A)(b: a.B) = d(a)(b) + + def fail(a: A)(b: a.B) = c.c(a)(b) +} diff --git a/test/pending/pos/t7234b.scala b/test/pending/pos/t7234b.scala new file mode 100644 index 0000000000..fee98e87a8 --- /dev/null +++ b/test/pending/pos/t7234b.scala @@ -0,0 +1,20 @@ +trait Main { + trait A { + type B + def b: B + } + trait C { + def c(a: A, x: Int = 0)(b: => a.B, bs: a.B*) + def d(a: A = null, x: Int = 0)(b1: => a.B = a.b, b2: a.B = a.b) + } + def c: C + def ok(a: A)(b: a.B) = c.c(a, 42)(b) + def fail(a: A)(b: a.B) = c.c(a)(b) + def fail2(a: A)(b: a.B) = c.c(a)(b, b) + def fail3(a: A)(b: a.B) = c.c(a)(b, Seq[a.B](b): _*) + + def fail4(a: A)(b: a.B) = c.d(a)() + def fail5(a: A)(b: a.B) = c.d(a)(b1 = a.b) + def fail6(a: A)(b: a.B) = c.d(a)(b2 = a.b) + def fail7(a: A)(b: a.B) = c.d()() +} -- cgit v1.2.3 From 403eadd0f10cf6e493b81913148b0b9065e80699 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 29 May 2013 23:44:21 +0200 Subject: SI-7517 Fix higher kinded type inference regression - Discovered in 2.10.2-RC1 - Ostensibly regressed in 7e52fb910b, which conceptually reverted part of 0cde930b so that (mutable) TypeVars don't use structural equality. - But, does *not* fail if 7e52fb910b is cherry-picked directly after 0cde930b, suggesting that it shone a light on a behaviour change in some other commit in between the two. - Indeed, the true regression came in https://github.com/scala/scala/commit/e5da30b843#L5L3176 - A targeted revert of e5da30b843 is undesirable, as we'd like SI-6846 to stay fixed What's happening here? In the enclosed test case, higher kinded type inference explores two possibilities: Composed.this.Split[A] K[[T]A[B[T]]] // `Split[A]` dealiased The difference in the flow of type inference can be seen from the diff below. Notice how now we no longer register `?K.addBound(Composed.this.Split)`, we instead only register `?K.addBound(K)` ```patch --- sandbox/old.log 2013-05-30 00:27:34.000000000 +0200 +++ sandbox/new.log 2013-05-30 00:28:28.000000000 +0200 @@ -1,55 +1,114 @@ ?K.unifyFull(Composed.this.Split[A]) ?K.unifySpecific(Composed.this.Split[A]) - ?K.addBound(Composed.this.Split) ?B.unifyFull(T) ?B.unifySpecific(T) `-> false ?B.unifyFull(Any) ?B.unifySpecific(Any) `-> false `-> false ?K.unifySpecific(L[[T]A[B[T]]]) - ?K.addBound(L) ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true + ?K.addBound(L) `-> true ?K.unifyFull(Composed.this.Split[A]) ?K.unifySpecific(Composed.this.Split[A]) - ?K.addBound(Composed.this.Split) ?B.unifyFull(x) ?B.unifySpecific(x) `-> false `-> false ?K.unifySpecific(L[[T]A[B[T]]]) + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true ?K.addBound(L) + `-> true +?K.unifyFull(Composed.this.Split[A]) + ?K.unifySpecific(Composed.this.Split[A]) + ?B.unifyFull(T) + ?B.unifySpecific(T) + `-> false + ?B.unifyFull(Any) + ?B.unifySpecific(Any) + `-> false + `-> false + ?K.unifySpecific(L[[T]A[B[T]]]) ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true ?B.unifyFull(B[T]) ?B.unifySpecific(B[T]) ?B.addBound(B) `-> true + ?K.addBound(L) + `-> true +?K.unifyFull(Composed.this.Split[A]) + ?K.unifySpecific(Composed.this.Split[A]) + ?B.unifyFull(x) + ?B.unifySpecific(x) + `-> false + `-> false + ?K.unifySpecific(L[[T]A[B[T]]]) + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?B.unifyFull(B[T]) + ?B.unifySpecific(B[T]) + ?B.addBound(B) + `-> true + ?K.addBound(L) + `-> true +?K.unifyFull(L[A]) + ?K.unifySpecific(L[A]) + ?K.addBound(L) + `-> true +?K.unifyFull(L[A]) + ?K.unifySpecific(L[A]) + ?K.addBound(L) `-> true ``` --- src/reflect/scala/reflect/internal/Types.scala | 7 +++---- test/files/pos/t7517.scala | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 test/files/pos/t7517.scala (limited to 'test') diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index ee584bed2c..0cc2b91a44 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3218,10 +3218,9 @@ trait Types extends api.Types { self: SymbolTable => sameLength(typeArgs, tp.typeArgs) && { val lhs = if (isLowerBound) tp.typeArgs else typeArgs val rhs = if (isLowerBound) typeArgs else tp.typeArgs - // this is a higher-kinded type var with same arity as tp. - // side effect: adds the type constructor itself as a bound - addBound(tp.typeConstructor) - isSubArgs(lhs, rhs, params, AnyDepth) + // This is a higher-kinded type var with same arity as tp. + // If so (see SI-7517), side effect: adds the type constructor itself as a bound. + isSubArgs(lhs, rhs, params, AnyDepth) && { addBound(tp.typeConstructor); true } } } // The type with which we can successfully unify can be hidden diff --git a/test/files/pos/t7517.scala b/test/files/pos/t7517.scala new file mode 100644 index 0000000000..7ce4c6b13e --- /dev/null +++ b/test/files/pos/t7517.scala @@ -0,0 +1,22 @@ +trait Box[ K[A[x]] ] + +object Box { + // type constructor composition + sealed trait ∙[A[_], B[_]] { type l[T] = A[B[T]] } + + // composes type constructors inside K + type SplitBox[K[A[x]], B[x]] = Box[ ({ type l[A[x]] = K[ (A ∙ B)#l] })#l ] + + def split[ K[A[x]], B[x] ](base: Box[K]): SplitBox[K,B] = ??? + + class Composed[B[_], L[A[x]] ] { + val box: Box[L] = ??? + + type Split[ A[x] ] = L[ (A ∙ B)#l ] + val a: Box[Split] = Box.split(box) + + //Either of these work: + val a1: Box[Split] = Box.split[L,B](box) + val a2: Box[ ({ type l[A[x]] = L[ (A ∙ B)#l ] })#l ] = Box.split(box) + } +} \ No newline at end of file -- cgit v1.2.3 From 75251f76001d3c781b0630c2061603ebb250a787 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 30 May 2013 09:26:46 +0200 Subject: SI-7532 Fix regression in Java inner classfile reader 395e90a modified the detection of top-level classes in ClassfileParser in two ways: 1. used `Name#containsChar` rather than `toString.indexOf ...` (good!) 2. decoded the name before doing this check (bad!) That code is actually only run for non-Scala classfiles, whose names don't need decoding. Attempting to do so converted `R$attr` to `R@tr`, which no longer contains a '$', and was wrongly treated as a top level class. This commit reverts the use of `decodedName`, and inlines the method to its only call site for clarity. --- .../scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 8 ++++---- test/files/pos/t7532/A_1.java | 6 ++++++ test/files/pos/t7532/B_2.scala | 5 +++++ test/files/pos/t7532b/A_1.scala | 7 +++++++ test/files/pos/t7532b/B_2.scala | 8 ++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 test/files/pos/t7532/A_1.java create mode 100644 test/files/pos/t7532/B_2.scala create mode 100644 test/files/pos/t7532b/A_1.scala create mode 100644 test/files/pos/t7532b/B_2.scala (limited to 'test') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index da117540b4..47a8b1f947 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -44,8 +44,6 @@ abstract class ClassfileParser { def srcfile = srcfile0 - private def currentIsTopLevel = !(currentClass.decodedName containsChar '$') - private object unpickler extends scala.reflect.internal.pickling.UnPickler { val global: ClassfileParser.this.global.type = ClassfileParser.this.global } @@ -515,8 +513,10 @@ abstract class ClassfileParser { } } - val c = if (currentIsTopLevel) pool.getClassSymbol(nameIdx) else clazz - if (currentIsTopLevel) { + val isTopLevel = !(currentClass containsChar '$') // Java class name; *don't* try to to use Scala name decoding (SI-7532) + + val c = if (isTopLevel) pool.getClassSymbol(nameIdx) else clazz + if (isTopLevel) { if (c != clazz) { if ((clazz eq NoSymbol) && (c ne NoSymbol)) clazz = c else mismatchError(c) diff --git a/test/files/pos/t7532/A_1.java b/test/files/pos/t7532/A_1.java new file mode 100644 index 0000000000..1ade76cc70 --- /dev/null +++ b/test/files/pos/t7532/A_1.java @@ -0,0 +1,6 @@ +class R { + public class attr { // Will have the bytecode name `R$attr`, not to be confused with `R@tr`! + } + public static class attr1 { + } +} diff --git a/test/files/pos/t7532/B_2.scala b/test/files/pos/t7532/B_2.scala new file mode 100644 index 0000000000..ee7ce7751f --- /dev/null +++ b/test/files/pos/t7532/B_2.scala @@ -0,0 +1,5 @@ +object Test { + val r = new R + new r.attr() // Was: error while loading attr, class file '.../t7532-pos.obj/R$attr.class' has location not matching its contents: contains class + new R.attr1 +} \ No newline at end of file diff --git a/test/files/pos/t7532b/A_1.scala b/test/files/pos/t7532b/A_1.scala new file mode 100644 index 0000000000..e8f9540609 --- /dev/null +++ b/test/files/pos/t7532b/A_1.scala @@ -0,0 +1,7 @@ +package pack +class R { + class attr // Will have the bytecode name `R$attr`, not to be confused with `R@tr`! + class `@` +} + +class `@` \ No newline at end of file diff --git a/test/files/pos/t7532b/B_2.scala b/test/files/pos/t7532b/B_2.scala new file mode 100644 index 0000000000..1555a5daa7 --- /dev/null +++ b/test/files/pos/t7532b/B_2.scala @@ -0,0 +1,8 @@ +import pack._ + +object Test { + val r = new R + new r.attr() + new r.`@` + new `@` +} \ No newline at end of file -- cgit v1.2.3 From d2faeb9ae60389668f1b5f45eb91c73127401e40 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 23 May 2013 09:25:11 +0200 Subject: SI-7507 Fix lookup of private[this] member in presence of self type. In the following code: trait Cake extends Slice trait Slice { self: Cake => // must have self type that extends `Slice` private[this] val bippy = () // must be private[this] locally(bippy) } `ThisType()`.findMember(bippy)` excluded the private local member on the grounds that the first class in the base type sequence, `Cake`, was not contained in `Slice`. scala> val thisType = typeOf[Slice].typeSymbol.thisType thisType: $r.intp.global.Type = Slice.this.type scala> thisType.baseClasses res6: List[$r.intp.global.Symbol] = List(trait Cake, trait Slice, class Object, class Any) This commit changes `findMember` to use the symbol of the `ThisType`, rather than the first base class, as the location of the selection. --- src/reflect/scala/reflect/internal/Types.scala | 12 ++++++++-- test/files/neg/t7507.check | 4 ++++ test/files/neg/t7507.scala | 7 ++++++ test/files/run/t7507.scala | 31 ++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 test/files/neg/t7507.check create mode 100644 test/files/neg/t7507.scala create mode 100644 test/files/run/t7507.scala (limited to 'test') diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index ee584bed2c..fc3f5de77f 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1172,6 +1172,14 @@ trait Types extends api.Types { self: SymbolTable => continue = false val bcs0 = baseClasses var bcs = bcs0 + // omit PRIVATE LOCALS unless selector class is contained in class owning the def. + def admitPrivateLocal(owner: Symbol): Boolean = { + val selectorClass = this match { + case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class. + case _ => bcs0.head + } + selectorClass.hasTransOwner(owner) + } while (!bcs.isEmpty) { val decls = bcs.head.info.decls var entry = decls.lookupEntry(name) @@ -1181,10 +1189,10 @@ trait Types extends api.Types { self: SymbolTable => if ((flags & required) == required) { val excl = flags & excluded if (excl == 0L && - (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. + ( (bcs eq bcs0) || (flags & PrivateLocal) != PrivateLocal || - (bcs0.head.hasTransOwner(bcs.head)))) { + admitPrivateLocal(bcs.head))) { if (name.isTypeName || stableOnly && sym.isStable) { if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start) if (suspension ne null) suspension foreach (_.suspended = false) diff --git a/test/files/neg/t7507.check b/test/files/neg/t7507.check new file mode 100644 index 0000000000..d402869fd4 --- /dev/null +++ b/test/files/neg/t7507.check @@ -0,0 +1,4 @@ +t7507.scala:6: error: value bippy in trait Cake cannot be accessed in Cake + locally(bippy) + ^ +one error found diff --git a/test/files/neg/t7507.scala b/test/files/neg/t7507.scala new file mode 100644 index 0000000000..1b4756d955 --- /dev/null +++ b/test/files/neg/t7507.scala @@ -0,0 +1,7 @@ +trait Cake extends Slice { + private[this] val bippy = () +} + +trait Slice { self: Cake => + locally(bippy) +} diff --git a/test/files/run/t7507.scala b/test/files/run/t7507.scala new file mode 100644 index 0000000000..6c1959ddac --- /dev/null +++ b/test/files/run/t7507.scala @@ -0,0 +1,31 @@ +trait Cake extends Slice + +// Minimization +trait Slice { self: Cake => // must have self type that extends `Slice` + private[this] val bippy = () // must be private[this] + locally(bippy) +} + +// Originally reported bug: +trait Cake1 extends Slice1 +trait Slice1 { self: Cake1 => + import java.lang.String // any import will do! + val Tuple2(x, y) = ((1, 2)) +} + + +// Nesting +trait Cake3 extends Outer.Slice3 + +// Minimization +object Outer { + private[this] val bippy = () + trait Slice3 { self: Cake3 => + locally(bippy) + } +} + +object Test extends App { + val s1 = new Cake1 {} + assert((s1.x, s1.y) == (1, 2), (s1.x, s1.y)) +} -- cgit v1.2.3 From 4dc3a3319705ba9cdf63978bbed9a2fc8051b34f Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 31 May 2013 23:03:25 +0200 Subject: SI-7375 ClassTag for value class aliases reifyRuntimeClass now always dealiases its argument prior to processing. --- src/compiler/scala/reflect/reify/package.scala | 7 +++++-- test/files/run/t7375a.check | 4 ++++ test/files/run/t7375a.scala | 16 ++++++++++++++++ test/files/run/t7375b.check | 4 ++++ test/files/run/t7375b/Macros_1.scala | 18 ++++++++++++++++++ test/files/run/t7375b/Test_2.scala | 3 +++ 6 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 test/files/run/t7375a.check create mode 100644 test/files/run/t7375a.scala create mode 100644 test/files/run/t7375b.check create mode 100644 test/files/run/t7375b/Macros_1.scala create mode 100644 test/files/run/t7375b/Test_2.scala (limited to 'test') diff --git a/src/compiler/scala/reflect/reify/package.scala b/src/compiler/scala/reflect/reify/package.scala index 55f8684df2..6777bb0a50 100644 --- a/src/compiler/scala/reflect/reify/package.scala +++ b/src/compiler/scala/reflect/reify/package.scala @@ -45,18 +45,21 @@ package object reify { def reifyType(global: Global)(typer: global.analyzer.Typer,universe: global.Tree, mirror: global.Tree, tpe: global.Type, concrete: Boolean = false): global.Tree = mkReifier(global)(typer, universe, mirror, tpe, concrete = concrete).reification.asInstanceOf[global.Tree] - def reifyRuntimeClass(global: Global)(typer0: global.analyzer.Typer, tpe: global.Type, concrete: Boolean = true): global.Tree = { + def reifyRuntimeClass(global: Global)(typer0: global.analyzer.Typer, tpe0: global.Type, concrete: Boolean = true): global.Tree = { import global._ import definitions._ import analyzer.enclosingMacroPosition + // SI-7375 + val tpe = tpe0.dealiasWiden + if (tpe.isSpliceable) { val classTagInScope = typer0.resolveClassTag(enclosingMacroPosition, tpe, allowMaterialization = false) if (!classTagInScope.isEmpty) return Select(classTagInScope, nme.runtimeClass) if (concrete) throw new ReificationException(enclosingMacroPosition, "tpe %s is an unresolved spliceable type".format(tpe)) } - tpe.normalize match { + tpe match { case TypeRef(_, ArrayClass, componentTpe :: Nil) => val componentErasure = reifyRuntimeClass(global)(typer0, componentTpe, concrete) gen.mkMethodCall(arrayClassMethod, List(componentErasure)) diff --git a/test/files/run/t7375a.check b/test/files/run/t7375a.check new file mode 100644 index 0000000000..a0a15dfb2f --- /dev/null +++ b/test/files/run/t7375a.check @@ -0,0 +1,4 @@ +C1 +C2 +C1 +C2 diff --git a/test/files/run/t7375a.scala b/test/files/run/t7375a.scala new file mode 100644 index 0000000000..e46ad08f63 --- /dev/null +++ b/test/files/run/t7375a.scala @@ -0,0 +1,16 @@ +import scala.reflect.ClassTag + +class C1(val n: Int) extends AnyVal +class C2(val n: Int) extends AnyRef + +object Test { + type F1 = C1 + type F2 = C2 + + def main(args: Array[String]): Unit = { + println(implicitly[ClassTag[C1]]) + println(implicitly[ClassTag[C2]]) + println(implicitly[ClassTag[F1]]) + println(implicitly[ClassTag[F2]]) + } +} diff --git a/test/files/run/t7375b.check b/test/files/run/t7375b.check new file mode 100644 index 0000000000..d7578e28ba --- /dev/null +++ b/test/files/run/t7375b.check @@ -0,0 +1,4 @@ +Predef.this.classOf[C1] +Predef.this.classOf[C2] +Predef.this.classOf[C1] +Predef.this.classOf[C2] diff --git a/test/files/run/t7375b/Macros_1.scala b/test/files/run/t7375b/Macros_1.scala new file mode 100644 index 0000000000..70e79cc2b4 --- /dev/null +++ b/test/files/run/t7375b/Macros_1.scala @@ -0,0 +1,18 @@ +import language.experimental.macros +import scala.reflect.macros.Context + +class C1(val n: Int) extends AnyVal +class C2(val n: Int) extends AnyRef + +object Macros { + type F1 = C1 + type F2 = C2 + + def foo = macro impl + def impl(c: Context) = { + import c.universe._ + def test[T: c.TypeTag] = reify(println(c.literal(c.reifyRuntimeClass(c.typeOf[T]).toString).splice)).tree + def tests = Block(List(test[C1], test[C2], test[F1], test[F2]), Literal(Constant(()))) + c.Expr[Unit](tests) + } +} \ No newline at end of file diff --git a/test/files/run/t7375b/Test_2.scala b/test/files/run/t7375b/Test_2.scala new file mode 100644 index 0000000000..acfddae942 --- /dev/null +++ b/test/files/run/t7375b/Test_2.scala @@ -0,0 +1,3 @@ +object Test extends App { + Macros.foo +} \ No newline at end of file -- cgit v1.2.3