summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala34
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala69
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala56
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala23
9 files changed, 106 insertions, 91 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index c35c0a1019..0cdba861a5 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1263,8 +1263,8 @@ self =>
case CHARLIT => in.charVal
case INTLIT => in.intVal(isNegated).toInt
case LONGLIT => in.intVal(isNegated)
- case FLOATLIT => in.floatVal(isNegated).toFloat
- case DOUBLELIT => in.floatVal(isNegated)
+ case FLOATLIT => in.floatVal(isNegated)
+ case DOUBLELIT => in.doubleVal(isNegated)
case STRINGLIT | STRINGPART => in.strVal.intern()
case TRUE => true
case FALSE => false
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 99713451ac..226c49ec07 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -983,23 +983,45 @@ trait Scanners extends ScannersCommon {
def intVal: Long = intVal(negated = false)
- /** Convert current strVal, base to double value
+ /** Convert current strVal, base to float value.
*/
- def floatVal(negated: Boolean): Double = {
- val limit: Double = if (token == DOUBLELIT) Double.MaxValue else Float.MaxValue
+ def floatVal(negated: Boolean): Float = {
try {
- val value: Double = java.lang.Double.valueOf(strVal).doubleValue()
- if (value > limit)
+ val value: Float = java.lang.Float.parseFloat(strVal)
+ if (value > Float.MaxValue)
syntaxError("floating point number too large")
+ val zeroly = "0.fF"
+ if (value == 0.0f && strVal.exists(c => !zeroly.contains(c)))
+ syntaxError("floating point number too small")
if (negated) -value else value
} catch {
case _: NumberFormatException =>
syntaxError("malformed floating point number")
+ 0.0f
+ }
+ }
+
+ def floatVal: Float = floatVal(negated = false)
+
+ /** Convert current strVal, base to double value.
+ */
+ def doubleVal(negated: Boolean): Double = {
+ try {
+ val value: Double = java.lang.Double.parseDouble(strVal)
+ if (value > Double.MaxValue)
+ syntaxError("double precision floating point number too large")
+ val zeroly = "0.dD"
+ if (value == 0.0d && strVal.exists(c => !zeroly.contains(c)))
+ syntaxError("double precision floating point number too small")
+ if (negated) -value else value
+ } catch {
+ case _: NumberFormatException =>
+ syntaxError("malformed double precision floating point number")
0.0
}
}
- def floatVal: Double = floatVal(negated = false)
+ def doubleVal: Double = doubleVal(negated = false)
def checkNoLetter(): Unit = {
if (isIdentifierPart(ch) && ch >= ' ')
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index 342031b601..99263bf834 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -7,9 +7,10 @@ package scala
package tools.nsc
package reporters
-import java.io.{ BufferedReader, PrintWriter }
-import scala.reflect.internal.util._
-import StringOps._
+import java.io.{BufferedReader, PrintWriter}
+import scala.reflect.internal.util.{Position, StringOps}
+import Position.formatMessage
+import StringOps.{countElementsAsString => countAs, trimAllTrailingSpace => trimTrailing}
/** This class implements a Reporter that displays messages on a text console.
*/
@@ -26,47 +27,35 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
private def label(severity: Severity): String = severity match {
case ERROR => "error"
case WARNING => "warning"
- case INFO => null
+ case INFO => ""
}
- protected def clabel(severity: Severity): String = {
- val label0 = label(severity)
- if (label0 eq null) "" else label0 + ": "
+ protected def clabel(severity: Severity): String = label(severity) match {
+ case "" => ""
+ case s => s"$s: "
}
- /** Returns the number of errors issued totally as a string.
- */
- private def getCountString(severity: Severity): String =
- StringOps.countElementsAsString((severity).count, label(severity))
-
/** Prints the message. */
- def printMessage(msg: String) {
- writer print trimAllTrailingSpace(msg) + "\n"
+ def printMessage(msg: String): Unit = {
+ writer.println(trimTrailing(msg))
writer.flush()
}
/** Prints the message with the given position indication. */
- def printMessage(posIn: Position, msg: String) {
- printMessage(Position.formatMessage(posIn, msg, shortname))
- }
- def print(pos: Position, msg: String, severity: Severity) {
- printMessage(pos, clabel(severity) + msg)
- }
+ def printMessage(posIn: Position, msg: String): Unit = printMessage(formatMessage(posIn, msg, shortname))
- /** Prints the column marker of the given position.
- */
- def printColumnMarker(pos: Position) =
- if (pos.isDefined) { printMessage(" " * (pos.column - 1) + "^") }
+ def print(pos: Position, msg: String, severity: Severity): Unit = printMessage(pos, s"${clabel(severity)}${msg}")
- /** Prints the number of errors and warnings if their are non-zero. */
- def printSummary() {
- if (WARNING.count > 0) printMessage(getCountString(WARNING) + " found")
- if ( ERROR.count > 0) printMessage(getCountString(ERROR ) + " found")
- }
+ /** Prints the column marker of the given position. */
+ def printColumnMarker(pos: Position): Unit = if (pos.isDefined) printMessage(" " * (pos.column - 1) + "^")
+
+ /** Prints the number of warnings and errors if there are any. */
+ def printSummary(): Unit =
+ for (k <- List(WARNING, ERROR) if k.count > 0) printMessage(s"${countAs(k.count, label(k))} found")
def display(pos: Position, msg: String, severity: Severity): Unit = {
val ok = severity match {
- case ERROR => ERROR.count <= settings.maxerrs.value
+ case ERROR => ERROR.count <= settings.maxerrs.value
case WARNING => WARNING.count <= settings.maxwarns.value
case _ => true
}
@@ -74,17 +63,19 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
}
def displayPrompt(): Unit = {
- writer.print("\na)bort, s)tack, r)esume: ")
+ writer.println()
+ writer.print("a)bort, s)tack, r)esume: ")
writer.flush()
if (reader != null) {
- val response = reader.read().asInstanceOf[Char].toLower
- if (response == 'a' || response == 's') {
- (new Exception).printStackTrace()
- if (response == 'a')
- sys exit 1
-
- writer.print("\n")
- writer.flush()
+ reader.read match {
+ case 'a' | 'A' =>
+ new Throwable().printStackTrace()
+ System.exit(1)
+ case 's' | 'S' =>
+ new Throwable().printStackTrace()
+ writer.println()
+ writer.flush()
+ case _ =>
}
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 2d8d591b6d..0910dca445 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -1211,7 +1211,7 @@ trait ContextErrors {
"pass-by-name arguments not allowed for case class parameters"
case AbstractVar =>
- "only classes can have declared but undefined members" + abstractVarMessage(sym)
+ "only traits and abstract classes can have declared but undefined members" + abstractVarMessage(sym)
}
issueSymbolTypeError(sym, msg)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index fde2f7bb03..d349597b14 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -1194,7 +1194,8 @@ trait Contexts { self: Analyzer =>
}
final def lookupCompanionOf(original: Symbol): Symbol = {
- lookupScopeEntry(original) match {
+ if (original.isModuleClass) original.sourceModule
+ else lookupScopeEntry(original) match {
case null => NoSymbol
case entry => entry.owner.lookupCompanion(original)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index df014b5161..ea82739504 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -240,10 +240,6 @@ abstract class Duplicators extends Analyzer {
result.symbol.updateAttachment(DelambdafyTarget)
result
- case fun: Function =>
- debuglog("Clearing the type and retyping Function: " + fun)
- super.typed(fun.clearType, mode, pt)
-
case vdef @ ValDef(mods, name, tpt, rhs) =>
// log("vdef fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol + " and " + invalidSyms)
//if (mods.hasFlag(Flags.LAZY)) vdef.symbol.resetFlag(Flags.MUTABLE) // Martin to Iulian: lazy vars can now appear because they are no longer boxed; Please check that deleting this statement is OK.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index e8147dbf3a..9dd260b274 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -495,21 +495,22 @@ trait Infer extends Checkable {
}
/** Return inferred type arguments, given type parameters, formal parameters,
- * argument types, result type and expected result type.
- * If this is not possible, throw a `NoInstance` exception.
- * Undetermined type arguments are represented by `definitions.NothingTpe`.
- * No check that inferred parameters conform to their bounds is made here.
- *
- * @param tparams the type parameters of the method
- * @param formals the value parameter types of the method
- * @param restpe the result type of the method
- * @param argtpes the argument types of the application
- * @param pt the expected return type of the application
- * @return @see adjustTypeArgs
- *
- * @throws NoInstance
- */
- def methTypeArgs(tparams: List[Symbol], formals: List[Type], restpe: Type,
+ * argument types, result type and expected result type.
+ * If this is not possible, throw a `NoInstance` exception.
+ * Undetermined type arguments are represented by `definitions.NothingTpe`.
+ * No check that inferred parameters conform to their bounds is made here.
+ *
+ * @param fn the function for reporting, may be empty
+ * @param tparams the type parameters of the method
+ * @param formals the value parameter types of the method
+ * @param restpe the result type of the method
+ * @param argtpes the argument types of the application
+ * @param pt the expected return type of the application
+ * @return @see adjustTypeArgs
+ *
+ * @throws NoInstance
+ */
+ def methTypeArgs(fn: Tree, tparams: List[Symbol], formals: List[Type], restpe: Type,
argtpes: List[Type], pt: Type): AdjustedTypeArgs.Result = {
val tvars = tparams map freshVar
if (!sameLength(formals, argtpes))
@@ -559,21 +560,12 @@ trait Infer extends Checkable {
val hasAny = pt :: restpe :: formals ::: argtpes ::: loBounds exists (_.dealiasWidenChain exists containsAny)
!hasAny
}
- def argumentPosition(idx: Int): Position = context.tree match {
- case x: ValOrDefDef => x.rhs match {
- case Apply(fn, args) if idx < args.size => args(idx).pos
- case _ => context.tree.pos
- }
- case _ => context.tree.pos
- }
- if (settings.warnInferAny && context.reportErrors && canWarnAboutAny) {
- foreachWithIndex(targs) ((targ, idx) =>
- targ.typeSymbol match {
- case sym @ (AnyClass | AnyValClass) =>
- reporter.warning(argumentPosition(idx), s"a type was inferred to be `${sym.name}`; this may indicate a programming error.")
- case _ =>
- }
- )
+ if (settings.warnInferAny && context.reportErrors && !fn.isEmpty && canWarnAboutAny) {
+ targs.foreach(_.typeSymbol match {
+ case sym @ (AnyClass | AnyValClass) =>
+ reporter.warning(fn.pos, s"a type was inferred to be `${sym.name}`; this may indicate a programming error.")
+ case _ =>
+ })
}
adjustTypeArgs(tparams, tvars, targs, restpe)
}
@@ -735,7 +727,7 @@ trait Infer extends Checkable {
)
def tryInstantiating(args: List[Type]) = falseIfNoInstance {
val restpe = mt resultType args
- val AdjustedTypeArgs.Undets(okparams, okargs, leftUndet) = methTypeArgs(undetparams, formals, restpe, args, pt)
+ val AdjustedTypeArgs.Undets(okparams, okargs, leftUndet) = methTypeArgs(EmptyTree, undetparams, formals, restpe, args, pt)
val restpeInst = restpe.instantiateTypeParams(okparams, okargs)
// #2665: must use weak conformance, not regular one (follow the monomorphic case above)
exprTypeArgs(leftUndet, restpeInst, pt, useWeaklyCompatible = true) match {
@@ -989,7 +981,7 @@ trait Infer extends Checkable {
val restpe = fn.tpe.resultType(argtpes)
val AdjustedTypeArgs.AllArgsAndUndets(okparams, okargs, allargs, leftUndet) =
- methTypeArgs(undetparams, formals, restpe, argtpes, pt)
+ methTypeArgs(fn, undetparams, formals, restpe, argtpes, pt)
if (checkBounds(fn, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")) {
val treeSubst = new TreeTypeSubstituter(okparams, okargs)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 45dfb427f0..a787a7bc12 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1130,7 +1130,7 @@ abstract class RefChecks extends Transform {
}
/** Sensibility check examines flavors of equals. */
def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match {
- case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && !currentOwner.isSynthetic =>
+ case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && (!currentOwner.isSynthetic || currentOwner.isAnonymousFunction) =>
checkSensibleEquals(pos, qual, name, fn.symbol, args.head)
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 58a44d3ac0..837ccf7e06 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -864,11 +864,24 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ =>
}
debuglog(s"fallback on implicits: ${tree}/$resetTree")
- val tree1 = typed(resetTree, mode)
- // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
- // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin.
- tree1 setType pluginsTyped(tree1.tpe, this, tree1, mode, pt)
- if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree)
+ // SO-10066 Need to patch the enclosing tree in the context to make translation of Dynamic
+ // work during fallback typechecking below.
+ val resetContext: Context = {
+ object substResetForOriginal extends Transformer {
+ override def transform(tree: Tree): Tree = {
+ if (tree eq original) resetTree
+ else super.transform(tree)
+ }
+ }
+ context.make(substResetForOriginal.transform(context.tree))
+ }
+ typerWithLocalContext(resetContext) { typer1 =>
+ val tree1 = typer1.typed(resetTree, mode)
+ // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
+ // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin.
+ tree1 setType pluginsTyped(tree1.tpe, typer1, tree1, mode, pt)
+ if (tree1.isEmpty) tree1 else typer1.adapt(tree1, mode, pt, EmptyTree)
+ }
}
)
else