summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala42
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala25
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala22
-rw-r--r--src/library/scala/Enumeration.scala4
-rw-r--r--src/swing/scala/swing/AbstractButton.scala2
-rw-r--r--src/swing/scala/swing/Button.scala2
-rw-r--r--src/swing/scala/swing/ButtonGroup.scala2
-rw-r--r--src/swing/scala/swing/EditorPane.scala2
-rw-r--r--src/swing/scala/swing/FormattedTextField.scala2
-rw-r--r--src/swing/scala/swing/GUIApplication.scala2
-rw-r--r--src/swing/scala/swing/ListView.scala2
-rw-r--r--src/swing/scala/swing/PasswordField.scala2
-rw-r--r--src/swing/scala/swing/Table.scala2
-rw-r--r--src/swing/scala/swing/TextArea.scala2
-rw-r--r--src/swing/scala/swing/TextComponent.scala2
-rw-r--r--src/swing/scala/swing/TextField.scala2
-rw-r--r--src/swing/scala/swing/ToggleButton.scala2
-rw-r--r--src/swing/scala/swing/UIElement.scala2
-rw-r--r--src/swing/scala/swing/Window.scala2
-rw-r--r--test/files/neg/t2494.check4
-rwxr-xr-xtest/files/neg/t2494.scala1
-rw-r--r--test/files/run/names-defaults.scala2
26 files changed, 84 insertions, 56 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 6bd3fee3fb..f8f6ee2c55 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -1803,7 +1803,8 @@ trait Trees {
/** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse
*/
- def resetAttrs[A<:Tree](x:A, strict: Boolean = false): A = {new ResetAttrsTraverser(strict).traverse(x); x}
+ def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
+ def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
/** A traverser which resets symbol and tpe fields of all nodes in a given tree
* except for (1) TypeTree nodes, whose <code>.tpe</code> field is kept and
@@ -1812,26 +1813,39 @@ trait Trees {
*
* (bq:) This traverser has mutable state and should be discarded after use
*/
- class ResetAttrsTraverser(strict: Boolean) extends Traverser {
- private val erasedSyms = new HashSet[Symbol]("erasedSyms", 8)
+ private class ResetAttrsTraverser extends Traverser {
+ protected def isLocal(sym: Symbol): Boolean = true
+ protected def resetDef(tree: Tree) {
+ tree.symbol = NoSymbol
+ tree.tpe = null
+ super.traverse(tree)
+ }
override def traverse(tree: Tree): Unit = tree match {
case EmptyTree | TypeTree() =>
;
- case Template(parents, self, body) =>
- tree.symbol = NoSymbol
+ case _: DefTree | Function(_, _) | Template(_, _, _) =>
+ resetDef(tree)
+ case _ =>
+ if (tree.hasSymbol && isLocal(tree.symbol)) tree.symbol = NoSymbol
tree.tpe = null
- if (!strict)
- for (stat <- body)
- if (stat.isDef) erasedSyms.addEntry(stat.symbol)
super.traverse(tree)
- case _: DefTree | Function(_, _) =>
- if (!strict) erasedSyms.addEntry(tree.symbol)
- tree.symbol = NoSymbol
- tree.tpe = null
+ }
+ }
+
+ private class ResetLocalAttrsTraverser extends ResetAttrsTraverser {
+ private val erasedSyms = new HashSet[Symbol](8)
+ override protected def isLocal(sym: Symbol) =
+ erasedSyms contains sym
+ override protected def resetDef(tree: Tree) {
+ erasedSyms addEntry tree.symbol
+ super.resetDef(tree)
+ }
+ override def traverse(tree: Tree): Unit = tree match {
+ case Template(parents, self, body) =>
+ for (stat <- body)
+ if (stat.isDef) erasedSyms.addEntry(stat.symbol)
super.traverse(tree)
case _ =>
- if (tree.hasSymbol && (strict || erasedSyms.contains(tree.symbol))) tree.symbol = NoSymbol
- tree.tpe = null
super.traverse(tree)
}
}
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index b1a94b8162..a94ba17d8a 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1964,7 +1964,9 @@ trait Symbols {
/** An exception for cyclic references of symbol definitions */
case class CyclicReference(sym: Symbol, info: Type)
- extends TypeError("illegal cyclic reference involving " + sym)
+ extends TypeError("illegal cyclic reference involving " + sym) {
+ // printStackTrace() // debug
+ }
/** A class for type histories */
private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) {
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 071f1baf29..710e7e1487 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -4861,7 +4861,7 @@ A type's typeSymbol should never be inspected directly.
// Errors and Diagnostics -----------------------------------------------------
/** An exception signalling a type error */
- class TypeError(val pos: Position, val msg: String) extends java.lang.Error(msg) {
+ class TypeError(var pos: Position, val msg: String) extends java.lang.Error(msg) {
def this(msg: String) = this(NoPosition, msg)
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 9752bb33ae..bc9c788804 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -344,7 +344,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
val substParam = new TreeSymSubstituter(List(fun.vparams.head.symbol), List(idparam));
def transformCase(cdef: CaseDef): CaseDef =
substParam(
- resetAttrs(
+ resetLocalAttrs(
CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true))))
if (cases exists treeInfo.isDefaultCase) Literal(true)
else
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index a32f945553..1e07442eee 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -100,6 +100,21 @@ self: Analyzer =>
tpeCache
}
+ /** Does type `tp` contain an Error type as parameter or result?
+ */
+ private def containsError(tp: Type): Boolean = tp match {
+ case PolyType(tparams, restpe) => containsError(restpe)
+ case MethodType(params, restpe) => (params map (_.tpe) exists (_.isError)) || containsError(restpe)
+ case _ => tp.isError
+ }
+
+ def isCyclicOrErroneous = try {
+ containsError(tpe)
+ } catch {
+ case ex: CyclicReference =>
+ true
+ }
+
override def equals(other: Any) = other match {
case that: ImplicitInfo =>
this.name == that.name &&
@@ -218,14 +233,6 @@ self: Analyzer =>
case _ => tp
}
- /** Does type `tp` contain an Error type as parameter or result?
- */
- private def containsError(tp: Type): Boolean = tp match {
- case PolyType(tparams, restpe) => containsError(restpe)
- case MethodType(params, restpe) => (params map (_.tpe) exists (_.isError)) || containsError(restpe)
- case _ => tp.isError
- }
-
/** Does type `dtor` dominate type `dted`?
* This is the case if the stripped cores `dtor1` and `dted1` of both types are
* the same wrt `=:=`, or if they overlap and the complexity of `dtor1` is higher
@@ -508,7 +515,7 @@ self: Analyzer =>
* SearchFailure if not.
*/
def tryImplicit(info: ImplicitInfo): SearchResult =
- if (containsError(info.tpe) ||
+ if (info.isCyclicOrErroneous ||
(isLocal && shadowed.contains(info.name)) ||
(isView && (info.sym == Predef_identity || info.sym == Predef_conforms)) //@M this condition prevents no-op conversions, which are a problem (besides efficiency),
// TODO: remove `info.sym == Predef_identity` once we have a new STARR that only has conforms as an implicit
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index c586729e22..f19f5516c0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -235,7 +235,7 @@ trait NamesDefaults { self: Analyzer =>
val (sym, byName) = symP
// resetAttrs required for #2290. given a block { val x = 1; x }, when wrapping into a function
// () => { val x = 1; x }, the owner of symbol x must change (to the apply method of the function).
- val body = if (byName) blockTyper.typed(Function(List(), resetAttrs(arg)))
+ val body = if (byName) blockTyper.typed(Function(List(), resetLocalAttrs(arg)))
else arg
atPos(body.pos)(ValDef(sym, body).setType(NoType))
})
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6f85e8ab16..9c5edf7e86 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -241,9 +241,10 @@ trait Typers { self: Analyzer =>
* @param pos0 The position where to report the error
* @param ex The exception that caused the error
*/
- def reportTypeError(pos0: Position, ex: TypeError) {
+ def reportTypeError(pos: Position, ex: TypeError) {
+ if (ex.pos == NoPosition) ex.pos = pos
+ if (!context.reportGeneralErrors) throw ex
if (settings.debug.value) ex.printStackTrace()
- val pos = if (ex.pos == NoPosition) pos0 else ex.pos
ex match {
case CyclicReference(sym, info: TypeCompleter) =>
val msg =
@@ -256,11 +257,11 @@ trait Typers { self: Analyzer =>
case _ =>
ex.getMessage()
}
- context.error(pos, msg)
+ context.error(ex.pos, msg)
if (sym == ObjectClass)
throw new FatalError("cannot redefine root "+sym)
case _ =>
- context.error(pos, ex)
+ context.error(ex.pos, ex)
}
}
@@ -703,11 +704,11 @@ trait Typers { self: Analyzer =>
/** Utility method: Try op1 on tree. If that gives an error try op2 instead.
*/
def tryBoth(tree: Tree)(op1: (Typer, Tree) => Tree)(op2: (Typer, Tree) => Tree): Tree =
- silent(op1(_, tree.duplicate)) match {
+ silent(op1(_, tree)) match {
case result1: Tree =>
result1
case ex1: TypeError =>
- silent(op2(_, tree)) match {
+ silent(op2(_, resetAllAttrs(tree))) match {
case result2: Tree =>
// println("snd succeeded: "+result2)
result2
@@ -800,8 +801,8 @@ trait Typers { self: Analyzer =>
typer1.silent(tpr => tpr.typed(tpr.applyImplicitArgs(tree), mode, pt)) match {
case result: Tree => result
case ex: TypeError =>
- if (settings.debug.value) log("fallback on implicits: "+tree+"/"+resetAttrs(original, true))
- val tree1 = typed(resetAttrs(original, true), mode, WildcardType)
+ if (settings.debug.value) log("fallback on implicits: "+tree+"/"+resetAllAttrs(original))
+ val tree1 = typed(resetAllAttrs(original), mode, WildcardType)
tree1.tpe = addAnnotations(tree1, tree1.tpe)
if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree)
}
@@ -1008,7 +1009,7 @@ trait Typers { self: Analyzer =>
/** Try to apply an implicit conversion to `qual' to that it contains
* a method `name` which can be applied to arguments `args' with expected type `pt'.
* If `pt' is defined, there is a fallback to try again with pt = ?.
- * This helps avoiding propagating result information to far and solves
+ * This helps avoiding propagating result information too far and solves
* #1756.
* If no conversion is found, return `qual' unchanged.
*
@@ -3067,6 +3068,7 @@ trait Typers { self: Analyzer =>
try {
newTyper(c).typedArgs(args, mode)
} catch {
+ case ex: CyclicReference => throw ex
case ex: TypeError =>
null
}
@@ -3417,7 +3419,7 @@ trait Typers { self: Analyzer =>
(!currentRun.compiles(defSym) ||
(context.unit ne null) && defSym.sourceFile != context.unit.source.file))
defSym = NoSymbol
- else if (impSym.isError)
+ else if (impSym.isError || impSym.name == nme.CONSTRUCTOR)
impSym = NoSymbol
}
if (defSym.exists) {
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index f4ed95489b..2feb892421 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -116,9 +116,7 @@ abstract class Enumeration(initial: Int, names: String*) {
* or initialize each Enumeration with Value(String),
* for valueOf to work.
* @param s an enumeration name
- * @return <tt>Some(Value)</tt> if an enumeration's name matches <var>s</var>,
- * else <tt>None</tt>
- * Note the change here is intentional. You should know whether
+ * Note the change here wrt 2.7 is intentional. You should know whether
* a name is in an Enumeration beforehand. If not, just use find on values.
*/
def withName(s: String): Value = values.find(_.toString == s).get
diff --git a/src/swing/scala/swing/AbstractButton.scala b/src/swing/scala/swing/AbstractButton.scala
index c3258b4fc6..991d82fb55 100644
--- a/src/swing/scala/swing/AbstractButton.scala
+++ b/src/swing/scala/swing/AbstractButton.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import java.awt.{Dimension, Insets}
import javax.swing.{AbstractButton => JAbstractButton, Icon}
-import event._
/**
* Base class of all button-like widgets, such as push buttons,
diff --git a/src/swing/scala/swing/Button.scala b/src/swing/scala/swing/Button.scala
index 698924b18d..e3387ef271 100644
--- a/src/swing/scala/swing/Button.scala
+++ b/src/swing/scala/swing/Button.scala
@@ -11,8 +11,8 @@
package scala.swing
-import javax.swing._
import event._
+import javax.swing._
object Button {
def apply(text0: String)(op: => Unit) = new Button(Action(text0)(op))
diff --git a/src/swing/scala/swing/ButtonGroup.scala b/src/swing/scala/swing/ButtonGroup.scala
index 4bf2cb21ff..8af67cdb3c 100644
--- a/src/swing/scala/swing/ButtonGroup.scala
+++ b/src/swing/scala/swing/ButtonGroup.scala
@@ -11,8 +11,8 @@
package scala.swing
-import javax.swing.{AbstractButton => JAbstractButton,Icon}
import event._
+import javax.swing.{AbstractButton => JAbstractButton,Icon}
import scala.collection._
import scala.collection.mutable.Buffer
diff --git a/src/swing/scala/swing/EditorPane.scala b/src/swing/scala/swing/EditorPane.scala
index 7b93e2cdff..a258865508 100644
--- a/src/swing/scala/swing/EditorPane.scala
+++ b/src/swing/scala/swing/EditorPane.scala
@@ -10,11 +10,11 @@
package scala.swing
+import event._
import javax.swing._
import javax.swing.text._
import java.awt.Color
import java.awt.event._
-import event._
/**
* A text component that allows multiline text input and display.
diff --git a/src/swing/scala/swing/FormattedTextField.scala b/src/swing/scala/swing/FormattedTextField.scala
index 6397de2621..623764dc76 100644
--- a/src/swing/scala/swing/FormattedTextField.scala
+++ b/src/swing/scala/swing/FormattedTextField.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import javax.swing._
import java.awt.event._
-import event._
object FormattedTextField {
/**
diff --git a/src/swing/scala/swing/GUIApplication.scala b/src/swing/scala/swing/GUIApplication.scala
index 0cce2cb176..a3965fcec8 100644
--- a/src/swing/scala/swing/GUIApplication.scala
+++ b/src/swing/scala/swing/GUIApplication.scala
@@ -11,8 +11,8 @@
package scala.swing
-import javax.swing._
import event.Event
+import javax.swing._
/**
* Convenience class with utility methods for GUI applications.
diff --git a/src/swing/scala/swing/ListView.scala b/src/swing/scala/swing/ListView.scala
index 49b69396fe..0712f78d57 100644
--- a/src/swing/scala/swing/ListView.scala
+++ b/src/swing/scala/swing/ListView.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import javax.swing._
import javax.swing.event._
-import event._
import java.awt.Color
object ListView {
diff --git a/src/swing/scala/swing/PasswordField.scala b/src/swing/scala/swing/PasswordField.scala
index 0a77ff6f38..4fcc761be5 100644
--- a/src/swing/scala/swing/PasswordField.scala
+++ b/src/swing/scala/swing/PasswordField.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import javax.swing._
import java.awt.event._
-import event._
/**
* A password field, that displays a replacement character for each character in the password.
diff --git a/src/swing/scala/swing/Table.scala b/src/swing/scala/swing/Table.scala
index 2cedbd1050..88f19f5f02 100644
--- a/src/swing/scala/swing/Table.scala
+++ b/src/swing/scala/swing/Table.scala
@@ -11,11 +11,11 @@
package scala.swing
+import event._
import javax.swing._
import javax.swing.table._
import javax.swing.event._
import java.awt.{Dimension, Color}
-import event._
import scala.collection.mutable.{Set, IndexedSeq}
object Table {
diff --git a/src/swing/scala/swing/TextArea.scala b/src/swing/scala/swing/TextArea.scala
index 08540845b6..4ff0a666da 100644
--- a/src/swing/scala/swing/TextArea.scala
+++ b/src/swing/scala/swing/TextArea.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import javax.swing._
import java.awt.event._
-import event._
/**
* A text component that allows multiline text input and display.
diff --git a/src/swing/scala/swing/TextComponent.scala b/src/swing/scala/swing/TextComponent.scala
index 70d6d8055c..3b81b567bb 100644
--- a/src/swing/scala/swing/TextComponent.scala
+++ b/src/swing/scala/swing/TextComponent.scala
@@ -11,11 +11,11 @@
package scala.swing
+import event._
import javax.swing._
import javax.swing.text._
import javax.swing.event._
import java.awt.Color
-import event._
object TextComponent {
trait HasColumns extends TextComponent {
diff --git a/src/swing/scala/swing/TextField.scala b/src/swing/scala/swing/TextField.scala
index 201a97b724..acb34b9a1b 100644
--- a/src/swing/scala/swing/TextField.scala
+++ b/src/swing/scala/swing/TextField.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import javax.swing._
import java.awt.event._
-import event._
/*object TextField {
diff --git a/src/swing/scala/swing/ToggleButton.scala b/src/swing/scala/swing/ToggleButton.scala
index 26958c94f8..608f2c02b7 100644
--- a/src/swing/scala/swing/ToggleButton.scala
+++ b/src/swing/scala/swing/ToggleButton.scala
@@ -11,8 +11,8 @@
package scala.swing
-import javax.swing._
import event._
+import javax.swing._
/**
* A two state button with a push button like user interface.
diff --git a/src/swing/scala/swing/UIElement.scala b/src/swing/scala/swing/UIElement.scala
index a557535627..f8f050b3d6 100644
--- a/src/swing/scala/swing/UIElement.scala
+++ b/src/swing/scala/swing/UIElement.scala
@@ -11,11 +11,11 @@
package scala.swing
+import event._
import java.awt.{Color, Cursor, Font, Dimension, Rectangle}
import scala.collection.mutable.HashMap
import scala.ref._
import java.util.WeakHashMap
-import event._
object UIElement {
private val ClientKey = "scala.swingWrapper"
diff --git a/src/swing/scala/swing/Window.scala b/src/swing/scala/swing/Window.scala
index e9fdfff7ca..bc333db9ca 100644
--- a/src/swing/scala/swing/Window.scala
+++ b/src/swing/scala/swing/Window.scala
@@ -11,9 +11,9 @@
package scala.swing
+import event._
import java.awt.{Image, Point, Window => AWTWindow}
import javax.swing._
-import event._
/**
* A window with decoration such as a title, border, and action buttons.
diff --git a/test/files/neg/t2494.check b/test/files/neg/t2494.check
new file mode 100644
index 0000000000..6d43011e24
--- /dev/null
+++ b/test/files/neg/t2494.check
@@ -0,0 +1,4 @@
+t2494.scala:1: error: recursive value a needs type
+object A { val a = { println("a = " + a); a = 1} }
+ ^
+one error found
diff --git a/test/files/neg/t2494.scala b/test/files/neg/t2494.scala
new file mode 100755
index 0000000000..71e6bc4bbf
--- /dev/null
+++ b/test/files/neg/t2494.scala
@@ -0,0 +1 @@
+object A { val a = { println("a = " + a); a = 1} }
diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala
index 1f92436628..008939cc9d 100644
--- a/test/files/run/names-defaults.scala
+++ b/test/files/run/names-defaults.scala
@@ -183,7 +183,7 @@ object Test extends Application {
println(argName) // should be 4
test5 { argName = 5 }
println(argName) // should be 5
- val a = test1(a = 10, b = "2") // local values a and b exist, but not ambiuous since they're val's
+ val a: Unit = test1(a = 10, b = "2") // local values a and b exist, but not ambiuous since they're val's
// dependent types and copy method