aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Trees.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/ast/tpd.scala5
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java57
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala91
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala43
-rw-r--r--compiler/test/dotc/tests.scala1
-rw-r--r--compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala6
11 files changed, 155 insertions, 88 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index bf11a442e..27be8c9d6 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -1077,6 +1077,13 @@ object Trees {
/** Hook to indicate that a transform of some subtree should be skipped */
protected def skipTransform(tree: Tree)(implicit ctx: Context): Boolean = false
+ /** For untyped trees, this is just the identity.
+ * For typed trees, a context derived form `ctx` that records `call` as the
+ * innermost enclosing call for which the inlined version is currently
+ * processed.
+ */
+ protected def inlineContext(call: Tree)(implicit ctx: Context): Context = ctx
+
abstract class TreeMap(val cpy: TreeCopier = inst.cpy) {
def transform(tree: Tree)(implicit ctx: Context): Tree =
@@ -1121,7 +1128,7 @@ object Trees {
case SeqLiteral(elems, elemtpt) =>
cpy.SeqLiteral(tree)(transform(elems), transform(elemtpt))
case Inlined(call, bindings, expansion) =>
- cpy.Inlined(tree)(call, transformSub(bindings), transform(expansion))
+ cpy.Inlined(tree)(call, transformSub(bindings), transform(expansion)(inlineContext(call)))
case TypeTree() =>
tree
case SingletonTypeTree(ref) =>
@@ -1225,7 +1232,7 @@ object Trees {
case SeqLiteral(elems, elemtpt) =>
this(this(x, elems), elemtpt)
case Inlined(call, bindings, expansion) =>
- this(this(x, bindings), expansion)
+ this(this(x, bindings), expansion)(inlineContext(call))
case TypeTree() =>
x
case SingletonTypeTree(ref) =>
diff --git a/compiler/src/dotty/tools/dotc/ast/tpd.scala b/compiler/src/dotty/tools/dotc/ast/tpd.scala
index ed268fda7..d1d886c55 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -933,10 +933,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
/** A key to be used in a context property that tracks enclosing inlined calls */
private val InlinedCalls = new Property.Key[List[Tree]]
- /** A context derived form `ctx` that records `call` as innermost enclosing
- * call for which the inlined version is currently processed.
- */
- def inlineContext(call: Tree)(implicit ctx: Context): Context =
+ override def inlineContext(call: Tree)(implicit ctx: Context): Context =
ctx.fresh.setProperty(InlinedCalls, call :: enclosingInlineds)
/** All enclosing calls that are currently inlined, from innermost to outermost */
diff --git a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
index 24d583b19..190445d60 100644
--- a/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala
@@ -5,7 +5,7 @@ package reporting
import core.Contexts.Context
import core.Decorators._
import printing.Highlighting.{Blue, Red}
-import diagnostic.{Message, MessageContainer, NoExplanation}
+import diagnostic.{ErrorMessageID, Message, MessageContainer, NoExplanation}
import diagnostic.messages._
import util.SourcePosition
@@ -95,9 +95,10 @@ trait MessageRendering {
if (pos.exists) Blue({
val file = pos.source.file.toString
val errId =
- if (message.errorId != NoExplanation.ID)
- s"[E${"0" * (3 - message.errorId.toString.length) + message.errorId}] "
- else ""
+ if (message.errorId ne ErrorMessageID.NoExplanationID) {
+ val errorNumber = message.errorId.errorNumber()
+ s"[E${"0" * (3 - errorNumber.toString.length) + errorNumber}] "
+ } else ""
val kind =
if (message.kind == "") diagnosticLevel
else s"${message.kind} $diagnosticLevel"
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
new file mode 100644
index 000000000..43930a56e
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
@@ -0,0 +1,57 @@
+package dotty.tools.dotc.reporting.diagnostic;
+
+/** Unique IDs identifying the messages */
+public enum ErrorMessageID {
+
+ // IMPORTANT: Add new IDs only at the end and never remove IDs
+
+ LazyErrorId, // // errorNumber: -2
+ NoExplanationID, // errorNumber: -1
+
+ EmptyCatchOrFinallyBlockID, // errorNumber: 0
+ EmptyCatchBlockID, // errorNumber: 1
+ EmptyCatchAndFinallyBlockID, // errorNumber: 2
+ DeprecatedWithOperatorID,
+ CaseClassMissingParamListID,
+ DuplicateBindID,
+ MissingIdentID,
+ TypeMismatchID,
+ NotAMemberID,
+ EarlyDefinitionsNotSupportedID,
+ TopLevelImplicitClassID,
+ ImplicitCaseClassID,
+ ObjectMayNotHaveSelfTypeID,
+ TupleTooLongID,
+ RepeatedModifierID,
+ InterpolatedStringErrorID,
+ UnboundPlaceholderParameterID,
+ IllegalStartSimpleExprID,
+ MissingReturnTypeID,
+ YieldOrDoExpectedInForComprehensionID,
+ ProperDefinitionNotFoundID,
+ ByNameParameterNotSupportedID,
+ WrongNumberOfTypeArgsID,
+ IllegalVariableInPatternAlternativeID,
+ TypeParamsTypeExpectedID,
+ IdentifierExpectedID,
+ AuxConstructorNeedsNonImplicitParameterID,
+ IncorrectRepeatedParameterSyntaxID,
+ IllegalLiteralID,
+ PatternMatchExhaustivityID,
+ MatchCaseUnreachableID,
+ SeqWildcardPatternPosID,
+ IllegalStartOfSimplePatternID,
+ PkgDuplicateSymbolID,
+ ExistentialTypesNoLongerSupportedID,
+ UnboundWildcardTypeID,
+ DanglingThisInPathID,
+ OverridesNothingID,
+ OverridesNothingButNameExistsID,
+ ForwardReferenceExtendsOverDefinitionID,
+ ExpectedTokenButFoundID;
+
+ public int errorNumber() {
+ return ordinal() - 2;
+ }
+
+}
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
index ab1222dab..09d7ae975 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala
@@ -30,11 +30,10 @@ object Message {
* Instead use the `persist` method to create an instance that does not keep a
* reference to these contexts.
*
- * @param errorId a unique number identifying the message, this will later be
+ * @param errorId a unique id identifying the message, this will later be
* used to reference documentation online
*/
-abstract class Message(val errorId: Int) { self =>
- import messages._
+abstract class Message(val errorId: ErrorMessageID) { self =>
/** The `msg` contains the diagnostic message e.g:
*
@@ -116,7 +115,7 @@ class ExtendMessage(_msg: () => Message)(f: String => String) { self =>
}
/** The fallback `Message` containing no explanation and having no `kind` */
-class NoExplanation(val msg: String) extends Message(NoExplanation.ID) {
+class NoExplanation(val msg: String) extends Message(ErrorMessageID.NoExplanationID) {
val explanation = ""
val kind = ""
@@ -127,8 +126,6 @@ class NoExplanation(val msg: String) extends Message(NoExplanation.ID) {
* lacks an explanation
*/
object NoExplanation {
- final val ID = -1
-
def unapply(m: Message): Option[Message] =
if (m.explanation == "") Some(m)
else None
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 94611e10d..3ca780419 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -17,6 +17,7 @@ import dotc.parsing.Scanners.Token
import dotc.parsing.Tokens
import printing.Highlighting._
import printing.Formatting
+import ErrorMessageID._
object messages {
@@ -94,8 +95,8 @@ object messages {
// Syntax Errors ---------------------------------------------------------- //
- abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree, errNo: Int)(implicit ctx: Context)
- extends Message(errNo) {
+ abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree, errNo: ErrorMessageID)(implicit ctx: Context)
+ extends Message(EmptyCatchOrFinallyBlockID) {
val explanation = {
val tryString = tryBody match {
case Block(Nil, untpd.EmptyTree) => "{}"
@@ -131,7 +132,7 @@ object messages {
}
case class EmptyCatchBlock(tryBody: untpd.Tree)(implicit ctx: Context)
- extends EmptyCatchOrFinallyBlock(tryBody, 1) {
+ extends EmptyCatchOrFinallyBlock(tryBody, EmptyCatchBlockID) {
val kind = "Syntax"
val msg =
hl"""|The ${"catch"} block does not contain a valid expression, try
@@ -139,7 +140,7 @@ object messages {
}
case class EmptyCatchAndFinallyBlock(tryBody: untpd.Tree)(implicit ctx: Context)
- extends EmptyCatchOrFinallyBlock(tryBody, 2) {
+ extends EmptyCatchOrFinallyBlock(tryBody, EmptyCatchAndFinallyBlockID) {
val kind = "Syntax"
val msg =
hl"""|A ${"try"} without ${"catch"} or ${"finally"} is equivalent to putting
@@ -147,7 +148,7 @@ object messages {
}
case class DeprecatedWithOperator()(implicit ctx: Context)
- extends Message(3) {
+ extends Message(DeprecatedWithOperatorID) {
val kind = "Syntax"
val msg =
hl"""${"with"} as a type operator has been deprecated; use `&' instead"""
@@ -158,7 +159,7 @@ object messages {
}
case class CaseClassMissingParamList(cdef: untpd.TypeDef)(implicit ctx: Context)
- extends Message(4) {
+ extends Message(CaseClassMissingParamListID) {
val kind = "Syntax"
val msg =
hl"""|A ${"case class"} must have at least one parameter list"""
@@ -172,7 +173,7 @@ object messages {
// Type Errors ------------------------------------------------------------ //
case class DuplicateBind(bind: untpd.Bind, tree: untpd.CaseDef)(implicit ctx: Context)
- extends Message(5) {
+ extends Message(DuplicateBindID) {
val kind = "Naming"
val msg = em"duplicate pattern variable: `${bind.name}`"
@@ -199,7 +200,7 @@ object messages {
}
case class MissingIdent(tree: untpd.Ident, treeKind: String, name: String)(implicit ctx: Context)
- extends Message(6) {
+ extends Message(MissingIdentID) {
val kind = "Unbound Identifier"
val msg = em"not found: $treeKind$name"
@@ -212,7 +213,7 @@ object messages {
}
case class TypeMismatch(found: Type, expected: Type, whyNoMatch: String = "", implicitFailure: String = "")(implicit ctx: Context)
- extends Message(7) {
+ extends Message(TypeMismatchID) {
val kind = "Type Mismatch"
val msg = {
val (where, printCtx) = Formatting.disambiguateTypes(found, expected)
@@ -227,7 +228,7 @@ object messages {
}
case class NotAMember(site: Type, name: Name, selected: String)(implicit ctx: Context)
- extends Message(8) {
+ extends Message(NotAMemberID) {
val kind = "Member Not Found"
//println(i"site = $site, decls = ${site.decls}, source = ${site.widen.typeSymbol.sourceFile}") //DEBUG
@@ -293,7 +294,7 @@ object messages {
}
case class EarlyDefinitionsNotSupported()(implicit ctx: Context)
- extends Message(9) {
+ extends Message(EarlyDefinitionsNotSupportedID) {
val kind = "Syntax"
val msg = "early definitions are not supported; use trait parameters instead"
@@ -339,7 +340,7 @@ object messages {
}
case class TopLevelImplicitClass(cdef: untpd.TypeDef)(implicit ctx: Context)
- extends Message(10) {
+ extends Message(TopLevelImplicitClassID) {
val kind = "Syntax"
val msg = hl"""An ${"implicit class"} may not be top-level"""
@@ -369,7 +370,7 @@ object messages {
}
case class ImplicitCaseClass(cdef: untpd.TypeDef)(implicit ctx: Context)
- extends Message(11) {
+ extends Message(ImplicitCaseClassID) {
val kind = "Syntax"
val msg = hl"""A ${"case class"} may not be defined as ${"implicit"}"""
@@ -382,7 +383,7 @@ object messages {
}
case class ObjectMayNotHaveSelfType(mdef: untpd.ModuleDef)(implicit ctx: Context)
- extends Message(12) {
+ extends Message(ObjectMayNotHaveSelfTypeID) {
val kind = "Syntax"
val msg = hl"""${"object"}s must not have a self ${"type"}"""
@@ -400,7 +401,7 @@ object messages {
}
case class TupleTooLong(ts: List[untpd.Tree])(implicit ctx: Context)
- extends Message(13) {
+ extends Message(TupleTooLongID) {
import Definitions.MaxTupleArity
val kind = "Syntax"
val msg = hl"""A ${"tuple"} cannot have more than ${MaxTupleArity} members"""
@@ -416,7 +417,7 @@ object messages {
}
case class RepeatedModifier(modifier: String)(implicit ctx:Context)
- extends Message(14) {
+ extends Message(RepeatedModifierID) {
val kind = "Syntax"
val msg = hl"""repeated modifier $modifier"""
@@ -438,7 +439,7 @@ object messages {
}
case class InterpolatedStringError()(implicit ctx:Context)
- extends Message(15) {
+ extends Message(InterpolatedStringErrorID) {
val kind = "Syntax"
val msg = "error in interpolated string: identifier or block expected"
val explanation = {
@@ -456,7 +457,7 @@ object messages {
}
case class UnboundPlaceholderParameter()(implicit ctx:Context)
- extends Message(16) {
+ extends Message(UnboundPlaceholderParameterID) {
val kind = "Syntax"
val msg = "unbound placeholder parameter; incorrect use of `_`"
val explanation =
@@ -489,7 +490,7 @@ object messages {
}
case class IllegalStartSimpleExpr(illegalToken: String)(implicit ctx: Context)
- extends Message(17) {
+ extends Message(IllegalStartSimpleExprID) {
val kind = "Syntax"
val msg = "illegal start of simple expression"
val explanation = {
@@ -507,7 +508,8 @@ object messages {
}
}
- case class MissingReturnType()(implicit ctx:Context) extends Message(18) {
+ case class MissingReturnType()(implicit ctx:Context)
+ extends Message(MissingReturnTypeID) {
val kind = "Syntax"
val msg = "missing return type"
val explanation =
@@ -519,7 +521,7 @@ object messages {
}
case class YieldOrDoExpectedInForComprehension()(implicit ctx: Context)
- extends Message(19) {
+ extends Message(YieldOrDoExpectedInForComprehensionID) {
val kind = "Syntax"
val msg = hl"${"yield"} or ${"do"} expected"
@@ -552,7 +554,7 @@ object messages {
}
case class ProperDefinitionNotFound()(implicit ctx: Context)
- extends Message(20) {
+ extends Message(ProperDefinitionNotFoundID) {
val kind = "Definition Not Found"
val msg = hl"""Proper definition was not found in ${"@usecase"}"""
@@ -591,7 +593,7 @@ object messages {
}
case class ByNameParameterNotSupported()(implicit ctx: Context)
- extends Message(21) {
+ extends Message(ByNameParameterNotSupportedID) {
val kind = "Syntax"
val msg = "By-name parameter type not allowed here."
@@ -615,7 +617,7 @@ object messages {
}
case class WrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
- extends Message(22) {
+ extends Message(WrongNumberOfTypeArgsID) {
val kind = "Syntax"
private val expectedCount = expectedArgs.length
@@ -661,7 +663,7 @@ object messages {
}
case class IllegalVariableInPatternAlternative()(implicit ctx: Context)
- extends Message(23) {
+ extends Message(IllegalVariableInPatternAlternativeID) {
val kind = "Syntax"
val msg = "Variables are not allowed in alternative patterns"
val explanation = {
@@ -690,7 +692,7 @@ object messages {
}
case class TypeParamsTypeExpected(mods: untpd.Modifiers, identifier: TermName)(implicit ctx: Context)
- extends Message(24) {
+ extends Message(TypeParamsTypeExpectedID) {
val kind = "Syntax"
val msg = hl"""Expected ${"type"} keyword for type parameter $identifier"""
val explanation =
@@ -703,7 +705,7 @@ object messages {
}
case class IdentifierExpected(identifier: String)(implicit ctx: Context)
- extends Message(25) {
+ extends Message(IdentifierExpectedID) {
val kind = "Syntax"
val msg = "identifier expected"
val explanation = {
@@ -724,7 +726,7 @@ object messages {
}
case class AuxConstructorNeedsNonImplicitParameter()(implicit ctx:Context)
- extends Message(26) {
+ extends Message(AuxConstructorNeedsNonImplicitParameterID) {
val kind = "Syntax"
val msg = "auxiliary constructor needs non-implicit parameter list"
val explanation =
@@ -739,7 +741,8 @@ object messages {
|"""
}
- case class IncorrectRepeatedParameterSyntax()(implicit ctx: Context) extends Message(27) {
+ case class IncorrectRepeatedParameterSyntax()(implicit ctx: Context)
+ extends Message(IncorrectRepeatedParameterSyntaxID) {
val kind = "Syntax"
val msg = "'*' expected"
val explanation =
@@ -765,7 +768,8 @@ object messages {
|""".stripMargin
}
- case class IllegalLiteral()(implicit ctx: Context) extends Message(28) {
+ case class IllegalLiteral()(implicit ctx: Context)
+ extends Message(IllegalLiteralID) {
val kind = "Syntax"
val msg = "illegal literal"
val explanation =
@@ -780,7 +784,7 @@ object messages {
}
case class PatternMatchExhaustivity(uncovered: String)(implicit ctx: Context)
- extends Message(29) {
+ extends Message(PatternMatchExhaustivityID) {
val kind = "Pattern Match Exhaustivity"
val msg =
hl"""|match may not be exhaustive.
@@ -792,14 +796,14 @@ object messages {
}
case class MatchCaseUnreachable()(implicit ctx: Context)
- extends Message(30) {
+ extends Message(MatchCaseUnreachableID) {
val kind = s"""Match ${hl"case"} Unreachable"""
val msg = "unreachable code"
val explanation = ""
}
case class SeqWildcardPatternPos()(implicit ctx: Context)
- extends Message(31) {
+ extends Message(SeqWildcardPatternPosID) {
val kind = "Syntax"
val msg = "`_*' can be used only for last argument"
val explanation = {
@@ -822,7 +826,8 @@ object messages {
}
}
- case class IllegalStartOfSimplePattern()(implicit ctx: Context) extends Message(32) {
+ case class IllegalStartOfSimplePattern()(implicit ctx: Context)
+ extends Message(IllegalStartOfSimplePatternID) {
val kind = "Syntax"
val msg = "illegal start of simple pattern"
val explanation = {
@@ -902,13 +907,14 @@ object messages {
}
case class PkgDuplicateSymbol(existing: Symbol)(implicit ctx: Context)
- extends Message(33) {
+ extends Message(PkgDuplicateSymbolID) {
val kind = "Duplicate Symbol"
val msg = hl"trying to define package with same name as `$existing`"
val explanation = ""
}
- case class ExistentialTypesNoLongerSupported()(implicit ctx: Context) extends Message(34) {
+ case class ExistentialTypesNoLongerSupported()(implicit ctx: Context)
+ extends Message(ExistentialTypesNoLongerSupportedID) {
val kind = "Syntax"
val msg =
hl"""|Existential types are no longer supported -
@@ -930,7 +936,8 @@ object messages {
|"""
}
- case class UnboundWildcardType()(implicit ctx: Context) extends Message(35) {
+ case class UnboundWildcardType()(implicit ctx: Context)
+ extends Message(UnboundWildcardTypeID) {
val kind = "Syntax"
val msg = "Unbound wildcard type"
val explanation =
@@ -974,7 +981,7 @@ object messages {
|"""
}
- case class DanglingThisInPath()(implicit ctx: Context) extends Message(36) {
+ case class DanglingThisInPath()(implicit ctx: Context) extends Message(DanglingThisInPathID) {
val kind = "Syntax"
val msg = hl"""Expected an additional member selection after the keyword ${"this"}"""
@@ -1011,7 +1018,7 @@ object messages {
}
case class OverridesNothing(member: Symbol)(implicit ctx: Context)
- extends Message(37) {
+ extends Message(OverridesNothingID) {
val kind = "Reference"
val msg = hl"""${member} overrides nothing"""
@@ -1023,7 +1030,7 @@ object messages {
}
case class OverridesNothingButNameExists(member: Symbol, existing: List[Denotations.SingleDenotation])(implicit ctx: Context)
- extends Message(38) {
+ extends Message(OverridesNothingButNameExistsID) {
val kind = "Reference"
val msg = hl"""${member} has a different signature than the overridden declaration"""
@@ -1042,7 +1049,7 @@ object messages {
}
case class ForwardReferenceExtendsOverDefinition(value: Symbol, definition: Symbol)(implicit ctx: Context)
- extends Message(39) {
+ extends Message(ForwardReferenceExtendsOverDefinitionID) {
val kind = "Reference"
val msg = hl"`${definition.name}` is a forward reference extending over the definition of `${value.name}`"
@@ -1061,7 +1068,7 @@ object messages {
}
case class ExpectedTokenButFound(expected: Token, found: Token, foundName: TermName)(implicit ctx: Context)
- extends Message(40) {
+ extends Message(ExpectedTokenButFoundID) {
val kind = "Syntax"
private val expectedText =
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 42c24ffb7..0ed6ed6b4 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -916,7 +916,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val result = assignType(cpy.UnApply(tree)(unapplyFn, unapplyImplicits, unapplyPatterns), ownType)
unapp.println(s"unapply patterns = $unapplyPatterns")
if ((ownType eq selType) || ownType.isError) result
- else Typed(result, TypeTree(ownType))
+ else tryWithClassTag(Typed(result, TypeTree(ownType)), selType)
case tp =>
val unapplyErr = if (tp.isError) unapplyFn else notAnExtractor(unapplyFn)
val typedArgsErr = args mapconserve (typed(_, defn.AnyType))
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index 27b0f28ca..fb0497c2b 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -356,8 +356,7 @@ object Checking {
*/
def checkNoPrivateLeaks(sym: Symbol, pos: Position)(implicit ctx: Context): Type = {
class NotPrivate extends TypeMap {
- type Errors = List[(String, Position)]
- var errors: Errors = Nil
+ var errors: List[String] = Nil
def accessBoundary(sym: Symbol): Symbol =
if (sym.is(Private) || !sym.owner.isClass) sym.owner
@@ -383,8 +382,8 @@ object Checking {
val prevErrors = errors
var tp1 =
if (isLeaked(tp.symbol)) {
- errors = (em"non-private $sym refers to private ${tp.symbol}\n in its type signature ${sym.info}",
- sym.pos) :: errors
+ errors =
+ em"non-private $sym refers to private ${tp.symbol}\n in its type signature ${sym.info}" :: errors
tp
}
else mapOver(tp)
@@ -408,7 +407,7 @@ object Checking {
}
val notPrivate = new NotPrivate
val info = notPrivate(sym.info)
- notPrivate.errors.foreach { case (msg, pos) => ctx.errorOrMigrationWarning(msg, pos) }
+ notPrivate.errors.foreach(ctx.errorOrMigrationWarning(_, pos))
info
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 2b57cf778..498fd001b 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -523,18 +523,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def handlePattern: Tree = {
val tpt1 = typedTpt
// special case for an abstract type that comes with a class tag
- tpt1.tpe.dealias match {
- case tref: TypeRef if !tref.symbol.isClass && !ctx.isAfterTyper =>
- inferImplicit(defn.ClassTagType.appliedTo(tref),
- EmptyTree, tpt1.pos)(ctx.retractMode(Mode.Pattern)) match {
- case SearchSuccess(arg, _, _, _) =>
- return typed(untpd.Apply(untpd.TypedSplice(arg), tree.expr), pt)
- case _ =>
- }
- case _ =>
- if (!ctx.isAfterTyper) tpt1.tpe.<:<(pt)(ctx.addMode(Mode.GADTflexible))
- }
- ascription(tpt1, isWildcard = true)
+ if (!ctx.isAfterTyper) tpt1.tpe.<:<(pt)(ctx.addMode(Mode.GADTflexible))
+ tryWithClassTag(ascription(tpt1, isWildcard = true), pt)
}
cases(
ifPat = handlePattern,
@@ -543,6 +533,23 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}
+ /** For a typed tree `e: T`, if `T` is an abstract type for which an implicit class tag `ctag`
+ * exists, rewrite to `ctag(e)`.
+ * @pre We are in pattern-matching mode (Mode.Pattern)
+ */
+ def tryWithClassTag(tree: Typed, pt: Type)(implicit ctx: Context) = tree.tpt.tpe.dealias match {
+ case tref: TypeRef if !tref.symbol.isClass && !ctx.isAfterTyper =>
+ require(ctx.mode.is(Mode.Pattern))
+ inferImplicit(defn.ClassTagType.appliedTo(tref),
+ EmptyTree, tree.tpt.pos)(ctx.retractMode(Mode.Pattern)) match {
+ case SearchSuccess(clsTag, _, _, _) =>
+ typed(untpd.Apply(untpd.TypedSplice(clsTag), untpd.TypedSplice(tree.expr)), pt)
+ case _ =>
+ tree
+ }
+ case _ => tree
+ }
+
def typedNamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context) = track("typedNamedArg") {
val arg1 = typed(tree.arg, pt)
assignType(cpy.NamedArg(tree)(tree.name, arg1), arg1)
@@ -1121,15 +1128,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Tree = track("typedBind") {
val pt1 = fullyDefinedType(pt, "pattern variable", tree.pos)
val body1 = typed(tree.body, pt1)
- typr.println(i"typed bind $tree pt = $pt1 bodytpe = ${body1.tpe}")
body1 match {
- case UnApply(fn, Nil, arg :: Nil) if tree.body.isInstanceOf[untpd.Typed] =>
- // A typed pattern `x @ (_: T)` with an implicit `ctag: ClassTag[T]`
- // was rewritten to `x @ ctag(_)`.
- // Rewrite further to `ctag(x @ _)`
- assert(fn.symbol.owner == defn.ClassTagClass)
+ case UnApply(fn, Nil, arg :: Nil) if fn.symbol.owner == defn.ClassTagClass && !body1.tpe.isError =>
+ // A typed pattern `x @ (e: T)` with an implicit `ctag: ClassTag[T]`
+ // was rewritten to `x @ ctag(e)` by `tryWithClassTag`.
+ // Rewrite further to `ctag(x @ e)`
tpd.cpy.UnApply(body1)(fn, Nil,
- typed(untpd.Bind(tree.name, arg).withPos(tree.pos), arg.tpe) :: Nil)
+ typed(untpd.Bind(tree.name, untpd.TypedSplice(arg)).withPos(tree.pos), arg.tpe) :: Nil)
case _ =>
val sym = newPatternBoundSym(tree.name, body1.tpe, tree.pos)
assignType(cpy.Bind(tree)(tree.name, body1), sym)
diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala
index fcd2d0982..7af903364 100644
--- a/compiler/test/dotc/tests.scala
+++ b/compiler/test/dotc/tests.scala
@@ -160,7 +160,6 @@ class tests extends CompilerTest {
@Test def rewrites = compileFile(posScala2Dir, "rewrites", "-rewrite" :: scala2mode)
- @Test def pos_859 = compileFile(posSpecialDir, "i859", scala2mode)(allowDeepSubtypes)
@Test def pos_t8146a = compileFile(posSpecialDir, "t8146a")(allowDeepSubtypes)
@Test def pos_t5545 = {
diff --git a/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala b/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala
index bf727d51a..858660075 100644
--- a/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala
+++ b/compiler/test/dotty/tools/dotc/reporting/TestMessageLaziness.scala
@@ -4,10 +4,8 @@ package reporting
import org.junit.Assert._
import org.junit.Test
-
import core.Contexts._
-
-import diagnostic.{ Message, MessageContainer, ExtendMessage }
+import diagnostic.{ErrorMessageID, ExtendMessage, Message, MessageContainer}
class TestMessageLaziness extends DottyTest {
ctx = ctx.fresh.setReporter(new NonchalantReporter)
@@ -19,7 +17,7 @@ class TestMessageLaziness extends DottyTest {
override def report(m: MessageContainer)(implicit ctx: Context) = ()
}
- case class LazyError() extends Message(1000) {
+ case class LazyError() extends Message(ErrorMessageID.LazyErrorId) {
throw new Error("Didn't stay lazy.")
val kind = "Test"