Skip to content

Commit

Permalink
SI-7259 Fix detection of Java defined Selects
Browse files Browse the repository at this point in the history
The fix for SI-3120, 3ff7743, introduced a fallback within
`typedSelect` that accounted for the ambiguity of a Java
selection syntax. Does `A.B` refer to a member of the type `A`
or of the companion object `A`? (The companion object here is a
fiction used by scalac to group the static members of a Java
class.)

The fallback in `typedSelect` was predicated on
`context.owner.enclosingTopLevelClass.isJavaDefined`.
However, this was incorrectly including Select-s in top-level
annotations in Scala files, which are owned by the enclosing
package class, which is considered to be Java defined. This
led to nonsensical error messages ("type scala not found.")

Instead, this commit checks the compilation unit of the context,
which is more direct and correct. (As I learned recently,
`currentUnit.isJavaDefined` would *not* be correct, as a lazy type
might complete a Java signature while compiling some other compilation
unit!)

A bonus post factum test case is included for SI-3120.

Manual forward port of f046853 which was not merged as
part of the routine 2.10.x to master merge. The test case
uncovered a NullPointerExceptiion crasher in annotation
typechecking introduced in 5878099; this has been prevented
with a null check.

Conflicts:
	src/compiler/scala/tools/nsc/typechecker/Typers.scala
  • Loading branch information
retronym committed Mar 26, 2013
1 parent 59d4998 commit 7d03dcc
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Typers.scala
Expand Up @@ -3558,7 +3558,7 @@ trait Typers extends Adaptations with Tags {
// If there are dummy type arguments in typeFun part, it suggests we // If there are dummy type arguments in typeFun part, it suggests we
// must type the actual constructor call, not only the select. The value // must type the actual constructor call, not only the select. The value
// arguments are how the type arguments will be inferred. // arguments are how the type arguments will be inferred.
if (targs.isEmpty && typedFun0.exists(t => isDummyAppliedType(t.tpe))) if (targs.isEmpty && typedFun0.exists(t => t.tpe != null && isDummyAppliedType(t.tpe)))
logResult(s"Retyped $typedFun0 to find type args")(typed(argss.foldLeft(fun0)(Apply(_, _)))) logResult(s"Retyped $typedFun0 to find type args")(typed(argss.foldLeft(fun0)(Apply(_, _))))
else else
typedFun0 typedFun0
Expand Down Expand Up @@ -4692,7 +4692,9 @@ trait Typers extends Adaptations with Tags {
def handleMissing: Tree = { def handleMissing: Tree = {
def errorTree = missingSelectErrorTree(tree, qual, name) def errorTree = missingSelectErrorTree(tree, qual, name)
def asTypeSelection = ( def asTypeSelection = (
if (context.owner.enclosingTopLevelClass.isJavaDefined && name.isTypeName) { if (context.unit.isJava && name.isTypeName) {
// SI-3120 Java uses the same syntax, A.B, to express selection from the
// value A and from the type A. We have to try both.
atPos(tree.pos)(gen.convertToSelectFromType(qual, name)) match { atPos(tree.pos)(gen.convertToSelectFromType(qual, name)) match {
case EmptyTree => None case EmptyTree => None
case tree1 => Some(typed1(tree1, mode, pt)) case tree1 => Some(typed1(tree1, mode, pt))
Expand Down
7 changes: 7 additions & 0 deletions test/files/neg/t7259.check
@@ -0,0 +1,7 @@
t7259.scala:1: error: not found: type xxxxx
@xxxxx // error: not found: type xxxx
^
t7259.scala:8: error: type xxxxx is not a member of package annotation
@annotation.xxxxx // error: not found: type scala
^
two errors found
9 changes: 9 additions & 0 deletions test/files/neg/t7259.scala
@@ -0,0 +1,9 @@
@xxxxx // error: not found: type xxxx
class Ok

//
// This had the wrong error message in 2.9 and 2.10.
//

@annotation.xxxxx // error: not found: type scala
class WrongErrorMessage
4 changes: 4 additions & 0 deletions test/files/pos/t3120/J1.java
@@ -0,0 +1,4 @@
class J1 {
public class Inner1 { }
public static class Inner2 { }
}
4 changes: 4 additions & 0 deletions test/files/pos/t3120/J2.java
@@ -0,0 +1,4 @@
public class J2 {
public void f1(J1.Inner1 p) { }
public void f2(J1.Inner2 p) { }
}
3 changes: 3 additions & 0 deletions test/files/pos/t3120/Q.java
@@ -0,0 +1,3 @@
public class Q {
public static void passInner(J1.Inner1 myInner) {}
}
3 changes: 3 additions & 0 deletions test/files/pos/t3120/Test.scala
@@ -0,0 +1,3 @@
object Test {
Q.passInner(null)
}

0 comments on commit 7d03dcc

Please sign in to comment.