Skip to content

Commit

Permalink
Merge remote-tracking branches 'retronym/ticket/5407', 'scalamacros/t…
Browse files Browse the repository at this point in the history
…opic/macrocherrypick', 'lrytz/t5626', 'lrytz/t5009', 'retronym/ticket/5029', 'retronym/ticket/4025', 'retronym/topic/quieter-nsdhnao' and 'retronym/ticket/1133' into develop
  • Loading branch information
paulp committed May 12, 2012
9 parents d55ea54 + f707141 + 364deb0 + 0c5de3c + 40e7cab + 6e2d3f0 + 3bbf632 + 716b2a7 + ba123f0 commit 255cd51
Show file tree
Hide file tree
Showing 20 changed files with 333 additions and 136 deletions.
2 changes: 1 addition & 1 deletion lib/scala-compiler.jar.desired.sha1
@@ -1 +1 @@
c020eccb8cf37963725985f36b44d070915cf4d2 ?scala-compiler.jar
5b3f50d124f84dcda869e17fb0cfd605ed40f385 ?scala-compiler.jar
2 changes: 1 addition & 1 deletion lib/scala-library.jar.desired.sha1
@@ -1 +1 @@
31c7188cef85c28b84b9ce35bc6780996e5dd139 ?scala-library.jar
8f19876a8908e7d7d2a140a8434805cfec2c1346 ?scala-library.jar
2 changes: 1 addition & 1 deletion src/compiler/scala/reflect/internal/Symbols.scala
Expand Up @@ -3054,7 +3054,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def originalEnclosingMethod = this

override def owner: Symbol =
abort("no-symbol does not have an owner (this is a bug: scala " + scala.util.Properties.versionString + ")")
abort("no-symbol does not have an owner")
override def typeConstructor: Type =
abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)")
}
Expand Down
19 changes: 15 additions & 4 deletions src/compiler/scala/tools/nsc/typechecker/Implicits.scala
Expand Up @@ -1133,16 +1133,27 @@ trait Implicits {
* An EmptyTree is returned if materialization fails.
*/
private def tagOfType(pre: Type, tp: Type, tagClass: Symbol): SearchResult = {
def success(arg: Tree) =
def success(arg: Tree) = {
def isMacroException(msg: String): Boolean =
// [Eugene] very unreliable, ask Hubert about a better way
msg contains "exception during macro expansion"

def processMacroExpansionError(pos: Position, msg: String): SearchResult = {
// giving up and reporting all macro exceptions regardless of their source
// this might lead to an avalanche of errors if one of your implicit macros misbehaves
if (isMacroException(msg)) context.error(pos, msg)
failure(arg, "failed to typecheck the materialized tag: %n%s".format(msg), pos)
}

try {
val tree1 = typed(atPos(pos.focus)(arg))
def isErroneous = tree exists (_.isErroneous)
if (context.hasErrors) failure(tp, "failed to typecheck the materialized typetag: %n%s".format(context.errBuffer.head.errMsg), context.errBuffer.head.errPos)
if (context.hasErrors) processMacroExpansionError(context.errBuffer.head.errPos, context.errBuffer.head.errMsg)
else new SearchResult(tree1, EmptyTreeTypeSubstituter)
} catch {
case ex: TypeError =>
failure(arg, "failed to typecheck the materialized typetag: %n%s".format(ex.msg), ex.pos)
processMacroExpansionError(ex.pos, ex.msg)
}
}

val prefix = (
// ClassTags only exist for scala.reflect.mirror, so their materializer
Expand Down
274 changes: 157 additions & 117 deletions src/compiler/scala/tools/nsc/typechecker/Macros.scala

Large diffs are not rendered by default.

19 changes: 17 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
Expand Up @@ -1488,8 +1488,23 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R

private def transformCaseApply(tree: Tree, ifNot: => Unit) = {
val sym = tree.symbol

if (sym.isSourceMethod && sym.isCase && sym.name == nme.apply)

def isClassTypeAccessible(tree: Tree): Boolean = tree match {
case TypeApply(fun, targs) =>
isClassTypeAccessible(fun)
case Select(module, apply) =>
// Fixes SI-5626. Classes in refinement types cannot be constructed with `new`. In this case,
// the companion class is actually not a ClassSymbol, but a reference to an abstract type.
module.symbol.companionClass.isClass
}

val doTransform =
sym.isSourceMethod &&
sym.isCase &&
sym.name == nme.apply &&
isClassTypeAccessible(tree)

if (doTransform)
toConstructor(tree.pos, tree.tpe)
else {
ifNot
Expand Down
22 changes: 17 additions & 5 deletions src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
Expand Up @@ -210,13 +210,25 @@ trait Unapplies extends ast.TreeDSL
// and re-added in ``finishWith'' in the namer.
def paramWithDefault(vd: ValDef) =
treeCopy.ValDef(vd, vd.mods | DEFAULTPARAM, vd.name, atPos(vd.pos.focus)(TypeTree() setOriginal vd.tpt), toIdent(vd))

val paramss = mmap(cparamss)(paramWithDefault)
val classTpe = classType(cdef, tparams)

val (copyParamss, funParamss) = cparamss match {
case Nil => (Nil, Nil)
case ps :: pss =>
(List(ps.map(paramWithDefault)), mmap(pss)(p => copyUntyped[ValDef](p).copy(rhs = EmptyTree)))
}

val classTpe = classType(cdef, tparams)
val bodyTpe = funParamss.foldRight(classTpe)((params, restp) => gen.scalaFunctionConstr(params.map(_.tpt), restp))

val argss = copyParamss match {
case Nil => Nil
case ps :: Nil => mmap(ps :: funParamss)(toIdent)
}
val body = funParamss.foldRight(New(classTpe, argss): Tree)(Function)

Some(atPos(cdef.pos.focus)(
DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, paramss, classTpe,
New(classTpe, mmap(paramss)(toIdent)))
DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, copyParamss, bodyTpe,
body)
))
}
}
Expand Down
32 changes: 32 additions & 0 deletions test/files/pos/t1133.scala
@@ -0,0 +1,32 @@
object Match
{
def main(args: Array[String]) = {
args(0) match {
case Extractor1(Extractor2(Extractor3("dog", "dog", "dog"), x2, x3), b, c, Extractor3("b", "b", f), e) => println(e)
case Extractor3(Extractor2(Extractor1("a", "aa", "aaa", "aa", "a"), Extractor2("a", "aa", "aaa"), e), y, z) => println(e)
case Extractor2(Extractor3("a", "a", x), Extractor3("b", "b", y), Extractor3("c", "c", z)) => println(z)
case _ => println("fail")
}
}

object Extractor1 {
def unapply(x: Any) = x match {
case x: String => Some(x, x+x, x+x+x, x+x, x)
case _ => None
}
}

object Extractor2 {
def unapply(x: Any) = x match {
case x: String => Some(x, x+x, x+x+x)
case _ => None
}
}

object Extractor3 {
def unapply(x: Any) = x match {
case x: String => Some(x, x, x)
case _ => None
}
}
}
1 change: 1 addition & 0 deletions test/files/pos/t5029.flags
@@ -0,0 +1 @@
-Xfatal-warnings
3 changes: 3 additions & 0 deletions test/files/pos/t5029.scala
@@ -0,0 +1,3 @@
object Test {
(Vector(): Seq[_]) match { case List() => true; case Nil => false }
}
12 changes: 12 additions & 0 deletions test/files/pos/t5626.scala
@@ -0,0 +1,12 @@
class C {
val blob = {
new { case class Foo() }
}
val blub = {
class Inner { case class Foo() }
new Inner
}

val foo = blob.Foo()
val bar = blub.Foo()
}
4 changes: 2 additions & 2 deletions test/files/pos/t5720-ownerous.scala
Expand Up @@ -28,10 +28,10 @@ class C {
//def model = Option(M("foo")()).getOrElse(M("bar")()).copy(currentUser = "")()

// the bug
def model = Option(m).getOrElse(M("bar")()).copy("baz")()
def model = Option(m).getOrElse(M("bar")()).copy("baz")("empty")

// style points for this version
def modish = ((null: Option[M]) getOrElse new M()()).copy()()
def modish = ((null: Option[M]) getOrElse new M()()).copy()("empty")

// various simplifications are too simple
case class N(currentUser: String = "anon")
Expand Down
2 changes: 1 addition & 1 deletion test/files/run/names-defaults.check
Expand Up @@ -92,7 +92,7 @@ test5
test5
5
10: 2
slkdfj1
slkdfj2
1
lskfdjlk
11
Expand Down
4 changes: 2 additions & 2 deletions test/files/run/names-defaults.scala
Expand Up @@ -176,7 +176,7 @@ object Test extends App {

println(Fact2()("jyp"))
println(Fact2(x = 1)())
println(Fact2(10)().copy(y = "blabla")())
println(Fact2(10)().copy(y = "blabla")(3))


// assignment to var <-> named argument
Expand All @@ -195,7 +195,7 @@ object Test extends App {
// dependent types and copy method
val a11 = new A2
val b11 = a11.B2(new a11.C2)(1)
println(b11.copy()())
println(b11.copy()(2))



Expand Down
19 changes: 19 additions & 0 deletions test/files/run/t4025.check
@@ -0,0 +1,19 @@
Type in expressions to have them evaluated.
Type :help for more information.

scala>

scala> class Color(val red: Int)
defined class Color

scala>

scala> case class Red(r:Int) extends Color(r)
defined class Red

scala>

scala> def f(c: Any) = c match { case Red(_) => () }
f: (c: Any)Unit

scala>
12 changes: 12 additions & 0 deletions test/files/run/t4025.scala
@@ -0,0 +1,12 @@
import scala.tools.nsc.Settings
import scala.tools.partest.ReplTest

object Test extends ReplTest {
def code = """
class Color(val red: Int)
case class Red(r:Int) extends Color(r)
def f(c: Any) = c match { case Red(_) => () }
"""
}
4 changes: 4 additions & 0 deletions test/files/run/t5009.check
@@ -0,0 +1,4 @@
C(1,true)
10
C(7283,20)
100
17 changes: 17 additions & 0 deletions test/files/run/t5009.scala
@@ -0,0 +1,17 @@
object Test extends App {

case class C[T, U <: String, O >: Object](x: Int, y: T)(z: U, b: Boolean)(s: O, val l: Int)

val c = C(1, true)("dlkfj", true)("dlkfjlk", 10)
println(c)
println(c.l)

val f1a = c.copy(y = 20, x = 7283)

val f1b = c.copy[Int, String, Object](y = 20, x = 7283)
val f2b = f1b("lkdjen", false)
val res = f2b(new Object, 100)
println(res)
println(res.l)

}
2 changes: 2 additions & 0 deletions test/files/run/t5407.check
@@ -0,0 +1,2 @@
2
2
17 changes: 17 additions & 0 deletions test/files/run/t5407.scala
@@ -0,0 +1,17 @@
case class Foo(private val x: Int, y: Option[Int], z: Boolean)

object Test extends App {
def foo(x: Foo) = x match {
case Foo(x, Some(y), z) => y
case Foo(x, y, z) => 0
}
val x = Foo(1, Some(2), false)
println(foo(x))


def bar(x: Foo) = x match {
case Foo(x, Some(y), z) => y
case Foo(x, None, z) => 0
}
println(bar(x))
}

0 comments on commit 255cd51

Please sign in to comment.