diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/javac/JavaParsers.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala | 17 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala | 2 | ||||
-rw-r--r-- | test/files/pos/t8719.check | 0 | ||||
-rw-r--r-- | test/files/pos/t8719/Macros_1.scala | 21 | ||||
-rw-r--r-- | test/files/pos/t8719/Test_2.scala | 10 | ||||
-rw-r--r-- | test/files/run/t8852a.scala | 34 |
9 files changed, 81 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 37b00aa9a3..9433ddcf31 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -488,7 +488,8 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { val vparams = formalParams() if (!isVoid) rtpt = optArrayBrackets(rtpt) optThrows() - val bodyOk = !inInterface || (mods hasFlag Flags.DEFAULTMETHOD) + val isStatic = mods hasFlag Flags.STATIC + val bodyOk = !inInterface || ((mods hasFlag Flags.DEFAULTMETHOD) || isStatic) val body = if (bodyOk && in.token == LBRACE) { methodBody() @@ -507,7 +508,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { EmptyTree } } - if (inInterface) mods1 |= Flags.DEFERRED + if (inInterface && !isStatic) mods1 |= Flags.DEFERRED List { atPos(pos) { DefDef(mods1, name.toTermName, tparams, List(vparams), rtpt, body) diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 9b85f1b36a..3544dc9966 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -459,7 +459,7 @@ abstract class UnCurry extends InfoTransform case UnApply(fn, args) => val fn1 = transform(fn) val args1 = fn.symbol.name match { - case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, patmat.alignPatterns(tree).expectedTypes) + case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, patmat.alignPatterns(global.typer.context, tree).expectedTypes) case _ => args } treeCopy.UnApply(tree, fn1, args1) diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala index 0eaffe7cee..d862805a07 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTranslation.scala @@ -377,8 +377,8 @@ trait MatchTranslation { object ExtractorCall { // TODO: check unargs == args def apply(tree: Tree): ExtractorCall = tree match { - case UnApply(unfun, args) => new ExtractorCallRegular(alignPatterns(tree), unfun, args) // extractor - case Apply(fun, args) => new ExtractorCallProd(alignPatterns(tree), fun, args) // case class + case UnApply(unfun, args) => new ExtractorCallRegular(alignPatterns(context, tree), unfun, args) // extractor + case Apply(fun, args) => new ExtractorCallProd(alignPatterns(context, tree), fun, args) // case class } } diff --git a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala index 8f21f4ecfc..79f5e3bee8 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala @@ -18,6 +18,7 @@ trait ScalacPatternExpanders { import global._ import definitions._ import treeInfo._ + import analyzer._ type PatternAligned = ScalacPatternExpander#Aligned @@ -94,7 +95,7 @@ trait ScalacPatternExpanders { def tupleExtractor(extractor: Extractor): Extractor = extractor.copy(fixed = tupleType(extractor.fixed) :: Nil) - private def validateAligned(tree: Tree, aligned: Aligned): Aligned = { + private def validateAligned(context: Context, tree: Tree, aligned: Aligned): Aligned = { import aligned._ def owner = tree.symbol.owner @@ -103,8 +104,8 @@ trait ScalacPatternExpanders { def offerString = if (extractor.isErroneous) "" else s" offering $offering" def arityExpected = ( if (extractor.hasSeq) "at least " else "" ) + productArity - def err(msg: String) = reporter.error(tree.pos, msg) - def warn(msg: String) = reporter.warning(tree.pos, msg) + def err(msg: String) = context.error(tree.pos, msg) + def warn(msg: String) = context.warning(tree.pos, msg) def arityError(what: String) = err(s"$what patterns for $owner$offerString: expected $arityExpected, found $totalArity") if (isStar && !isSeq) @@ -117,7 +118,7 @@ trait ScalacPatternExpanders { aligned } - def apply(sel: Tree, args: List[Tree]): Aligned = { + def apply(context: Context, sel: Tree, args: List[Tree]): Aligned = { val fn = sel match { case Unapplied(fn) => fn case _ => sel @@ -145,12 +146,12 @@ trait ScalacPatternExpanders { } val normalizedExtractor = if (requiresTupling) tupleExtractor(extractor) else extractor - validateAligned(fn, Aligned(patterns, normalizedExtractor)) + validateAligned(context, fn, Aligned(patterns, normalizedExtractor)) } - def apply(tree: Tree): Aligned = tree match { - case Apply(fn, args) => apply(fn, args) - case UnApply(fn, args) => apply(fn, args) + def apply(context: Context, tree: Tree): Aligned = tree match { + case Apply(fn, args) => apply(context, fn, args) + case UnApply(fn, args) => apply(context, fn, args) } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala index da0e67a2a5..bb8c3c3c6d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala @@ -309,7 +309,7 @@ trait PatternTypers { // the union of the expected type and the inferred type of the argument to unapply val glbType = glb(ensureFullyDefined(pt) :: unapplyArg.tpe_* :: Nil) val wrapInTypeTest = canRemedy && !(fun1.symbol.owner isNonBottomSubClass ClassTagClass) - val formals = patmat.alignPatterns(fun1, args).unexpandedFormals + val formals = patmat.alignPatterns(context.asInstanceOf[analyzer.Context], fun1, args).unexpandedFormals val args1 = typedArgsForFormals(args, formals, mode) val result = UnApply(fun1, args1) setPos tree.pos setType glbType diff --git a/test/files/pos/t8719.check b/test/files/pos/t8719.check new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/files/pos/t8719.check diff --git a/test/files/pos/t8719/Macros_1.scala b/test/files/pos/t8719/Macros_1.scala new file mode 100644 index 0000000000..152c92f254 --- /dev/null +++ b/test/files/pos/t8719/Macros_1.scala @@ -0,0 +1,21 @@ +import scala.language.experimental.macros +import scala.reflect.macros.TypecheckException +import scala.reflect.macros.whitebox.Context + +object Macros { + def typecheck_impl(c: Context)(code: c.Expr[String]): c.Expr[Option[String]] = { + import c.universe._ + + val Expr(Literal(Constant(codeStr: String))) = code + + try { + c.typecheck(c.parse(codeStr)) + c.Expr(q"None: Option[String]") + } catch { + case e: TypecheckException => + c.Expr(q"Some(${ e.toString }): Option[String]") + } + } + + def typecheck(code: String): Option[String] = macro typecheck_impl +}
\ No newline at end of file diff --git a/test/files/pos/t8719/Test_2.scala b/test/files/pos/t8719/Test_2.scala new file mode 100644 index 0000000000..997eb2f236 --- /dev/null +++ b/test/files/pos/t8719/Test_2.scala @@ -0,0 +1,10 @@ +case class Foo(i: Int, c: Char) + +object Bar { + def unapply(foo: Foo): Option[(Int, Char)] = Some((foo.i, foo.c)) +} + +object Test extends App { + println(Macros.typecheck("val Foo(x, y, z) = Foo(1, 'a')")) + println(Macros.typecheck("val Bar(x, y, z) = Foo(1, 'a')")) +}
\ No newline at end of file diff --git a/test/files/run/t8852a.scala b/test/files/run/t8852a.scala new file mode 100644 index 0000000000..cbff8ab75b --- /dev/null +++ b/test/files/run/t8852a.scala @@ -0,0 +1,34 @@ +import scala.tools.partest._ + +// Test that static methods in Java interfaces (new in Java 8) +// are callable from jointly compiler Scala code. +object Test extends CompilerTest { + import global._ + + override lazy val units: List[CompilationUnit] = { + // This test itself does not depend on JDK8. + javaCompilationUnits(global)(staticMethodInInterface) ++ + compilationUnits(global)(scalaClient) + } + + private def staticMethodInInterface = """ +public interface Interface { + public static int staticMethod() { + return 42; + } +} + + """ + + private def scalaClient = """ +object Test { + val x: Int = Interface.staticMethod() +} + +class C extends Interface // expect no errors about unimplemented members. + + """ + + // We're only checking we can compile it. + def check(source: String, unit: global.CompilationUnit): Unit = () +} |