diff options
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Decorators.scala | 33 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/Reporter.scala | 33 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 14 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 24 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ErrorReporting.scala | 64 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 14 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ImportInfo.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/TypeAssigner.scala | 22 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 48 |
15 files changed, 142 insertions, 125 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index ea9e7566a..8d891b9d9 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -9,7 +9,6 @@ import Decorators._ import language.higherKinds import collection.mutable.ListBuffer import config.Printers._ -import typer.ErrorReporting.InfoString import typer.Mode object desugar { diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 5dc08386f..4f95ff247 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -511,9 +511,6 @@ object Contexts { protected[dotc] val indentTab = " " - /** Should warnings and errors containing non-sensical strings be suppressed? */ - private[dotc] var suppressNonSensicalErrors = true - def reset() = { for ((_, set) <- uniqueSets) set.clear() for (i <- 0 until classOfId.length) classOfId(i) = null diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala index 21f914d99..25b5dbabc 100644 --- a/src/dotty/tools/dotc/core/Decorators.scala +++ b/src/dotty/tools/dotc/core/Decorators.scala @@ -3,7 +3,7 @@ package core import annotation.tailrec import Symbols._ -import Contexts._, Names._, Phases._, printing.Texts._, printing.Printer +import Contexts._, Names._, Phases._, printing.Texts._, printing.Printer, printing.Showable import util.Positions.Position, util.SourcePosition import collection.mutable.ListBuffer import dotty.tools.dotc.transform.TreeTransforms._ @@ -136,5 +136,36 @@ object Decorators { implicit def sourcePos(pos: Position)(implicit ctx: Context): SourcePosition = ctx.source.atPos(pos) + + /** The i"..." string interpolator adds two features to the s interpolator: + * 1) On all Showables, `show` is called instead of `toString` + * 2) Lists can be formatted using the desired separator between two `%` signs, + * eg `i"myList = (${myList}%, %)"` + */ + implicit class InfoString(val sc: StringContext) extends AnyVal { + + def i(args: Any*)(implicit ctx: Context): String = { + + def treatArg(arg: Any, suffix: String): (Any, String) = arg match { + case arg: Seq[_] if suffix.nonEmpty && suffix.head == '%' => + val (rawsep, rest) = suffix.tail.span(_ != '%') + val sep = StringContext.treatEscapes(rawsep) + if (rest.nonEmpty) (arg map treatSingleArg mkString sep, rest.tail) + else (arg, suffix) + case _ => + (treatSingleArg(arg), suffix) + } + + def treatSingleArg(arg: Any) : Any = arg match { + case arg: Showable => arg.show + case _ => arg + } + + val prefix :: suffixes = sc.parts.toList + val (args1, suffixes1) = (args, suffixes).zipped.map(treatArg(_, _)).unzip + new StringContext(prefix :: suffixes1.toList: _*).s(args1: _*) + } + } + } diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala index 933262861..b0404c6b3 100644 --- a/src/dotty/tools/dotc/reporting/Reporter.scala +++ b/src/dotty/tools/dotc/reporting/Reporter.scala @@ -10,26 +10,27 @@ import collection.mutable import config.Settings.Setting import config.Printers import java.lang.System.currentTimeMillis +import typer.ErrorReporting.DiagnosticString object Reporter { - class Diagnostic(msgFn: => String, val pos: SourcePosition, val severity: Severity, base: ContextBase) extends Exception { + class Diagnostic(msgFn: => String, val pos: SourcePosition, val severity: Severity) extends Exception { + import DiagnosticString._ private var myMsg: String = null - private var myIsSuppressed: Boolean = false + private var myIsNonSensical: Boolean = false def msg: String = { - if (myMsg == null) - try myMsg = msgFn - catch { - case ex: SuppressedMessage => - myIsSuppressed = true - val saved = base.suppressNonSensicalErrors - base.suppressNonSensicalErrors = false - try myMsg = msgFn - finally base.suppressNonSensicalErrors = saved + if (myMsg == null) { + myMsg = msgFn + if (myMsg.contains(nonSensicalStartTag)) { + myIsNonSensical = true + // myMsg might be composed of several d"..." invocations -> nested nonsensical tags possible + myMsg = myMsg.replaceAllLiterally(nonSensicalStartTag, "").replaceAllLiterally(nonSensicalEndTag, "") } + } myMsg } - def isSuppressed = { msg; myIsSuppressed } + def isNonSensical = { msg; myIsNonSensical } + def isSuppressed(implicit ctx: Context): Boolean = !ctx.settings.YshowSuppressedErrors.value && isNonSensical override def toString = s"$severity at $pos: $msg" override def getMessage() = msg @@ -38,8 +39,8 @@ object Reporter { else severity } - def Diagnostic(msgFn: => String, pos: SourcePosition, severity: Severity)(implicit ctx: Context) = - new Diagnostic(msgFn, pos, severity, ctx.base) + def Diagnostic(msgFn: => String, pos: SourcePosition, severity: Severity) = + new Diagnostic(msgFn, pos, severity) class Severity(val level: Int) extends AnyVal { override def toString = this match { @@ -71,8 +72,6 @@ object Reporter { case UncheckedWARNING => ctx.settings.unchecked case FeatureWARNING => ctx.settings.feature } - - class SuppressedMessage extends Exception } import Reporter._ @@ -221,7 +220,7 @@ abstract class Reporter { def report(d: Diagnostic)(implicit ctx: Context): Unit = if (!isHidden(d)) { doReport(d) - count(d.promotedSeverity.level) += 1 + if (!d.isSuppressed) count(d.promotedSeverity.level) += 1 } def incomplete(d: Diagnostic)(implicit ctx: Context): Unit = diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index ea3afc679..5913875b8 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -10,6 +10,7 @@ import core.Symbols._ import core.Types._ import core.Constants._ import core.StdNames._ +import core.Decorators._ import core.transform.Erasure.isUnboundedGeneric import typer.ErrorReporting._ import ast.Trees._ diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 9a21e1c54..57f11480c 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -588,9 +588,9 @@ trait Applications extends Compatibility { self: Typer => def extractorMemberType(tp: Type, name: Name) = { val ref = tp member name if (ref.isOverloaded) - errorType(s"Overloaded reference to ${ref.show} is not allowed in extractor", tree.pos) + errorType(i"Overloaded reference to $ref is not allowed in extractor", tree.pos) else if (ref.info.isInstanceOf[PolyType]) - errorType(s"Reference to polymorphic ${ref.show}: ${ref.info.show} is not allowed in extractor", tree.pos) + errorType(i"Reference to polymorphic $ref: ${ref.info} is not allowed in extractor", tree.pos) else ref.info.widenExpr.dealias } @@ -618,7 +618,7 @@ trait Applications extends Compatibility { self: Typer => if (unapplyResult derivesFrom defn.SeqClass) seqSelector :: Nil else if (unapplyResult isRef defn.BooleanClass) Nil else { - ctx.error(s"${unapplyResult.show} is not a valid result type of an unapply method of an extractor", tree.pos) + ctx.error(i"$unapplyResult is not a valid result type of an unapply method of an extractor", tree.pos) Nil } } @@ -636,7 +636,7 @@ trait Applications extends Compatibility { self: Typer => unapplyFn.tpe.widen match { case mt: MethodType if mt.paramTypes.length == 1 && !mt.isDependent => val unapplyArgType = mt.paramTypes.head - unapp.println(s"unapp arg tpe = ${unapplyArgType.show}, pt = ${pt.show}") + unapp.println(i"unapp arg tpe = $unapplyArgType, pt = $pt") def wpt = widenForMatchSelector(pt) // needed? val ownType = if (pt <:< unapplyArgType) { @@ -647,7 +647,7 @@ trait Applications extends Compatibility { self: Typer => maximizeType(unapplyArgType) match { case Some(tvar) => def msg = - i"""There is no best instantiation of pattern type $unapplyArgType + d"""There is no best instantiation of pattern type $unapplyArgType |that makes it a subtype of selector type $pt. |Non-variant type variable ${tvar.origin} cannot be uniquely instantiated.""".stripMargin if (fromScala2x) { @@ -671,7 +671,7 @@ trait Applications extends Compatibility { self: Typer => unapp.println("Neither sub nor super") unapp.println(TypeComparer.explained(implicit ctx => unapplyArgType <:< wpt)) errorType( - i"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $wpt", + d"Pattern type $unapplyArgType is neither a subtype nor a supertype of selector type $wpt", tree.pos) } @@ -692,7 +692,7 @@ trait Applications extends Compatibility { self: Typer => case _ => args } if (argTypes.length != bunchedArgs.length) { - ctx.error(i"wrong number of argument patterns for $qual; expected: ($argTypes%, %)", tree.pos) + ctx.error(d"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 5818da180..287e93c7a 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -14,7 +14,7 @@ import util.{Stats, SimpleMap} import util.common._ import Decorators._ import Uniques._ -import ErrorReporting.{errorType, InfoString} +import ErrorReporting.{errorType, DiagnosticString} import config.Printers._ import collection.mutable @@ -27,7 +27,7 @@ trait Checking { def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = { if (!proto.isInstanceOf[SelectionProto]) { val sym = tree.tpe.termSymbol - if ((sym is Package) || (sym is JavaModule)) ctx.error(i"$sym is not a value", tree.pos) + if ((sym is Package) || (sym is JavaModule)) ctx.error(d"$sym is not a value", tree.pos) } tree } @@ -38,7 +38,7 @@ trait Checking { def substituted(tp: Type) = tp.substParams(poly, argTypes) for ((arg, bounds) <- args zip poly.paramBounds) { def notConforms(which: String, bound: Type) = - ctx.error(i"Type argument ${arg.tpe} does not conform to $which bound $bound", arg.pos) + ctx.error(d"Type argument ${arg.tpe} does not conform to $which bound $bound", arg.pos) if (!(arg.tpe <:< substituted(bounds.hi))) notConforms("upper", bounds.hi) if (!(bounds.lo <:< arg.tpe)) notConforms("lower", bounds.lo) } @@ -46,13 +46,13 @@ trait Checking { /** Check that type `tp` is stable. */ def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = - if (!tp.isStable) ctx.error(i"$tp is not stable", pos) + if (!tp.isStable) ctx.error(d"$tp is not stable", pos) /** Check that type `tp` is a legal prefix for '#'. * @return The type itself */ def checkLegalPrefix(tp: Type, pos: Position)(implicit ctx: Context): Unit = - if (!tp.isLegalPrefix) ctx.error(i"$tp is not a valid prefix for '#'", pos) + if (!tp.isLegalPrefix) ctx.error(d"$tp is not a valid prefix for '#'", pos) /** Check that `tp` is a class type with a stable prefix. Also, if `isFirst` is * false check that `tp` is a trait. @@ -62,10 +62,10 @@ trait Checking { tp.underlyingClassRef match { case tref: TypeRef => checkStable(tref.prefix, pos) - if (traitReq && !(tref.symbol is Trait)) ctx.error(i"$tref is not a trait", pos) + if (traitReq && !(tref.symbol is Trait)) ctx.error(d"$tref is not a trait", pos) tp case _ => - ctx.error(i"$tp is not a class type", pos) + ctx.error(d"$tp is not a class type", pos) defn.ObjectClass.typeRef } @@ -74,7 +74,7 @@ trait Checking { case tpt: untpd.DerivedTypeTree => case TypeTree(untpd.EmptyTree) => val resStr = if (defTree.isInstanceOf[untpd.DefDef]) "result " else "" - ctx.error(i"${resStr}type of implicit definition needs to be given explicitly", defTree.pos) + ctx.error(d"${resStr}type of implicit definition needs to be given explicitly", defTree.pos) case _ => } @@ -96,7 +96,7 @@ trait Checking { case tp: RefinedType => tp.derivedRefinedType(tp.parent, tp.refinedName, checkFeasible(tp.refinedInfo, pos, where)) case tp @ TypeBounds(lo, hi) if !(lo <:< hi) => - ctx.error(i"no type exists between low bound $lo and high bound $hi$where", pos) + ctx.error(d"no type exists between low bound $lo and high bound $hi$where", pos) tp.derivedTypeAlias(hi) case _ => tp @@ -113,17 +113,17 @@ trait Checking { typr.println(i"conflict? $decl $other") if (decl.signature matches other.signature) { def doubleDefError(decl: Symbol, other: Symbol): Unit = { - def ofType = if (decl.isType) "" else i": ${other.info}" + def ofType = if (decl.isType) "" else d": ${other.info}" def explanation = if (!decl.isSourceMethod) "" else "\n (both definitions have the same erased type signature)" - ctx.error(i"$decl is already defined as $other$ofType$explanation", decl.pos) + ctx.error(d"$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(i"two or more overloaded variants of $decl have default arguments") + ctx.error(d"two or more overloaded variants of $decl have default arguments") decl resetFlag HasDefaultParams } } diff --git a/src/dotty/tools/dotc/typer/ErrorReporting.scala b/src/dotty/tools/dotc/typer/ErrorReporting.scala index 397285f6a..8f9b01fe6 100644 --- a/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -10,7 +10,6 @@ import Applications._, Implicits._ import util.Positions._ import printing.Showable import printing.Disambiguation.disambiguated -import reporting.Reporter.SuppressedMessage object ErrorReporting { @@ -33,7 +32,7 @@ object ErrorReporting { val treeSym = ctx.symOfContextTree(tree) if (treeSym.exists && treeSym.name == cycleSym.name && treeSym.owner == cycleSym.owner) { val result = if (cycleSym.isSourceMethod) " result" else "" - i"overloaded or recursive $cycleSym needs$result type" + d"overloaded or recursive $cycleSym needs$result type" } else errorMsg(msg, cx.outer) case _ => @@ -49,11 +48,11 @@ object ErrorReporting { case tp: FunProto => val result = tp.resultType match { case tp: WildcardType => "" - case tp => i"and expected result type $tp" + case tp => d"and expected result type $tp" } - i"arguments (${tp.typedArgs.tpes}%, %)$result" + d"arguments (${tp.typedArgs.tpes}%, %)$result" case _ => - i"expected type $tp" + d"expected type $tp" } def anonymousTypeMemberStr(tpe: Type) = { @@ -62,12 +61,12 @@ object ErrorReporting { case _: PolyType | _: MethodType => "method" case _ => "value of type" } - i"$kind $tpe" + d"$kind $tpe" } def overloadedAltsStr(alts: List[SingleDenotation]) = - i"overloaded alternatives of ${denotStr(alts.head)} with types\n" + - i" ${alts map (_.info)}%\n %" + d"overloaded alternatives of ${denotStr(alts.head)} with types\n" + + d" ${alts map (_.info)}%\n %" def denotStr(denot: Denotation): String = if (denot.isOverloaded) overloadedAltsStr(denot.alternatives) @@ -97,7 +96,7 @@ object ErrorReporting { case tp: TypeRef => s"with info ${tp.info} / ${tp.prefix.toString} / ${tp.prefix.dealias.toString}" case _ => "" } - i"""type mismatch: + d"""type mismatch: | found : $found | required: $expected""".stripMargin + typerStateStr + explanationStr } @@ -105,12 +104,18 @@ object ErrorReporting { def err(implicit ctx: Context): Errors = new Errors - /** Implementation of i"..." string interpolator */ - implicit class InfoString(val sc: StringContext) extends AnyVal { - - def i(args: Any*)(implicit ctx: Context): String = { - + /** 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 { + import DiagnosticString._ + 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 => @@ -118,29 +123,14 @@ object ErrorReporting { case _ => true } - def treatArg(arg: Any, suffix: String): (Any, String) = arg match { - case arg: List[_] if suffix.nonEmpty && suffix.head == '%' => - val (rawsep, rest) = suffix.tail.span(_ != '%') - val sep = StringContext.treatEscapes(rawsep) - if (rest.nonEmpty) (arg map treatSingleArg mkString sep, rest.tail) - else (arg, suffix) - case _ => - (treatSingleArg(arg), suffix) - } - - def treatSingleArg(arg: Any) : Any = arg match { - case arg: Showable => arg.show - case _ => arg - } - - if (ctx.reporter.hasErrors && - ctx.suppressNonSensicalErrors && - !ctx.settings.YshowSuppressedErrors.value && - !args.forall(isSensical(_))) - throw new SuppressedMessage - val prefix :: suffixes = sc.parts.toList - val (args1, suffixes1) = (args, suffixes).zipped.map(treatArg(_, _)).unzip - new StringContext(prefix :: suffixes1.toList: _*).s(args1: _*) + val s = new InfoString(sc).i(args : _*) + if (args.forall(isSensical(_))) s else nonSensicalStartTag + s + nonSensicalEndTag } } + + object DiagnosticString { + final val nonSensicalStartTag = "<nonsensical>" + final val nonSensicalEndTag = "</nonsensical>" + } + }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index db549b2d4..93876651a 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -204,8 +204,8 @@ object Implicits { protected def pt: Type protected def argument: tpd.Tree protected def qualify(implicit ctx: Context) = - if (argument.isEmpty) i"match type $pt" - else i"convert from ${argument.tpe} to $pt" + if (argument.isEmpty) d"match type $pt" + else d"convert from ${argument.tpe} to $pt" /** An explanation of the cause of the failure as a string */ def explanation(implicit ctx: Context): String @@ -214,7 +214,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 = - i"both ${err.refStr(alt1)} and ${err.refStr(alt2)} $qualify" + d"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 @@ -222,17 +222,17 @@ object Implicits { class NonMatchingImplicit(ref: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure { def explanation(implicit ctx: Context): String = - i"${err.refStr(ref)} does not $qualify" + d"${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 = - i"${err.refStr(ref)} does $qualify but is shadowed by ${err.refStr(shadowing)}" + d"${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 = - i"${err.refStr(ref)} produces a diverging implicit search when trying to $qualify" + d"${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 { @@ -425,7 +425,7 @@ trait Implicits { self: Typer => if (argument.isEmpty) f(resultType) else ViewProto(f(argument.tpe.widen), f(resultType)) assert(argument.isEmpty || argument.tpe.isValueType || argument.tpe.isInstanceOf[ExprType], - i"found: ${argument.tpe}, expected: $pt") + d"found: ${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/ImportInfo.scala b/src/dotty/tools/dotc/typer/ImportInfo.scala index 8c5f0c1e6..9fbd07102 100644 --- a/src/dotty/tools/dotc/typer/ImportInfo.scala +++ b/src/dotty/tools/dotc/typer/ImportInfo.scala @@ -7,7 +7,7 @@ import ast.Trees._ import core._ import util.SimpleMap import Symbols._, Names._, Denotations._, Types._, Contexts._, StdNames._, Flags._ -import typer.ErrorReporting.InfoString +import Decorators.InfoString object ImportInfo { /** The import info for a root import from given symbol `sym` */ diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 173ac3aeb..bd44ccac5 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -15,7 +15,7 @@ import util.{Stats, SimpleMap} import util.common._ import Decorators._ import Uniques._ -import ErrorReporting.{errorType, InfoString} +import ErrorReporting.{errorType, DiagnosticString} import config.Printers._ import collection.mutable @@ -153,7 +153,7 @@ trait Inferencing { this: Checking => case _ => // add synthetic class type val first :: _ = ensureFirstIsClass(parents.tpes) - TypeTree(checkFeasible(first, pos, i"\n in inferred parent $first")).withPos(pos) :: parents + TypeTree(checkFeasible(first, pos, d"\n in inferred parent $first")).withPos(pos) :: parents } /** Interpolate those undetermined type variables in the widened type of this tree diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index d0e78185f..2425bea50 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -209,7 +209,7 @@ class Namer { typer: Typer => ctx.error(s"${preExisting.showLocated} is compiled twice, runid = ${ctx.runId}", tree.pos) } else if ((!ctx.owner.isClass || name.isTypeName) && preExisting.exists) { - ctx.error(i"$name is already defined as $preExisting") + ctx.error(d"$name is already defined as $preExisting") } } diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 16869454f..aeba02648 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -14,7 +14,7 @@ import util.{Stats, SimpleMap} import util.common._ import Decorators._ import Uniques._ -import ErrorReporting.{errorType, InfoString} +import ErrorReporting.errorType import config.Printers._ import collection.mutable diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index 5345b7396..5821b58b2 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -118,13 +118,13 @@ trait TypeAssigner { case sym :: Nil => if (sym.owner == pre.typeSymbol) sym.show else sym.showLocated case _ => - i"none of the overloaded alternatives named $name" + d"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(i"$what cannot be accessed as a member of $pre$where.$whyNot", pos) + ctx.error(d"$what cannot be accessed as a member of $pre$where.$whyNot", pos) ErrorType } } else if (d.symbol is TypeParamAccessor) // always dereference type param accessors @@ -145,8 +145,8 @@ trait TypeAssigner { else { if (!site.isErroneous) { ctx.error( - if (name == nme.CONSTRUCTOR) i"$site does not have a constructor" - else i"$name is not a member of $site", pos) + if (name == nme.CONSTRUCTOR) d"$site does not have a constructor" + else d"$name is not a member of $site", pos) } ErrorType } @@ -202,9 +202,9 @@ trait TypeAssigner { case p :: Nil => p case Nil => - errorType(i"$mix does not name a parent class of $cls", tree.pos) + errorType(d"$mix does not name a parent class of $cls", tree.pos) case p :: q :: _ => - errorType(s"ambiguous parent class qualifier", tree.pos) + errorType("ambiguous parent class qualifier", tree.pos) } val owntype = if (!mix.isEmpty) findMixinSuper(cls.info) @@ -217,9 +217,9 @@ trait TypeAssigner { val ownType = fn.tpe.widen match { case fntpe @ MethodType(_, ptypes) => if (sameLength(ptypes, args)) fntpe.instantiate(args.tpes) - else errorType(s"wrong number of parameters for ${fn.tpe}; expected: ${ptypes.length}", tree.pos) + else errorType(i"wrong number of parameters for ${fn.tpe}; expected: ${ptypes.length}", tree.pos) case t => - errorType(s"${err.exprStr(fn)} does not take parameters", tree.pos) + errorType(i"${err.exprStr(fn)} does not take parameters", tree.pos) } tree.withType(ownType) } @@ -229,9 +229,9 @@ trait TypeAssigner { case pt: PolyType => val argTypes = args.tpes if (sameLength(argTypes, pt.paramNames)) pt.instantiate(argTypes) - else errorType(i"wrong number of type parameters for ${fn.tpe}; expected: ${pt.paramNames.length}", tree.pos) + else errorType(d"wrong number of type parameters for ${fn.tpe}; expected: ${pt.paramNames.length}", tree.pos) case _ => - errorType(s"${err.exprStr(fn)} does not take type parameters", tree.pos) + errorType(i"${err.exprStr(fn)} does not take type parameters", tree.pos) } tree.withType(ownType) } @@ -296,7 +296,7 @@ trait TypeAssigner { val tparams = tycon.tpe.typeParams val ownType = if (sameLength(tparams, args)) tycon.tpe.appliedTo(args.tpes) - else errorType(i"wrong number of type arguments for ${tycon.tpe}, should be ${tparams.length}", tree.pos) + else errorType(d"wrong number of type arguments for ${tycon.tpe}, should be ${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 c2488f68c..60acda4b7 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -121,8 +121,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) i"imported$qualifier by ${whereFound.importInfo}" - else i"defined$qualifier in ${whereFound.owner}" + if (prec == wildImport || prec == namedImport) d"imported$qualifier by ${whereFound.importInfo}" + else d"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. @@ -139,7 +139,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit else { if (!previous.isError && !found.isError) { error( - i"""reference to $name is ambiguous; + d"""reference to $name is ambiguous; |it is both ${bindingString(newPrec, ctx, "")} |and ${bindingString(prevPrec, prevCtx, " subsequently")}""".stripMargin, tree.pos) @@ -154,7 +154,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(i"reference to $name is ambiguous; it is imported twice in ${ctx.tree}", + error(d"reference to $name is ambiguous; it is imported twice in ${ctx.tree}", tree.pos) found } @@ -257,7 +257,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit if (rawType.exists) ensureAccessible(rawType, superAccess = false, tree.pos) else { - error(i"not found: $kind$name", tree.pos) + error(d"not found: $kind$name", tree.pos) ErrorType } checkValue(tree.withType(ownType.underlyingIfRepeated), pt) @@ -412,7 +412,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit ensureNoLocalRefs(block1, pt, forcedDefined = true) } else errorTree(block, - i"local definition of ${leaks.head.name} escapes as part of block's type ${block.tpe}"/*; full type: ${result.tpe.toString}"*/) + d"local definition of ${leaks.head.name} escapes as part of block's type ${block.tpe}"/*; full type: ${result.tpe.toString}"*/) } def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = track("typedIf") { @@ -490,15 +490,15 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } val ofFun = if (nme.syntheticParamNames(args.length + 1) contains param.name) - s" of expanded function ${tree.show}" + i" of expanded function $tree" else "" - errorType(s"missing parameter type for parameter ${param.name}$ofFun, expected = ${pt.show}", param.pos) + errorType(i"missing parameter type for parameter ${param.name}$ofFun, expected = $pt", param.pos) } def protoFormal(i: Int): Type = if (protoFormals.length == params.length) protoFormals(i) - else errorType(s"wrong number of parameters, expected: ${protoFormals.length}", tree.pos) + else errorType(i"wrong number of parameters, expected: ${protoFormals.length}", tree.pos) val inferredParams: List[untpd.ValDef] = for ((param, i) <- params.zipWithIndex) yield @@ -532,7 +532,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(i"result type of closure is an underspecified SAM type $pt", tree.pos) + ctx.error(d"result type of closure is an underspecified SAM type $pt", tree.pos) TypeTree(pt) case _ => if (!mt.isDependent) EmptyTree @@ -579,7 +579,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit foreachSubTreeOf(pat) { case b: Bind => if (ctx.scope.lookup(b.name) == NoSymbol) ctx.enter(b.symbol) - else ctx.error(i"duplicate pattern variable: ${b.name}", b.pos) + else ctx.error(d"duplicate pattern variable: ${b.name}", b.pos) case _ => } val guard1 = typedExpr(tree.guard, defn.BooleanType) @@ -609,7 +609,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val proto = if (owner.isConstructor) defn.UnitType else owner.info.finalResultType (from, proto) } - else (EmptyTree, errorType(i"$owner has return statement; needs result type", tree.pos)) + else (EmptyTree, errorType(d"$owner has return statement; needs result type", tree.pos)) else enclMethInfo(cx.outer) } val (from, proto) = enclMethInfo(ctx) @@ -700,7 +700,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } val res = cpy.RefinedTypeTree(tree, tpt1, refinements1) withType (tpt1.tpe /: refinements1)(addRefinement) - typr.println(s"typed refinement: ${res.tpe.show}") + typr.println(i"typed refinement: ${res.tpe}") res } @@ -722,13 +722,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val hi1 = typed(hi) // need to do in later phase, as this might cause a cyclic reference error. See pos/t0039.scala // if (!(lo1.tpe <:< hi1.tpe)) - // ctx.error(i"lower bound ${lo1.tpe} does not conform to upper bound ${hi1.tpe}", tree.pos) + // ctx.error(d"lower bound ${lo1.tpe} does not conform to upper bound ${hi1.tpe}", tree.pos) assignType(cpy.TypeBoundsTree(tree, lo1, hi1), lo1, hi1) } def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = track("typedBind") { val body1 = typed(tree.body, pt) - typr.println(s"typed bind ${tree.show} pt = ${pt.show} bodytpe = ${body1.tpe.show}") + typr.println(i"typed bind $tree pt = $pt bodytpe = ${body1.tpe}") val sym = ctx.newSymbol(ctx.owner, tree.name.asTermName, EmptyFlags, body1.tpe, coord = tree.pos) assignType(cpy.Bind(tree, tree.name, body1), sym) } @@ -837,7 +837,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(i"$pkg is not a packge", tree.pos) + ctx.error(d"$pkg is not a packge", tree.pos) ctx } val stats1 = typedStats(tree.stats, pkg.moduleClass)(packageContext) @@ -951,7 +951,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit } } - def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = /*>|>*/ ctx.traceIndented (s"typing ${tree.show}", typr, show = true) /*<|<*/ { + def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = /*>|>*/ ctx.traceIndented (i"typing $tree", typr, show = true) /*<|<*/ { if (!tree.isEmpty && ctx.typerState.isGlobalCommittable) assert(tree.pos.exists, tree) try adapt(typedUnadapted(tree, pt), pt) catch { @@ -1081,7 +1081,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case Nil => def noMatches = errorTree(tree, - i"""none of the ${err.overloadedAltsStr(altDenots)} + d"""none of the ${err.overloadedAltsStr(altDenots)} |match $expectedStr""".stripMargin) def hasEmptyParams(denot: SingleDenotation) = denot.info.paramTypess == ListOfNil pt match { @@ -1097,7 +1097,7 @@ 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, - i"""Ambiguous overload. The ${err.overloadedAltsStr(remainingDenots)} + d"""Ambiguous overload. The ${err.overloadedAltsStr(remainingDenots)} |$all match $expectedStr""".stripMargin) } } @@ -1117,7 +1117,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case Apply(_, _) => " more" case _ => "" } - (_, _) => errorTree(tree, i"$methodStr does not take$more parameters") + (_, _) => errorTree(tree, d"$methodStr does not take$more parameters") } } @@ -1130,14 +1130,14 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit EmptyTree } val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) => - def where = i"parameter $pname of $methodStr" + def where = d"parameter $pname of $methodStr" inferImplicit(formal, EmptyTree, tree.pos.endPos) match { case SearchSuccess(arg, _, _) => arg case ambi: AmbiguousImplicits => implicitArgError(s"ambiguous implicits: ${ambi.explanation} of $where") case failure: SearchFailure => - implicitArgError(i"no implicit argument of type $formal found for $where" + failure.postscript) + implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript) } } adapt(tpd.Apply(tree, args), pt) @@ -1152,13 +1152,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit adaptInterpolated(tpd.Apply(tree, Nil), pt) else errorTree(tree, - i"""missing arguments for $methodStr + d"""missing arguments for $methodStr |follow this method with `_' if you want to treat it as a partially applied function""".stripMargin) case _ => if (tree.tpe <:< pt) tree else if (ctx.mode is Mode.Pattern) tree // no subtype check for pattern else { - typr.println(s"adapt to subtype ${tree.tpe.show} !<:< ${pt.show}") + typr.println(i"adapt to subtype ${tree.tpe} !<:< $pt") //typr.println(TypeComparer.explained(implicit ctx => tree.tpe <:< pt)) adaptToSubType(wtp) } |