aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-08-07 17:29:24 +0200
committerMartin Odersky <odersky@gmail.com>2016-08-16 17:34:42 +0200
commit8d4d9a363d90cc24bd79b18ea2ef7cba6a746bef (patch)
tree89305ec17cdc4d421047e0ec4a742a79b91a286f /src/dotty/tools/dotc/typer
parentd5f42680803e40f9b3698404848450d088fca07a (diff)
downloaddotty-8d4d9a363d90cc24bd79b18ea2ef7cba6a746bef.tar.gz
dotty-8d4d9a363d90cc24bd79b18ea2ef7cba6a746bef.tar.bz2
dotty-8d4d9a363d90cc24bd79b18ea2ef7cba6a746bef.zip
New string infterpolators
Roll `sm` and `i` into one interpolator (also called `i`) Evolve `d` to `em` interpolator (for error messages) New interpolator `ex` with more explanations, replaces disambiguation.
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala10
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala38
-rw-r--r--src/dotty/tools/dotc/typer/ErrorReporting.scala85
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala20
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala8
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala6
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala22
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala52
8 files changed, 113 insertions, 128 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index f0a514e8c..c8f41b7fa 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -777,9 +777,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
maximizeType(unapplyArgType) match {
case Some(tvar) =>
def msg =
- d"""There is no best instantiation of pattern type $unapplyArgType
- |that makes it a subtype of selector type $selType.
- |Non-variant type variable ${tvar.origin} cannot be uniquely instantiated.""".stripMargin
+ ex"""There is no best instantiation of pattern type $unapplyArgType
+ |that makes it a subtype of selector type $selType.
+ |Non-variant type variable ${tvar.origin} cannot be uniquely instantiated."""
if (fromScala2x) {
// We can't issue an error here, because in Scala 2, ::[B] is invariant
// whereas List[+T] is covariant. According to the strict rule, a pattern
@@ -801,7 +801,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
unapp.println("Neither sub nor super")
unapp.println(TypeComparer.explained(implicit ctx => unapplyArgType <:< selType))
errorType(
- d"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $selType",
+ ex"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $selType",
tree.pos)
}
@@ -822,7 +822,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
case _ => args
}
if (argTypes.length != bunchedArgs.length) {
- ctx.error(d"wrong number of argument patterns for $qual; expected: ($argTypes%, %)", tree.pos)
+ ctx.error(em"wrong number of argument patterns for $qual; expected: ($argTypes%, %)", tree.pos)
argTypes = argTypes.take(args.length) ++
List.fill(argTypes.length - args.length)(WildcardType)
}
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index b1cceea88..d77520c77 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -25,7 +25,7 @@ import util.common._
import transform.SymUtils._
import Decorators._
import Uniques._
-import ErrorReporting.{err, errorType, DiagnosticString}
+import ErrorReporting.{err, errorType}
import config.Printers._
import collection.mutable
import SymDenotations.NoCompleter
@@ -40,11 +40,11 @@ object Checking {
def checkBounds(args: List[tpd.Tree], boundss: List[TypeBounds], instantiate: (Type, List[Type]) => Type)(implicit ctx: Context) = {
(args, boundss).zipped.foreach { (arg, bound) =>
if (!bound.isHK && arg.tpe.isHK)
- ctx.error(d"missing type parameter(s) for $arg", arg.pos)
+ ctx.error(ex"missing type parameter(s) for $arg", arg.pos)
}
for ((arg, which, bound) <- ctx.boundsViolations(args, boundss, instantiate))
ctx.error(
- d"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
+ ex"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
arg.pos)
}
@@ -65,7 +65,7 @@ object Checking {
tycon match {
case tycon: TypeLambda =>
ctx.errorOrMigrationWarning(
- d"unreducible application of higher-kinded type $tycon to wildcard arguments",
+ ex"unreducible application of higher-kinded type $tycon to wildcard arguments",
pos)
case _ =>
checkWildcardHKApply(tp.superType, pos)
@@ -117,14 +117,14 @@ object Checking {
case tref: TypeRef =>
val cls = tref.symbol
if (cls.is(AbstractOrTrait))
- ctx.error(d"$cls is abstract; cannot be instantiated", pos)
+ ctx.error(em"$cls is abstract; cannot be instantiated", pos)
if (!cls.is(Module)) {
// Create a synthetic singleton type instance, and check whether
// it conforms to the self type of the class as seen from that instance.
val stp = SkolemType(tp)
val selfType = tref.givenSelfType.asSeenFrom(stp, cls)
if (selfType.exists && !(stp <:< selfType))
- ctx.error(d"$tp does not conform to its self type $selfType; cannot be instantiated")
+ ctx.error(ex"$tp does not conform to its self type $selfType; cannot be instantiated")
}
case _ =>
}
@@ -133,7 +133,7 @@ object Checking {
def checkRealizable(tp: Type, pos: Position)(implicit ctx: Context): Unit = {
val rstatus = realizability(tp)
if (rstatus ne Realizable) {
- def msg = d"$tp is not a legal path\n since it${rstatus.msg}"
+ def msg = em"$tp is not a legal path\n since it${rstatus.msg}"
if (ctx.scala2Mode) ctx.migrationWarning(msg, pos) else ctx.error(msg, pos)
}
}
@@ -378,7 +378,7 @@ object Checking {
var tp1 =
if (tp.symbol.is(Private) &&
!accessBoundary(sym).isContainedIn(tp.symbol.owner)) {
- errors = (d"non-private $sym refers to private ${tp.symbol}\n in its type signature ${sym.info}",
+ errors = (em"non-private $sym refers to private ${tp.symbol}\n in its type signature ${sym.info}",
pos) :: errors
tp
}
@@ -422,20 +422,20 @@ trait Checking {
val sym = tree.tpe.termSymbol
// The check is avoided inside Java compilation units because it always fails
// on the singleton type Module.type.
- if ((sym is Package) || ((sym is JavaModule) && !ctx.compilationUnit.isJava)) ctx.error(d"$sym is not a value", tree.pos)
+ if ((sym is Package) || ((sym is JavaModule) && !ctx.compilationUnit.isJava)) ctx.error(em"$sym is not a value", tree.pos)
}
tree
}
/** Check that type `tp` is stable. */
def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit =
- if (!tp.isStable) ctx.error(d"$tp is not stable", pos)
+ if (!tp.isStable) ctx.error(ex"$tp is not stable", pos)
/** Check that all type members of `tp` have realizable bounds */
def checkRealizableBounds(tp: Type, pos: Position)(implicit ctx: Context): Unit = {
val rstatus = boundsRealizability(tp)
if (rstatus ne Realizable)
- ctx.error(i"$tp cannot be instantiated since it${rstatus.msg}", pos)
+ ctx.error(ex"$tp cannot be instantiated since it${rstatus.msg}", pos)
}
/** Check that `tp` is a class type.
@@ -447,11 +447,11 @@ trait Checking {
def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type =
tp.underlyingClassRef(refinementOK = false) match {
case tref: TypeRef =>
- if (traitReq && !(tref.symbol is Trait)) ctx.error(d"$tref is not a trait", pos)
+ if (traitReq && !(tref.symbol is Trait)) ctx.error(ex"$tref is not a trait", pos)
if (stablePrefixReq && ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos)
tp
case _ =>
- ctx.error(d"$tp is not a class type", pos)
+ ctx.error(ex"$tp is not a class type", pos)
defn.ObjectType
}
@@ -475,7 +475,7 @@ trait Checking {
case tp: RecType =>
tp.rebind(tp.parent)
case tp @ TypeBounds(lo, hi) if !(lo <:< hi) =>
- ctx.error(d"no type exists between low bound $lo and high bound $hi$where", pos)
+ ctx.error(ex"no type exists between low bound $lo and high bound $hi$where", pos)
TypeAlias(hi)
case _ =>
tp
@@ -493,17 +493,17 @@ trait Checking {
typr.println(i"conflict? $decl $other")
if (decl.matches(other)) {
def doubleDefError(decl: Symbol, other: Symbol): Unit = {
- def ofType = if (decl.isType) "" else d": ${other.info}"
+ def ofType = if (decl.isType) "" else em": ${other.info}"
def explanation =
if (!decl.isRealMethod) ""
else "\n (the definitions have matching type signatures)"
- ctx.error(d"$decl is already defined as $other$ofType$explanation", decl.pos)
+ ctx.error(em"$decl is already defined as $other$ofType$explanation", decl.pos)
}
if (decl is Synthetic) doubleDefError(other, decl)
else doubleDefError(decl, other)
}
if ((decl is HasDefaultParams) && (other is HasDefaultParams)) {
- ctx.error(d"two or more overloaded variants of $decl have default arguments")
+ ctx.error(em"two or more overloaded variants of $decl have default arguments")
decl resetFlag HasDefaultParams
}
}
@@ -524,7 +524,7 @@ trait Checking {
ctx.error(i"$caller may not call constructor of $called", call.pos)
else if (called.is(Trait) && !caller.mixins.contains(called))
ctx.error(i"""$called is already implemented by super${caller.superClass},
- |its constructor cannot be called again""".stripMargin, call.pos)
+ |its constructor cannot be called again""", call.pos)
}
/** Check that `tpt` does not define a higher-kinded type */
@@ -532,7 +532,7 @@ trait Checking {
if (tpt.tpe.isHK && !ctx.compilationUnit.isJava) {
// be more lenient with missing type params in Java,
// needed to make pos/java-interop/t1196 work.
- errorTree(tpt, d"missing type parameter for ${tpt.tpe}")
+ errorTree(tpt, ex"missing type parameter for ${tpt.tpe}")
}
else tpt
}
diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala
index 6f7d427cb..ad84ff583 100644
--- a/src/dotty/tools/dotc/typer/ErrorReporting.scala
+++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala
@@ -9,8 +9,8 @@ import Types._, ProtoTypes._, Contexts._, Decorators._, Denotations._, Symbols._
import Applications._, Implicits._, Flags._
import util.Positions._
import reporting.Diagnostic
-import printing.Showable
-import printing.Disambiguation.disambiguated
+import printing.{Showable, RefinedPrinter}
+import scala.collection.mutable
import java.util.regex.Matcher.quoteReplacement
object ErrorReporting {
@@ -38,7 +38,7 @@ object ErrorReporting {
val treeSym = ctx.symOfContextTree(tree)
if (treeSym.exists && treeSym.name == cycleSym.name && treeSym.owner == cycleSym.owner) {
val result = if (cycleSym is Method) " result" else ""
- d"overloaded or recursive $cycleSym needs$result type"
+ em"overloaded or recursive $cycleSym needs$result type"
}
else errorMsg(msg, cx.outer)
case _ =>
@@ -48,6 +48,9 @@ object ErrorReporting {
errorMsg(ex.show, ctx)
}
+ def wrongNumberOfArgs(fntpe: Type, kind: String, expected: Int, pos: Position)(implicit ctx: Context) =
+ errorType(em"wrong number of ${kind}arguments for $fntpe, expected: $expected", pos)
+
class Errors(implicit ctx: Context) {
/** An explanatory note to be added to error messages
@@ -59,15 +62,15 @@ object ErrorReporting {
def expectedTypeStr(tp: Type): String = tp match {
case tp: PolyProto =>
- d"type arguments [${tp.targs}%, %] and ${expectedTypeStr(tp.resultType)}"
+ em"type arguments [${tp.targs}%, %] and ${expectedTypeStr(tp.resultType)}"
case tp: FunProto =>
val result = tp.resultType match {
case _: WildcardType | _: IgnoredProto => ""
- case tp => d" and expected result type $tp"
+ case tp => em" and expected result type $tp"
}
- d"arguments (${tp.typedArgs.tpes}%, %)$result"
+ em"arguments (${tp.typedArgs.tpes}%, %)$result"
case _ =>
- d"expected type $tp"
+ em"expected type $tp"
}
def anonymousTypeMemberStr(tpe: Type) = {
@@ -76,12 +79,12 @@ object ErrorReporting {
case _: PolyType | _: MethodType => "method"
case _ => "value of type"
}
- d"$kind $tpe"
+ em"$kind $tpe"
}
def overloadedAltsStr(alts: List[SingleDenotation]) =
- d"overloaded alternatives of ${denotStr(alts.head)} with types\n" +
- d" ${alts map (_.info)}%\n %"
+ em"overloaded alternatives of ${denotStr(alts.head)} with types\n" +
+ em" ${alts map (_.info)}%\n %"
def denotStr(denot: Denotation): String =
if (denot.isOverloaded) overloadedAltsStr(denot.alternatives)
@@ -97,9 +100,8 @@ object ErrorReporting {
def patternConstrStr(tree: Tree): String = ???
- def typeMismatch(tree: Tree, pt: Type, implicitFailure: SearchFailure = NoImplicitMatches): Tree = {
+ def typeMismatch(tree: Tree, pt: Type, implicitFailure: SearchFailure = NoImplicitMatches): Tree =
errorTree(tree, typeMismatchStr(normalize(tree.tpe, pt), pt) + implicitFailure.postscript)
- }
/** A subtype log explaining why `found` does not conform to `expected` */
def whyNoMatchStr(found: Type, expected: Type) =
@@ -108,28 +110,31 @@ object ErrorReporting {
else
""
- def typeMismatchStr(found: Type, expected: Type) = disambiguated { implicit ctx =>
- def infoStr = found match { // DEBUG
- case tp: TypeRef => s"with info ${tp.info} / ${tp.prefix.toString} / ${tp.prefix.dealias.toString}"
- case _ => ""
- }
+ def typeMismatchStr(found: Type, expected: Type) = {
// replace constrained polyparams and their typevars by their bounds where possible
- val reported = new TypeMap {
+ object reported extends TypeMap {
+ def setVariance(v: Int) = variance = v
+ val constraint = ctx.typerState.constraint
def apply(tp: Type): Type = tp match {
case tp: PolyParam =>
- val e = ctx.typerState.constraint.entry(tp)
- if (e.exists)
- if (variance > 0) e.bounds.hi
- else if (variance < 0) e.bounds.lo
- else tp
- else tp
+ constraint.entry(tp) match {
+ case bounds: TypeBounds =>
+ if (variance < 0) apply(constraint.fullUpperBound(tp))
+ else if (variance > 0) apply(constraint.fullLowerBound(tp))
+ else tp
+ case NoType => tp
+ case instType => apply(instType)
+ }
case tp: TypeVar => apply(tp.stripTypeVar)
case _ => mapOver(tp)
}
}
- d"""type mismatch:
- | found : $found
- | required: ${reported(expected)}""".stripMargin + whyNoMatchStr(found, expected)
+ val found1 = reported(found)
+ reported.setVariance(-1)
+ val expected1 = reported(expected)
+ ex"""type mismatch:
+ | found : $found1
+ | required: $expected1""" + whyNoMatchStr(found, expected)
}
/** Format `raw` implicitNotFound argument, replacing all
@@ -139,35 +144,11 @@ object ErrorReporting {
def implicitNotFoundString(raw: String, paramNames: List[String], args: List[Type]): String = {
def translate(name: String): Option[String] = {
val idx = paramNames.indexOf(name)
- if (idx >= 0) Some(quoteReplacement(args(idx).show)) else None
+ if (idx >= 0) Some(quoteReplacement(ex"${args(idx)}")) else None
}
"""\$\{\w*\}""".r.replaceSomeIn(raw, m => translate(m.matched.drop(2).init))
}
}
def err(implicit ctx: Context): Errors = new Errors
-
- /** The d string interpolator works like the i string interpolator, but marks nonsensical errors
- * using `<nonsensical>...</nonsensical>` tags.
- * Note: Instead of these tags, it would be nicer to return a data structure containing the message string
- * and a boolean indicating whether the message is sensical, but then we cannot use string operations
- * like concatenation, stripMargin etc on the values returned by d"...", and in the current error
- * message composition methods, this is crucial.
- */
- implicit class DiagnosticString(val sc: StringContext) extends AnyVal {
- def d(args: Any*)(implicit ctx: Context): String = {
- def isSensical(arg: Any): Boolean = arg match {
- case l: Seq[_] => l.forall(isSensical(_))
- case tpe: Type if tpe.isErroneous => false
- case NoType => false
- case sym: Symbol if sym.isCompleted =>
- sym.info != ErrorType && sym.info != TypeAlias(ErrorType) && sym.info != NoType
- case _ => true
- }
-
- val s = new StringInterpolators(sc).i(args : _*)
- if (args.forall(isSensical(_))) s
- else Diagnostic.nonSensicalStartTag + s + Diagnostic.nonSensicalEndTag
- }
- }
}
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 1eba64e2e..0a3307140 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -217,8 +217,8 @@ object Implicits {
protected def pt: Type
protected def argument: tpd.Tree
protected def qualify(implicit ctx: Context) =
- if (argument.isEmpty) d"match type $pt"
- else d"convert from ${argument.tpe} to $pt"
+ if (argument.isEmpty) em"match type $pt"
+ else em"convert from ${argument.tpe} to $pt"
/** An explanation of the cause of the failure as a string */
def explanation(implicit ctx: Context): String
@@ -227,7 +227,7 @@ object Implicits {
/** An ambiguous implicits failure */
class AmbiguousImplicits(alt1: TermRef, alt2: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
def explanation(implicit ctx: Context): String =
- d"both ${err.refStr(alt1)} and ${err.refStr(alt2)} $qualify"
+ em"both ${err.refStr(alt1)} and ${err.refStr(alt2)} $qualify"
override def postscript(implicit ctx: Context) =
"\nNote that implicit conversions cannot be applied because they are ambiguous;" +
"\n " + explanation
@@ -235,17 +235,17 @@ object Implicits {
class NonMatchingImplicit(ref: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
def explanation(implicit ctx: Context): String =
- d"${err.refStr(ref)} does not $qualify"
+ em"${err.refStr(ref)} does not $qualify"
}
class ShadowedImplicit(ref: TermRef, shadowing: Type, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
def explanation(implicit ctx: Context): String =
- d"${err.refStr(ref)} does $qualify but is shadowed by ${err.refStr(shadowing)}"
+ em"${err.refStr(ref)} does $qualify but is shadowed by ${err.refStr(shadowing)}"
}
class DivergingImplicit(ref: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
def explanation(implicit ctx: Context): String =
- d"${err.refStr(ref)} produces a diverging implicit search when trying to $qualify"
+ em"${err.refStr(ref)} produces a diverging implicit search when trying to $qualify"
}
class FailedImplicit(failures: List[ExplainedSearchFailure], val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
@@ -253,7 +253,9 @@ object Implicits {
if (failures.isEmpty) s" No implicit candidates were found that $qualify"
else " " + (failures map (_.explanation) mkString "\n ")
override def postscript(implicit ctx: Context): String =
- "\nImplicit search failure summary:\n" + explanation
+ i"""
+ |Implicit search failure summary:
+ |$explanation"""
}
}
@@ -456,7 +458,7 @@ trait Implicits { self: Typer =>
if (!arg.isEmpty) arg
else {
var msgFn = (where: String) =>
- d"no implicit argument of type $formal found for $where" + failure.postscript
+ em"no implicit argument of type $formal found for $where" + failure.postscript
for {
notFound <- formal.typeSymbol.getAnnotation(defn.ImplicitNotFoundAnnot)
Trees.Literal(Constant(raw: String)) <- notFound.argument(0)
@@ -568,7 +570,7 @@ trait Implicits { self: Typer =>
// Not clear whether we need to drop the `.widen` here. All tests pass with it in place, though.
assert(argument.isEmpty || argument.tpe.isValueType || argument.tpe.isInstanceOf[ExprType],
- d"found: $argument: ${argument.tpe}, expected: $pt")
+ em"found: $argument: ${argument.tpe}, expected: $pt")
/** The expected type for the searched implicit */
lazy val fullProto = implicitProto(pt, identity)
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index f917c233f..698f7e9a9 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -646,7 +646,7 @@ class Namer { typer: Typer =>
val pname = paramAccessor.name
def illegal(how: String): Unit = {
- ctx.error(d"Illegal override of public type parameter $pname in $parent$how", paramAccessor.pos)
+ ctx.error(em"Illegal override of public type parameter $pname in $parent$how", paramAccessor.pos)
ok = false
}
@@ -659,7 +659,7 @@ class Namer { typer: Typer =>
case TypeRef(pre, name1) if name1 == pname && (pre =:= cls.thisType) =>
// OK, parameter is passed on directly
case _ =>
- illegal(d".\nParameter is both redeclared and instantiated with $alias.")
+ illegal(em".\nParameter is both redeclared and instantiated with $alias.")
}
case _ => // OK, argument is not fully defined
}
@@ -832,7 +832,7 @@ class Namer { typer: Typer =>
// println(s"final inherited for $sym: ${inherited.toString}") !!!
// println(s"owner = ${sym.owner}, decls = ${sym.owner.info.decls.show}")
def isInline = sym.is(Final, butNot = Method | Mutable)
-
+
// Widen rhs type and approximate `|' but keep ConstantTypes if
// definition is inline (i.e. final in Scala2).
def widenRhs(tp: Type): Type = tp.widenTermRefExpr match {
@@ -856,7 +856,7 @@ class Namer { typer: Typer =>
else {
if (sym is Implicit) {
val resStr = if (mdef.isInstanceOf[DefDef]) "result " else ""
- ctx.error(d"${resStr}type of implicit definition needs to be given explicitly", mdef.pos)
+ ctx.error(s"${resStr}type of implicit definition needs to be given explicitly", mdef.pos)
sym.resetFlag(Implicit)
}
lhsType orElse WildcardType
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala
index a654bb08f..2838866fd 100644
--- a/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -81,14 +81,14 @@ object RefChecks {
def checkSelfConforms(other: TypeRef, category: String, relation: String) = {
val otherSelf = other.givenSelfType.asSeenFrom(cls.thisType, other.classSymbol)
if (otherSelf.exists && !(cinfo.selfType <:< otherSelf))
- ctx.error(d"$category: self type ${cinfo.selfType} of $cls does not conform to self type $otherSelf of $relation ${other.classSymbol}", cls.pos)
+ ctx.error(ex"$category: self type ${cinfo.selfType} of $cls does not conform to self type $otherSelf of $relation ${other.classSymbol}", cls.pos)
}
for (parent <- cinfo.classParents) {
val pclazz = parent.classSymbol
if (pclazz.is(Final))
- ctx.error(d"cannot extend final $pclazz", cls.pos)
+ ctx.error(em"cannot extend final $pclazz", cls.pos)
if (pclazz.is(Sealed) && pclazz.associatedFile != cls.associatedFile)
- ctx.error(d"cannot extend sealed $pclazz in different compilation unit", cls.pos)
+ ctx.error(em"cannot extend sealed $pclazz in different compilation unit", cls.pos)
checkSelfConforms(parent, "illegal inheritance", "parent")
}
for (reqd <- cinfo.givenSelfType.classSymbols)
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index c2b7b7101..ab151fb1d 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -171,13 +171,13 @@ trait TypeAssigner {
case sym :: Nil =>
if (sym.owner == pre.typeSymbol) sym.show else sym.showLocated
case _ =>
- d"none of the overloaded alternatives named $name"
+ em"none of the overloaded alternatives named $name"
}
val where = if (ctx.owner.exists) s" from ${ctx.owner.enclosingClass}" else ""
val whyNot = new StringBuffer
alts foreach (_.isAccessibleFrom(pre, superAccess, whyNot))
if (!tpe.isError)
- ctx.error(d"$what cannot be accessed as a member of $pre$where.$whyNot", pos)
+ ctx.error(ex"$what cannot be accessed as a member of $pre$where.$whyNot", pos)
ErrorType
}
}
@@ -205,10 +205,12 @@ trait TypeAssigner {
if (!site.isErroneous) {
def notAMember = d"${if (name.isTypeName) "type" else "value"} $name is not a member of $site"
ctx.error(
- if (name == nme.CONSTRUCTOR) d"$site does not have a constructor"
- else if (site.derivesFrom(defn.DynamicClass)) s"$notAMember\npossible cause: maybe a wrong Dynamic method signature?"
- else notAMember,
- pos)
+ if (name == nme.CONSTRUCTOR) ex"$site does not have a constructor"
+ else if (site.derivesFrom(defn.DynamicClass)) {
+ ex"$name is not a member of $site\n" +
+ "possible cause: maybe a wrong Dynamic method signature?"
+ }
+ else ex"$name is not a member of $site", pos)
}
ErrorType
}
@@ -283,7 +285,7 @@ trait TypeAssigner {
case p :: Nil =>
p
case Nil =>
- errorType(d"$mix does not name a parent class of $cls", tree.pos)
+ errorType(em"$mix does not name a parent class of $cls", tree.pos)
case p :: q :: _ =>
errorType("ambiguous parent class qualifier", tree.pos)
}
@@ -302,7 +304,7 @@ trait TypeAssigner {
val ownType = fn.tpe.widen match {
case fntpe @ MethodType(_, ptypes) =>
if (sameLength(ptypes, args) || ctx.phase.prev.relaxedTyping) fntpe.instantiate(args.tpes)
- else errorType(i"wrong number of parameters for ${fn.tpe}; expected: ${ptypes.length}", tree.pos)
+ else wrongNumberOfArgs(fn.tpe, "", ptypes.length, tree.pos)
case t =>
errorType(i"${err.exprStr(fn)} does not take parameters", tree.pos)
}
@@ -348,7 +350,7 @@ trait TypeAssigner {
else {
val argTypes = args.tpes
if (sameLength(argTypes, paramNames)|| ctx.phase.prev.relaxedTyping) pt.instantiate(argTypes)
- else errorType(d"wrong number of type parameters for ${fn.tpe}; expected: ${pt.paramNames.length}", tree.pos)
+ else wrongNumberOfArgs(fn.tpe, "type ", pt.paramNames.length, tree.pos)
}
case _ =>
errorType(i"${err.exprStr(fn)} does not take type parameters", tree.pos)
@@ -429,7 +431,7 @@ trait TypeAssigner {
val ownType =
if (hasNamedArg(args)) (tycon.tpe /: args)(refineNamed)
else if (sameLength(tparams, args)) tycon.tpe.appliedTo(args.tpes)
- else errorType(d"wrong number of type arguments for ${tycon.tpe}, should be ${tparams.length}", tree.pos)
+ else wrongNumberOfArgs(tycon.tpe, "type ", tparams.length, tree.pos)
tree.withType(ownType)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index e982f9aa9..2b690ef51 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -134,8 +134,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
* or defined in <symbol>
*/
def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
- if (prec == wildImport || prec == namedImport) d"imported$qualifier by ${whereFound.importInfo}"
- else d"defined$qualifier in ${whereFound.owner}"
+ if (prec == wildImport || prec == namedImport) ex"imported$qualifier by ${whereFound.importInfo}"
+ else ex"defined$qualifier in ${whereFound.owner}"
/** Check that any previously found result from an inner context
* does properly shadow the new one from an outer context.
@@ -152,9 +152,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
else {
if (!previous.isError && !found.isError) {
error(
- d"""reference to $name is ambiguous;
- |it is both ${bindingString(newPrec, ctx, "")}
- |and ${bindingString(prevPrec, prevCtx, " subsequently")}""".stripMargin,
+ ex"""reference to $name is ambiguous;
+ |it is both ${bindingString(newPrec, ctx, "")}
+ |and ${bindingString(prevPrec, prevCtx, " subsequently")}""",
tree.pos)
}
previous
@@ -167,7 +167,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def checkUnambiguous(found: Type) = {
val other = namedImportRef(site, selectors.tail)
if (other.exists && found.exists && (found != other))
- error(d"reference to $name is ambiguous; it is imported twice in ${ctx.tree}",
+ error(em"reference to $name is ambiguous; it is imported twice in ${ctx.tree}",
tree.pos)
found
}
@@ -275,7 +275,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (rawType.exists)
ensureAccessible(rawType, superAccess = false, tree.pos)
else {
- error(d"not found: $kind$name", tree.pos)
+ error(em"not found: $kind$name", tree.pos)
ErrorType
}
@@ -304,10 +304,10 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
tree match {
case tree @ Select(qual, _) if !qual.tpe.isStable =>
val alt = typedSelect(tree, pt, Typed(qual, TypeTree(SkolemType(qual.tpe.widen))))
- typr.println(d"healed type: ${tree.tpe} --> $alt")
+ typr.println(i"healed type: ${tree.tpe} --> $alt")
alt.asInstanceOf[T]
case _ =>
- ctx.error(d"unsafe instantiation of type ${tree.tpe}", tree.pos)
+ ctx.error(ex"unsafe instantiation of type ${tree.tpe}", tree.pos)
tree
}
else tree
@@ -342,7 +342,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
convertToSelectFromType(tree.qualifier, tree.name) match {
case Some(sftt) => typedSelectFromTypeTree(sftt, pt)
- case _ => ctx.error(d"Could not convert $tree to a SelectFromTypeTree"); EmptyTree
+ case _ => ctx.error(em"Could not convert $tree to a SelectFromTypeTree"); EmptyTree
}
}
@@ -569,7 +569,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
ensureNoLocalRefs(tree1, pt, localSyms, forcedDefined = true)
} else
errorTree(tree,
- d"local definition of ${leaks.head.name} escapes as part of expression's type ${tree.tpe}"/*; full type: ${result.tpe.toString}"*/)
+ em"local definition of ${leaks.head.name} escapes as part of expression's type ${tree.tpe}"/*; full type: ${result.tpe.toString}"*/)
}
def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = track("typedIf") {
@@ -723,7 +723,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
pt match {
case SAMType(meth) if !defn.isFunctionType(pt) && mt <:< meth.info =>
if (!isFullyDefined(pt, ForceDegree.all))
- ctx.error(d"result type of closure is an underspecified SAM type $pt", tree.pos)
+ ctx.error(ex"result type of closure is an underspecified SAM type $pt", tree.pos)
TypeTree(pt)
case _ =>
if (!mt.isDependent) EmptyTree
@@ -802,7 +802,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
super.transform(tree.withType(elimWildcardSym(tree.tpe))) match {
case b: Bind =>
if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol)
- else ctx.error(d"duplicate pattern variable: ${b.name}", b.pos)
+ else ctx.error(em"duplicate pattern variable: ${b.name}", b.pos)
b.symbol.info = elimWildcardSym(b.symbol.info)
b
case t => t
@@ -854,7 +854,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val proto = returnProto(owner, cx.scope)
(from, proto)
}
- else (EmptyTree, errorType(d"$owner has return statement; needs result type", tree.pos))
+ else (EmptyTree, errorType(em"$owner has return statement; needs result type", tree.pos))
}
else enclMethInfo(cx.outer)
}
@@ -973,7 +973,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val tpt1 = typed(tree.tpt, AnyTypeConstructorProto)(ctx.retractMode(Mode.Pattern))
val tparams = tpt1.tpe.typeParams
if (tparams.isEmpty) {
- ctx.error(d"${tpt1.tpe} does not take type parameters", tree.pos)
+ ctx.error(ex"${tpt1.tpe} does not take type parameters", tree.pos)
tpt1
}
else {
@@ -982,7 +982,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (hasNamedArg(args)) typedNamedArgs(args)
else {
if (args.length != tparams.length) {
- ctx.error(d"wrong number of type arguments for ${tpt1.tpe}, should be ${tparams.length}", tree.pos)
+ wrongNumberOfArgs(tpt1.tpe, "type ", tparams.length, tree.pos)
args = args.take(tparams.length)
}
def typedArg(arg: untpd.Tree, tparam: TypeParamInfo) = {
@@ -1207,7 +1207,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case _ =>
// add synthetic class type
val first :: _ = ensureFirstIsClass(parents.tpes)
- TypeTree(checkFeasible(first, pos, d"\n in inferred parent $first")).withPos(pos) :: parents
+ TypeTree(checkFeasible(first, pos, em"\n in inferred parent $first")).withPos(pos) :: parents
}
/** If this is a real class, make sure its first parent is a
@@ -1239,7 +1239,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val packageContext =
if (pkg is Package) ctx.fresh.setOwner(pkg.moduleClass).setTree(tree)
else {
- ctx.error(d"$pkg is already defined, cannot be a package", tree.pos)
+ ctx.error(em"$pkg is already defined, cannot be a package", tree.pos)
ctx
}
val stats1 = typedStats(tree.stats, pkg.moduleClass)(packageContext)
@@ -1522,8 +1522,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def methodStr = err.refStr(methPart(tree).tpe)
def missingArgs = errorTree(tree,
- d"""missing arguments for $methodStr
- |follow this method with `_' if you want to treat it as a partially applied function""".stripMargin)
+ em"""missing arguments for $methodStr
+ |follow this method with `_' if you want to treat it as a partially applied function""")
def adaptOverloaded(ref: TermRef) = {
val altDenots = ref.denot.alternatives
@@ -1537,8 +1537,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Nil =>
def noMatches =
errorTree(tree,
- d"""none of the ${err.overloadedAltsStr(altDenots)}
- |match $expectedStr""".stripMargin)
+ em"""none of the ${err.overloadedAltsStr(altDenots)}
+ |match $expectedStr""")
def hasEmptyParams(denot: SingleDenotation) = denot.info.paramTypess == ListOfNil
pt match {
case pt: FunProto =>
@@ -1553,8 +1553,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val remainingDenots = alts map (_.denot.asInstanceOf[SingleDenotation])
def all = if (remainingDenots.length == 2) "both" else "all"
errorTree(tree,
- d"""Ambiguous overload. The ${err.overloadedAltsStr(remainingDenots)}
- |$all match $expectedStr""".stripMargin)
+ em"""Ambiguous overload. The ${err.overloadedAltsStr(remainingDenots)}
+ |$all match $expectedStr""")
}
}
@@ -1581,7 +1581,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Apply(_, _) => " more"
case _ => ""
}
- (_, _) => errorTree(tree, d"$methodStr does not take$more parameters")
+ (_, _) => errorTree(tree, em"$methodStr does not take$more parameters")
}
}
@@ -1630,7 +1630,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
def implicitArgError(msg: String => String) =
- errors += (() => msg(d"parameter $pname of $methodStr"))
+ errors += (() => msg(em"parameter $pname of $methodStr"))
inferImplicitArg(formal, implicitArgError, tree.pos.endPos)
}
if (errors.nonEmpty) {