aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala12
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Trees.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/ast/tpd.scala7
-rw-r--r--compiler/src/dotty/tools/dotc/config/CompilerCommand.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/config/PathResolver.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/config/ScalaSettings.scala173
-rw-r--r--compiler/src/dotty/tools/dotc/config/Settings.scala20
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala92
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala52
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeErasure.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala31
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Tokens.scala4
-rw-r--r--compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala3
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/MessageRendering.scala9
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/Reporter.scala16
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java58
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/Message.scala11
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala160
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Erasure.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala25
-rw-r--r--compiler/src/dotty/tools/dotc/transform/LambdaLift.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/transform/TreeChecker.scala8
-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/Inliner.scala26
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala57
28 files changed, 448 insertions, 384 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index e3102fda2..deb239143 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -559,7 +559,7 @@ object desugar {
* ValDef or DefDef.
*/
def makePatDef(original: Tree, mods: Modifiers, pat: Tree, rhs: Tree)(implicit ctx: Context): Tree = pat match {
- case VarPattern(named, tpt) =>
+ case IdPattern(named, tpt) =>
derivedValDef(original, named, tpt, rhs, mods)
case _ =>
val rhsUnchecked = makeAnnotated("scala.unchecked", rhs)
@@ -816,7 +816,7 @@ object desugar {
* Otherwise this gives { case pat => body }
*/
def makeLambda(pat: Tree, body: Tree): Tree = pat match {
- case VarPattern(named, tpt) =>
+ case IdPattern(named, tpt) =>
Function(derivedValDef(pat, named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
case _ =>
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil, unchecked = false)
@@ -898,7 +898,9 @@ object desugar {
}
def isIrrefutableGenFrom(gen: GenFrom): Boolean =
- gen.isInstanceOf[IrrefutableGenFrom] || isIrrefutable(gen.pat, gen.expr)
+ gen.isInstanceOf[IrrefutableGenFrom] ||
+ IdPattern.unapply(gen.pat).isDefined ||
+ isIrrefutable(gen.pat, gen.expr)
/** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
* matched against `rhs`.
@@ -1062,9 +1064,9 @@ object desugar {
TypeDef(tpnme.REFINE_CLASS, impl).withFlags(Trait)
}
- /** If tree is a variable pattern, return its name and type, otherwise return None.
+ /** If tree is of the form `id` or `id: T`, return its name and type, otherwise return None.
*/
- private object VarPattern {
+ private object IdPattern {
def unapply(tree: Tree)(implicit ctx: Context): Option[VarInfo] = tree match {
case id: Ident => Some(id, TypeTree())
case Typed(id: Ident, tpt) => Some((id, tpt))
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..e5904156f 100644
--- a/compiler/src/dotty/tools/dotc/ast/tpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/tpd.scala
@@ -342,7 +342,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
private def followOuterLinks(t: Tree)(implicit ctx: Context) = t match {
case t: This if ctx.erasedTypes && !(t.symbol == ctx.owner.enclosingClass || t.symbol.isStaticOwner) =>
// after erasure outer paths should be respected
- new ExplicitOuter.OuterOps(ctx).path(t.tpe.widen.classSymbol)
+ new ExplicitOuter.OuterOps(ctx).path(toCls = t.tpe.widen.classSymbol)
case t =>
t
}
@@ -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/config/CompilerCommand.scala b/compiler/src/dotty/tools/dotc/config/CompilerCommand.scala
index 19ede3cec..c2301a3aa 100644
--- a/compiler/src/dotty/tools/dotc/config/CompilerCommand.scala
+++ b/compiler/src/dotty/tools/dotc/config/CompilerCommand.scala
@@ -93,21 +93,20 @@ object CompilerCommand extends DotClass {
def shouldStopWithInfo = {
import settings._
- Set(help, Xhelp, Yhelp, showPlugins, showPhases) exists (_.value)
+ Set(help, Xhelp, Yhelp) exists (_.value)
}
def infoMessage: String = {
import settings._
- if (help.value) usageMessage
- else if (Xhelp.value) xusageMessage
- else if (Yhelp.value) yusageMessage
-// else if (showPlugins.value) global.pluginDescriptions
-// else if (showPhases.value) global.phaseDescriptions + (
-// if (debug.value) "\n" + global.phaseFlagDescriptions else ""
-// )
- else ""
+ if (help.value) usageMessage
+ else if (Xhelp.value) xusageMessage
+ else if (Yhelp.value) yusageMessage
+ else ""
}
+ // Print all warnings encountered during arguments parsing
+ summary.warnings.foreach(ctx.warning(_))
+
if (summary.errors.nonEmpty) {
summary.errors foreach (ctx.error(_))
ctx.echo(" dotc -help gives more information")
diff --git a/compiler/src/dotty/tools/dotc/config/PathResolver.scala b/compiler/src/dotty/tools/dotc/config/PathResolver.scala
index 184b3718a..159989e6f 100644
--- a/compiler/src/dotty/tools/dotc/config/PathResolver.scala
+++ b/compiler/src/dotty/tools/dotc/config/PathResolver.scala
@@ -144,7 +144,7 @@ object PathResolver {
}
else {
implicit val ctx = (new ContextBase).initialCtx
- val ArgsSummary(sstate, rest, errors) =
+ val ArgsSummary(sstate, rest, errors, warnings) =
ctx.settings.processArguments(args.toList, true)
errors.foreach(println)
val pr = new PathResolver()(ctx.fresh.setSettings(sstate))
diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
index e4c90789c..fd79fcaa6 100644
--- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -8,152 +8,74 @@ class ScalaSettings extends Settings.SettingGroup {
protected def defaultClasspath = sys.env.getOrElse("CLASSPATH", ".")
- /** Path related settings.
- */
+ /** Path related settings */
val bootclasspath = PathSetting("-bootclasspath", "Override location of bootstrap class files.", Defaults.scalaBootClassPath)
val extdirs = PathSetting("-extdirs", "Override location of installed extensions.", Defaults.scalaExtDirs)
val javabootclasspath = PathSetting("-javabootclasspath", "Override java boot classpath.", Defaults.javaBootClassPath)
val javaextdirs = PathSetting("-javaextdirs", "Override java extdirs classpath.", Defaults.javaExtDirs)
val sourcepath = PathSetting("-sourcepath", "Specify location(s) of source files.", "") // Defaults.scalaSourcePath
- val argfiles = BooleanSetting("@<file>", "A text file containing compiler arguments (options and source files)")
val classpath = PathSetting("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp"
val d = StringSetting("-d", "directory|jar", "destination for generated classfiles.", ".")
val priorityclasspath = PathSetting("-priorityclasspath", "class path that takes precedence over all other paths (or testing only)", "")
- /** Other settings.
- */
- val dependencyfile = StringSetting("-dependencyfile", "file", "Set dependency tracking file.", ".scala_dependencies")
+ /** Other settings */
val deprecation = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.")
val migration = BooleanSetting("-migration", "Emit warning and location for migration issues from Scala 2.")
val encoding = StringSetting("-encoding", "encoding", "Specify character encoding used by source files.", Properties.sourceEncoding)
val explaintypes = BooleanSetting("-explaintypes", "Explain type errors in more detail.")
val explain = BooleanSetting("-explain", "Explain errors in more detail.")
val feature = BooleanSetting("-feature", "Emit warning and location for usages of features that should be imported explicitly.")
- val g = ChoiceSetting("-g", "level", "Set level of generated debugging info.", List("none", "source", "line", "vars", "notailcalls"), "vars")
val help = BooleanSetting("-help", "Print a synopsis of standard options")
- val nowarn = BooleanSetting("-nowarn", "Generate no warnings.")
val color = ChoiceSetting("-color", "mode", "Colored output", List("always", "never"/*, "auto"*/), "always"/* "auto"*/)
val target = ChoiceSetting("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
- List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "jvm-1.8", "msil"),
- "jvm-1.8")
- val scalajs = BooleanSetting("-scalajs", "Compile in Scala.js mode (requires scalajs-library.jar on the classpath).")
+ List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "jvm-1.8", "msil"), "jvm-1.8")
val unchecked = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.")
val uniqid = BooleanSetting("-uniqid", "Uniquely tag all identifiers in debugging output.")
val usejavacp = BooleanSetting("-usejavacp", "Utilize the java.class.path in classpath resolution.")
val verbose = BooleanSetting("-verbose", "Output messages about what the compiler is doing.")
val version = BooleanSetting("-version", "Print product version and exit.")
val pageWidth = IntSetting("-pagewidth", "Set page width", 80)
-
- val jvmargs = PrefixSetting("-J<flag>", "-J", "Pass <flag> directly to the runtime system.")
- val defines = PrefixSetting("-Dproperty=value", "-D", "Pass -Dproperty=value directly to the runtime system.")
- val toolcp = PathSetting("-toolcp", "Add to the runner classpath.", "")
- val nobootcp = BooleanSetting("-nobootcp", "Do not use the boot classpath for the scala jars.")
val strict = BooleanSetting("-strict", "Use strict type rules, which means some formerly legal code does not typecheck anymore.")
-
- val nospecialization = BooleanSetting("-no-specialization", "Ignore @specialize annotations.")
val language = MultiStringSetting("-language", "feature", "Enable one or more language features.")
val rewrite = OptionSetting[Rewrites]("-rewrite", "When used in conjunction with -language:Scala2 rewrites sources to migrate to new syntax")
/** -X "Advanced" settings
*/
val Xhelp = BooleanSetting("-X", "Print a synopsis of advanced options.")
- val assemname = StringSetting("-Xassem-name", "file", "(Requires -target:msil) Name of the output assembly.", "").dependsOn(target, "msil")
- val assemrefs = StringSetting("-Xassem-path", "path", "(Requires -target:msil) List of assemblies referenced by the program.", ".").dependsOn(target, "msil")
- val assemextdirs = StringSetting("-Xassem-extdirs", "dirs", "(Requires -target:msil) List of directories containing assemblies. default:lib", Defaults.scalaLibDir.path).dependsOn(target, "msil")
- val sourcedir = StringSetting("-Xsourcedir", "directory", "(Requires -target:msil) Mirror source folder structure in output directory.", ".").dependsOn(target, "msil")
- val checkInit = BooleanSetting("-Xcheckinit", "Wrap field accessors to throw an exception on uninitialized access.")
- val noassertions = BooleanSetting("-Xdisable-assertions", "Generate no assertions or assumptions.")
-// val elidebelow = IntSetting("-Xelide-below", "Calls to @elidable methods are omitted if method priority is lower than argument",
-// elidable.MINIMUM, None, elidable.byName get _)
val noForwarders = BooleanSetting("-Xno-forwarders", "Do not generate static forwarders in mirror classes.")
- val genPhaseGraph = StringSetting("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "")
- val XlogImplicits = BooleanSetting("-Xlog-implicits", "Show more detail on why some implicits are not applicable.")
val XminImplicitSearchDepth = IntSetting("-Xmin-implicit-search-depth", "Set number of levels of implicit searches undertaken before checking for divergence.", 5)
val xmaxInlines = IntSetting("-Xmax-inlines", "Maximal number of successive inlines", 32)
- val logImplicitConv = BooleanSetting("-Xlog-implicit-conversions", "Print a message whenever an implicit conversion is inserted.")
- val logReflectiveCalls = BooleanSetting("-Xlog-reflective-calls", "Print a message when a reflective method call is generated")
- val logFreeTerms = BooleanSetting("-Xlog-free-terms", "Print a message when reification creates a free term.")
- val logFreeTypes = BooleanSetting("-Xlog-free-types", "Print a message when reification resorts to generating a free type.")
val maxClassfileName = IntSetting("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, 72 to 255)
val Xmigration = VersionSetting("-Xmigration", "Warn about constructs whose behavior may have changed since version.")
- val Xsource = VersionSetting("-Xsource", "Treat compiler input as Scala source for the specified version.")
- val Xverify = BooleanSetting("-Xverify", "Verify generic signatures in generated bytecode (asm backend only.)")
- val plugin = MultiStringSetting("-Xplugin", "file", "Load one or more plugins from files.")
- val disable = MultiStringSetting("-Xplugin-disable", "plugin", "Disable the given plugin(s).")
- val showPlugins = BooleanSetting("-Xplugin-list", "Print a synopsis of loaded plugins.")
- val require = MultiStringSetting("-Xplugin-require", "plugin", "Abort unless the given plugin(s) are available.")
- val pluginsDir = StringSetting("-Xpluginsdir", "path", "Path to search compiler plugins.", Defaults.scalaPluginPath)
val Xprint = PhasesSetting("-Xprint", "Print out program after")
- val writeICode = PhasesSetting("-Xprint-icode", "Log internal icode to *.icode files after", "icode")
- val Xprintpos = BooleanSetting("-Xprint-pos", "Print tree positions, as offsets.")
val printtypes = BooleanSetting("-Xprint-types", "Print tree types (debugging option).")
val XprintDiff = BooleanSetting("-Xprint-diff", "Print changed parts of the tree since last print.")
val XprintDiffDel = BooleanSetting("-Xprint-diff-del", "Print chaged parts of the tree since last print including deleted parts.")
val prompt = BooleanSetting("-Xprompt", "Display a prompt after each error (debugging option).")
- val script = StringSetting("-Xscript", "object", "Treat the source file as a script and wrap it in a main method.", "")
val mainClass = StringSetting("-Xmain-class", "path", "Class for manifest's Main-Class entry (only useful with -d <jar>)", "")
- val Xshowcls = StringSetting("-Xshow-class", "class", "Show internal representation of class.", "")
- val Xshowobj = StringSetting("-Xshow-object", "object", "Show internal representation of object.", "")
- val showPhases = BooleanSetting("-Xshow-phases", "Print a synopsis of compiler phases.")
- val sourceReader = StringSetting("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "")
val XnoValueClasses = BooleanSetting("-Xno-value-classes", "Do not use value classes. Helps debugging.")
val XreplLineWidth = IntSetting("-Xrepl-line-width", "Maximial number of columns per line for REPL output", 390)
- val XoldPatmat = BooleanSetting("-Xoldpatmat", "Use the pre-2.10 pattern matcher. Otherwise, the 'virtualizing' pattern matcher is used in 2.10.")
- val XnoPatmatAnalysis = BooleanSetting("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.")
- val XfullLubs = BooleanSetting("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.")
- val wikiSyntax = BooleanSetting("-Xwiki-syntax", "Retains the Scala2 behavior of using Wiki Syntax in Scaladoc")
- /** -Y "Private" settings
- */
- val overrideObjects = BooleanSetting("-Yoverride-objects", "Allow member objects to be overridden.")
+ /** -Y "Private" settings */
val overrideVars = BooleanSetting("-Yoverride-vars", "Allow vars to be overridden.")
val Yhelp = BooleanSetting("-Y", "Print a synopsis of private options.")
- val browse = PhasesSetting("-Ybrowse", "Browse the abstract syntax tree after")
val Ycheck = PhasesSetting("-Ycheck", "Check the tree at the end of")
val YcheckMods = BooleanSetting("-Ycheck-mods", "Check that symbols and their defining trees have modifiers in sync")
- val YcheckTypedTrees = BooleanSetting("-YcheckTypedTrees", "Check all constructured typed trees for type correctness")
- val Yshow = PhasesSetting("-Yshow", "(Requires -Xshow-class or -Xshow-object) Show after")
- val Ycloselim = BooleanSetting("-Yclosure-elim", "Perform closure elimination.")
- val Ycompacttrees = BooleanSetting("-Ycompact-trees", "Use compact tree printer when displaying trees.")
- val noCompletion = BooleanSetting("-Yno-completion", "Disable tab-completion in the REPL.")
- val Ydce = BooleanSetting("-Ydead-code", "Perform dead code elimination.")
val debug = BooleanSetting("-Ydebug", "Increase the quantity of debugging output.")
val debugNames = BooleanSetting("-YdebugNames", "Show name-space indicators when printing names")
val debugTrace = BooleanSetting("-Ydebug-trace", "Trace core operations")
val debugFlags = BooleanSetting("-Ydebug-flags", "Print all flags of definitions")
val debugOwners = BooleanSetting("-Ydebug-owners", "Print all owners of definitions (requires -Yprint-syms)")
- //val doc = BooleanSetting ("-Ydoc", "Generate documentation")
val termConflict = ChoiceSetting("-Yresolve-term-conflict", "strategy", "Resolve term conflicts", List("package", "object", "error"), "error")
- val inlineHandlers = BooleanSetting("-Yinline-handlers", "Perform exception handler inlining when possible.")
- val YinlinerWarnings = BooleanSetting("-Yinline-warnings", "Emit inlining warnings. (Normally surpressed due to high volume)")
- val Ylinearizer = ChoiceSetting("-Ylinearizer", "which", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo")
val log = PhasesSetting("-Ylog", "Log operations during")
val Ylogcp = BooleanSetting("-Ylog-classpath", "Output information about what classpath is being applied.")
- val Ynogenericsig = BooleanSetting("-Yno-generic-signatures", "Suppress generation of generic signatures for Java.")
val YnoImports = BooleanSetting("-Yno-imports", "Compile without importing scala.*, java.lang.*, or Predef.")
val YnoPredef = BooleanSetting("-Yno-predef", "Compile without importing Predef.")
- val noAdaptedArgs = BooleanSetting("-Yno-adapted-args", "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver.")
- val selfInAnnots = BooleanSetting("-Yself-in-annots", "Include a \"self\" identifier inside of annotations.")
- val Yshowtrees = BooleanSetting("-Yshow-trees", "(Requires -Xprint:) Print detailed ASTs in formatted form.")
- val YshowtreesCompact = BooleanSetting("-Yshow-trees-compact", "(Requires -Xprint:) Print detailed ASTs in compact form.")
- val YshowtreesStringified = BooleanSetting("-Yshow-trees-stringified", "(Requires -Xprint:) Print stringifications along with detailed ASTs.")
- val Yshowsyms = BooleanSetting("-Yshow-syms", "Print the AST symbol hierarchy after each phase.")
- val Yshowsymkinds = BooleanSetting("-Yshow-symkinds", "Print abbreviated symbol kinds next to symbol names.")
val Yskip = PhasesSetting("-Yskip", "Skip")
- val Ygenjavap = StringSetting("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
val Ydumpclasses = StringSetting("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "")
- val Ynosqueeze = BooleanSetting("-Yno-squeeze", "Disable creation of compact code in matching.")
val YstopAfter = PhasesSetting("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
val YstopBefore = PhasesSetting("-Ystop-before", "Stop before") // stop before erasure as long as we have not debugged it fully
- val refinementMethodDispatch = ChoiceSetting("-Ystruct-dispatch", "policy", "structural method dispatch policy", List("no-cache", "mono-cache", "poly-cache", "invoke-dynamic"), "poly-cache")
- val Yrangepos = BooleanSetting("-Yrangepos", "Use range positions for syntax trees.")
- val Ybuilderdebug = ChoiceSetting("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none")
- val Yreifycopypaste = BooleanSetting("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.")
- val Yreplsync = BooleanSetting("-Yrepl-sync", "Do not use asynchronous code for repl startup")
val YmethodInfer = BooleanSetting("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
- val etaExpandKeepsStar = BooleanSetting("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.")
- val Yinvalidate = StringSetting("-Yinvalidate", "classpath-entry", "Invalidate classpath entry before run", "")
- val noSelfCheck = BooleanSetting("-Yno-self-type-checks", "Suppress check for self-type conformance among inherited members.")
val YtraceContextCreation = BooleanSetting("-Ytrace-context-creation", "Store stack trace of context creations.")
val YshowSuppressedErrors = BooleanSetting("-Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally supressed.")
val Yheartbeat = BooleanSetting("-Yheartbeat", "show heartbeat stack trace of compiler operations.")
@@ -167,52 +89,17 @@ class ScalaSettings extends Settings.SettingGroup {
val YforceSbtPhases = BooleanSetting("-Yforce-sbt-phases", "Run the phases used by sbt for incremental compilation (ExtractDependencies and ExtractAPI) even if the compiler is ran outside of sbt, for debugging.")
val YdumpSbtInc = BooleanSetting("-Ydump-sbt-inc", "For every compiled foo.scala, output the API representation and dependencies used for sbt incremental compilation in foo.inc, implies -Yforce-sbt-phases.")
val YcheckAllPatmat = BooleanSetting("-Ycheck-all-patmat", "Check exhaustivity and redundancy of all pattern matching (used for testing the algorithm)")
- def stop = YstopAfter
- /** Area-specific debug output.
- */
- val Ybuildmanagerdebug = BooleanSetting("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
- val Ycompletion = BooleanSetting("-Ycompletion-debug", "Trace all tab completion activity.")
- val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.")
- val Yidedebug = BooleanSetting("-Yide-debug", "Generate, validate and output trees using the interactive compiler.")
- val Yinferdebug = BooleanSetting("-Yinfer-debug", "Trace type inference and implicit search.")
- val Yissuedebug = BooleanSetting("-Yissue-debug", "Print stack traces when a context issues an error.")
- val YmacrodebugLite = BooleanSetting("-Ymacro-debug-lite", "Trace essential macro-related activities.")
- val YmacrodebugVerbose = BooleanSetting("-Ymacro-debug-verbose", "Trace all macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions.")
- val Ypmatdebug = BooleanSetting("-Ypmat-debug", "Trace all pattern matcher activity.")
- val Yposdebug = BooleanSetting("-Ypos-debug", "Trace position validation.")
- val Yreifydebug = BooleanSetting("-Yreify-debug", "Trace reification.")
- val Yrepldebug = BooleanSetting("-Yrepl-debug", "Trace all repl activity.")
- val Ytyperdebug = BooleanSetting("-Ytyper-debug", "Trace all type assignments.")
- val Ypatmatdebug = BooleanSetting("-Ypatmat-debug", "Trace pattern matching translation.")
+ /** Area-specific debug output */
val Yexplainlowlevel = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")
val YnoDoubleBindings = BooleanSetting("-Yno-double-bindings", "Assert no namedtype is bound twice (should be enabled only if program is error-free).")
val YshowVarBounds = BooleanSetting("-Yshow-var-bounds", "Print type variables with their bounds")
val YnoInline = BooleanSetting("-Yno-inline", "Suppress inlining.")
+ /** Linker specific flags */
val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize"
- /** IDE-specific settings
- */
- val YpresentationVerbose = BooleanSetting("-Ypresentation-verbose", "Print information about presentation compiler tasks.")
- val YpresentationDebug = BooleanSetting("-Ypresentation-debug", "Enable debugging output for the presentation compiler.")
- val YpresentationStrict = BooleanSetting("-Ypresentation-strict", "Do not report type errors in sources with syntax errors.")
-
- val YpresentationLog = StringSetting("-Ypresentation-log", "file", "Log presentation compiler events into file", "")
- val YpresentationReplay = StringSetting("-Ypresentation-replay", "file", "Replay presentation compiler events from file", "")
- val YpresentationDelay = IntSetting("-Ypresentation-delay", "Wait number of ms after typing before starting typechecking", 0, 0 to 999)
-
- /** Doc specific settings */
- val template = OptionSetting[String](
- "-template",
- "A mustache template for rendering each top-level entity in the API"
- )
-
- val resources = OptionSetting[String](
- "-resources",
- "A directory containing static resources needed for the API documentation"
- )
-
+ /** Dottydoc specific settings */
val siteRoot = StringSetting(
"-siteroot",
"site root",
@@ -227,49 +114,5 @@ class ScalaSettings extends Settings.SettingGroup {
sys.props("user.dir").split(sys.props("file.separator")).last
)
- val DocVersion = StringSetting (
- "-Ydoc-version",
- "version",
- "An optional version number, to be appended to the title",
- ""
- )
-
- val DocOutput = StringSetting (
- "-Ydoc-output",
- "outdir",
- "The output directory in which to place the documentation",
- "."
- )
-
- val DocFooter = StringSetting (
- "-Ydoc-footer",
- "footer",
- "A footer on every Scaladoc page, by default the EPFL/Lightbend copyright notice. Can be overridden with a custom footer.",
- ""
- )
-
- val DocUncompilable = StringSetting (
- "-Ydoc-no-compile",
- "path",
- "A directory containing sources which should be parsed, no more (e.g. AnyRef.scala)",
- ""
- )
-
- //def DocUncompilableFiles(implicit ctx: Context) = DocUncompilable.value match {
- // case "" => Nil
- // case path => io.Directory(path).deepFiles.filter(_ hasExtension "scala").toList
- //}
-
- val DocExternalDoc = MultiStringSetting (
- "-Ydoc-external-doc",
- "external-doc",
- "comma-separated list of classpath_entry_path#doc_URL pairs describing external dependencies."
- )
-
- val DocAuthor = BooleanSetting("-Ydoc-author", "Include authors.", true)
-
- val DocGroups = BooleanSetting (
- "-Ydoc:groups",
- "Group similar functions together (based on the @group annotation)"
- )
+ val wikiSyntax = BooleanSetting("-Xwiki-syntax", "Retains the Scala2 behavior of using Wiki Syntax in Scaladoc")
}
diff --git a/compiler/src/dotty/tools/dotc/config/Settings.scala b/compiler/src/dotty/tools/dotc/config/Settings.scala
index cffa047fe..58fa6d366 100644
--- a/compiler/src/dotty/tools/dotc/config/Settings.scala
+++ b/compiler/src/dotty/tools/dotc/config/Settings.scala
@@ -44,10 +44,14 @@ object Settings {
case class ArgsSummary(
sstate: SettingsState,
arguments: List[String],
- errors: List[String]) {
+ errors: List[String],
+ warnings: List[String]) {
def fail(msg: String) =
- ArgsSummary(sstate, arguments, errors :+ msg)
+ ArgsSummary(sstate, arguments.tail, errors :+ msg, warnings)
+
+ def warn(msg: String) =
+ ArgsSummary(sstate, arguments.tail, errors, warnings :+ msg)
}
case class Setting[T: ClassTag] private[Settings] (
@@ -106,11 +110,11 @@ object Settings {
}
def tryToSet(state: ArgsSummary): ArgsSummary = {
- val ArgsSummary(sstate, arg :: args, errors) = state
+ val ArgsSummary(sstate, arg :: args, errors, warnings) = state
def update(value: Any, args: List[String]) =
- ArgsSummary(updateIn(sstate, value), args, errors)
+ ArgsSummary(updateIn(sstate, value), args, errors, warnings)
def fail(msg: String, args: List[String]) =
- ArgsSummary(sstate, args, errors :+ msg)
+ ArgsSummary(sstate, args, errors :+ msg, warnings)
def missingArg =
fail(s"missing argument for option $name", args)
def doSet(argRest: String) = ((implicitly[ClassTag[T]], args): @unchecked) match {
@@ -206,7 +210,7 @@ object Settings {
* to get their arguments.
*/
protected def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
- def stateWithArgs(args: List[String]) = ArgsSummary(state.sstate, args, state.errors)
+ def stateWithArgs(args: List[String]) = ArgsSummary(state.sstate, args, state.errors, state.warnings)
state.arguments match {
case Nil =>
checkDependencies(stateWithArgs(skipped))
@@ -219,7 +223,7 @@ object Settings {
if (state1 ne state) processArguments(state1, processAll, skipped)
else loop(settings1)
case Nil =>
- state.fail(s"bad option: '$x'")
+ processArguments(state.warn(s"bad option '$x' was ignored"), processAll, skipped)
}
loop(allSettings.toList)
case arg :: args =>
@@ -229,7 +233,7 @@ object Settings {
}
def processArguments(arguments: List[String], processAll: Boolean)(implicit ctx: Context): ArgsSummary =
- processArguments(ArgsSummary(ctx.sstate, arguments, Nil), processAll, Nil)
+ processArguments(ArgsSummary(ctx.sstate, arguments, Nil, Nil), processAll, Nil)
def publish[T](settingf: Int => Setting[T]): Setting[T] = {
val setting = settingf(_allSettings.length)
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index c61e92f3a..847177e2f 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -528,6 +528,8 @@ class Definitions {
lazy val EqType = ctx.requiredClassRef("scala.Eq")
def EqClass(implicit ctx: Context) = EqType.symbol.asClass
+ lazy val XMLTopScopeModuleRef = ctx.requiredModuleRef("scala.xml.TopScope")
+
// Annotation base classes
lazy val AnnotationType = ctx.requiredClassRef("scala.annotation.Annotation")
def AnnotationClass(implicit ctx: Context) = AnnotationType.symbol.asClass
@@ -636,13 +638,9 @@ class Definitions {
FunctionType(args.length, isImplicit).appliedTo(args ::: resultType :: Nil)
def unapply(ft: Type)(implicit ctx: Context) = {
val tsym = ft.typeSymbol
- val isImplicitFun = isImplicitFunctionClass(tsym)
- if (isImplicitFun || isFunctionClass(tsym)) {
- val targs = ft.argInfos
- val numArgs = targs.length - 1
- if (numArgs >= 0 && FunctionType(numArgs, isImplicitFun).symbol == tsym)
- Some(targs.init, targs.last, isImplicitFun)
- else None
+ if (isFunctionClass(tsym)) {
+ val targs = ft.dealias.argInfos
+ Some(targs.init, targs.last, tsym.name.isImplicitFunction)
}
else None
}
@@ -695,20 +693,17 @@ class Definitions {
lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2)
lazy val ProductNType = mkArityArray("scala.Product", MaxTupleArity, 0)
- def FunctionClass(n: Int)(implicit ctx: Context) =
- if (n < MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n)
+ def FunctionClass(n: Int, isImplicit: Boolean = false)(implicit ctx: Context) =
+ if (isImplicit) ctx.requiredClass("scala.ImplicitFunction" + n.toString)
+ else if (n <= MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n)
else ctx.requiredClass("scala.Function" + n.toString)
lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply)
def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol
- def ImplicitFunctionClass(n: Int)(implicit ctx: Context) =
- ctx.requiredClass("scala.ImplicitFunction" + n.toString)
-
def FunctionType(n: Int, isImplicit: Boolean = false)(implicit ctx: Context): TypeRef =
- if (isImplicit && !ctx.erasedTypes) ImplicitFunctionClass(n).typeRef
- else if (n < MaxImplementedFunctionArity) ImplementedFunctionType(n)
- else FunctionClass(n).typeRef
+ if (n <= MaxImplementedFunctionArity && (!isImplicit || ctx.erasedTypes)) ImplementedFunctionType(n)
+ else FunctionClass(n, isImplicit).typeRef
private lazy val TupleTypes: Set[TypeRef] = TupleType.toSet
private lazy val ProductTypes: Set[TypeRef] = ProductNType.toSet
@@ -732,14 +727,61 @@ class Definitions {
def isBottomType(tp: Type) =
tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
- def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
- def isImplicitFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.ImplicitFunction)
- /** Is a class that will be erased to FunctionXXL */
- def isXXLFunctionClass(cls: Symbol) = cls.name.functionArity > MaxImplementedFunctionArity
+ /** Is a function class.
+ * - FunctionN for N >= 0
+ * - ImplicitFunctionN for N >= 0
+ */
+ def isFunctionClass(cls: Symbol) = scalaClassName(cls).isFunction
+
+ /** Is an implicit function class.
+ * - ImplicitFunctionN for N >= 0
+ */
+ def isImplicitFunctionClass(cls: Symbol) = scalaClassName(cls).isImplicitFunction
+
+ /** Is a class that will be erased to FunctionXXL
+ * - FunctionN for N >= 22
+ * - ImplicitFunctionN for N >= 22
+ */
+ def isXXLFunctionClass(cls: Symbol) = scalaClassName(cls).functionArity > MaxImplementedFunctionArity
+
+ /** Is a synthetic function class
+ * - FunctionN for N > 22
+ * - ImplicitFunctionN for N >= 0
+ */
+ def isSyntheticFunctionClass(cls: Symbol) = scalaClassName(cls).isSyntheticFunction
+
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple)
def isProductClass(cls: Symbol) = isVarArityClass(cls, tpnme.Product)
+ /** Returns the erased class of the function class `cls`
+ * - FunctionN for N > 22 becomes FunctionXXL
+ * - FunctionN for 22 > N >= 0 remains as FunctionN
+ * - ImplicitFunctionN for N > 22 becomes FunctionXXL
+ * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
+ * - anything else becomes a NoSymbol
+ */
+ def erasedFunctionClass(cls: Symbol): Symbol = {
+ val arity = scalaClassName(cls).functionArity
+ if (arity > 22) defn.FunctionXXLClass
+ else if (arity >= 0) defn.FunctionClass(arity)
+ else NoSymbol
+ }
+
+ /** Returns the erased type of the function class `cls`
+ * - FunctionN for N > 22 becomes FunctionXXL
+ * - FunctionN for 22 > N >= 0 remains as FunctionN
+ * - ImplicitFunctionN for N > 22 becomes FunctionXXL
+ * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
+ * - anything else becomes a NoType
+ */
+ def erasedFunctionType(cls: Symbol): Type = {
+ val arity = scalaClassName(cls).functionArity
+ if (arity > 22) defn.FunctionXXLType
+ else if (arity >= 0) defn.FunctionType(arity)
+ else NoType
+ }
+
val predefClassNames: Set[Name] =
Set("Predef$", "DeprecatedPredef", "LowPriorityImplicits").map(_.toTypeName)
@@ -810,16 +852,13 @@ class Definitions {
def isFunctionType(tp: Type)(implicit ctx: Context) = {
val arity = functionArity(tp)
val sym = tp.dealias.typeSymbol
- arity >= 0 && (
- isFunctionClass(sym) && tp.isRef(FunctionType(arity, isImplicit = false).typeSymbol) ||
- isImplicitFunctionClass(sym) && tp.isRef(FunctionType(arity, isImplicit = true).typeSymbol)
- )
+ arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType(arity, sym.name.isImplicitFunction).typeSymbol)
}
def functionArity(tp: Type)(implicit ctx: Context) = tp.dealias.argInfos.length - 1
def isImplicitFunctionType(tp: Type)(implicit ctx: Context) =
- isFunctionType(tp) && tp.dealias.typeSymbol.name.startsWith(tpnme.ImplicitFunction)
+ isFunctionType(tp) && tp.dealias.typeSymbol.name.isImplicitFunction
// ----- primitive value class machinery ------------------------------------------
@@ -893,9 +932,6 @@ class Definitions {
// ----- Initialization ---------------------------------------------------
- private def maxImplemented(name: Name) =
- if (name `startsWith` tpnme.Function) MaxImplementedFunctionArity else 0
-
/** Give the scala package a scope where a FunctionN trait is automatically
* added when someone looks for it.
*/
@@ -905,7 +941,7 @@ class Definitions {
val newDecls = new MutableScope(oldDecls) {
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
val res = super.lookupEntry(name)
- if (res == null && name.isTypeName && name.functionArity > maxImplemented(name))
+ if (res == null && name.isTypeName && name.isSyntheticFunction)
newScopeEntry(newFunctionNTrait(name.asTypeName))
else res
}
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index c037d1ce7..aac313892 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -8,6 +8,7 @@ import Names._, StdNames._, Contexts._, Symbols._, Flags._
import Decorators.StringDecorator
import util.{Chars, NameTransformer}
import Chars.isOperatorPart
+import Definitions._
object NameOps {
@@ -231,13 +232,50 @@ object NameOps {
}
}
- def functionArity: Int = {
- def test(prefix: Name): Int =
- if (name.startsWith(prefix))
- try name.drop(prefix.length).toString.toInt
- catch { case ex: NumberFormatException => -1 }
- else -1
- test(tpnme.Function) max test(tpnme.ImplicitFunction)
+ /** Is a synthetic function name
+ * - N for FunctionN
+ * - N for ImplicitFunctionN
+ * - (-1) otherwise
+ */
+ def functionArity: Int =
+ functionArityFor(tpnme.Function) max functionArityFor(tpnme.ImplicitFunction)
+
+ /** Is a function name
+ * - FunctionN for N >= 0
+ * - ImplicitFunctionN for N >= 0
+ * - false otherwise
+ */
+ def isFunction: Boolean = functionArity >= 0
+
+ /** Is a implicit function name
+ * - ImplicitFunctionN for N >= 0
+ * - false otherwise
+ */
+ def isImplicitFunction: Boolean = functionArityFor(tpnme.ImplicitFunction) >= 0
+
+ /** Is a synthetic function name
+ * - FunctionN for N > 22
+ * - ImplicitFunctionN for N >= 0
+ * - false otherwise
+ */
+ def isSyntheticFunction: Boolean = {
+ functionArityFor(tpnme.Function) > MaxImplementedFunctionArity ||
+ functionArityFor(tpnme.ImplicitFunction) >= 0
+ }
+
+ /** Parsed function arity for function with some specific prefix */
+ private def functionArityFor(prefix: Name): Int = {
+ if (name.startsWith(prefix))
+ try name.toString.substring(prefix.length).toInt
+ catch { case _: NumberFormatException => -1 }
+ else -1
+ }
+
+
+ /** The number of hops specified in an outer-select name */
+ def outerSelectHops: Int = {
+ require(isOuterSelect)
+ name.dropRight(nme.OUTER_SELECT.length).toString.toInt
}
/** The name of the generic runtime operation corresponding to an array operation */
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index 4a9c50dad..c424c6182 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -533,6 +533,7 @@ object StdNames {
val nullRuntimeClass: N = "scala.runtime.Null$"
val synthSwitch: N = "$synthSwitch"
+ val _scope: N = "$scope"
// unencoded operators
object raw {
diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
index 2a341390b..ff99008bb 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -44,7 +44,7 @@ object TypeErasure {
val sym = tp.symbol
sym.isClass &&
sym != defn.AnyClass && sym != defn.ArrayClass &&
- !defn.isXXLFunctionClass(sym) && !defn.isImplicitFunctionClass(sym)
+ !defn.isSyntheticFunctionClass(sym)
case _: TermRef =>
true
case JavaArrayType(elem) =>
@@ -358,8 +358,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
if (!sym.isClass) this(tp.info)
else if (semiEraseVCs && isDerivedValueClass(sym)) eraseDerivedValueClassRef(tp)
else if (sym == defn.ArrayClass) apply(tp.appliedTo(TypeBounds.empty)) // i966 shows that we can hit a raw Array type.
- else if (defn.isXXLFunctionClass(sym)) defn.FunctionXXLType
- else if (defn.isImplicitFunctionClass(sym)) apply(defn.FunctionType(sym.name.functionArity))
+ else if (defn.isSyntheticFunctionClass(sym)) defn.erasedFunctionType(sym)
else eraseNormalClassRef(tp)
case tp: RefinedType =>
val parent = tp.parent
@@ -370,7 +369,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
case SuperType(thistpe, supertpe) =>
SuperType(this(thistpe), this(supertpe))
case ExprType(rt) =>
- defn.FunctionClass(0).typeRef
+ defn.FunctionType(0)
case AndType(tp1, tp2) =>
erasedGlb(this(tp1), this(tp2), isJava)
case OrType(tp1, tp2) =>
@@ -496,8 +495,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
val erasedVCRef = eraseDerivedValueClassRef(tp)
if (erasedVCRef.exists) return sigName(erasedVCRef)
}
- if (defn.isImplicitFunctionClass(sym))
- sigName(defn.FunctionType(sym.name.functionArity))
+ if (defn.isSyntheticFunctionClass(sym))
+ sigName(defn.erasedFunctionType(sym))
else
normalizeClass(sym.asClass).fullName.asTypeName
case defn.ArrayOf(elem) =>
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index 9f4cdbd35..b46bc401d 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -110,7 +110,8 @@ object Parsers {
*/
def syntaxError(msg: => Message, offset: Int = in.offset): Unit =
if (offset > lastErrorOffset) {
- syntaxError(msg, Position(offset))
+ val length = if (in.name != null) in.name.show.length else 0
+ syntaxError(msg, Position(offset, offset + length))
lastErrorOffset = in.offset
}
@@ -249,11 +250,6 @@ object Parsers {
lastErrorOffset = in.offset
} // DEBUG
- private def expectedMsg(token: Int): String =
- expectedMessage(showToken(token))
- private def expectedMessage(what: String): String =
- s"$what expected but ${showToken(in.token)} found"
-
/** Consume one token of the specified type, or
* signal an error if it is not there.
*
@@ -262,7 +258,7 @@ object Parsers {
def accept(token: Int): Int = {
val offset = in.offset
if (in.token != token) {
- syntaxErrorOrIncomplete(expectedMsg(token))
+ syntaxErrorOrIncomplete(ExpectedTokenButFound(token, in.token, in.name))
}
if (in.token == token) in.nextToken()
offset
@@ -408,14 +404,13 @@ object Parsers {
var opStack: List[OpInfo] = Nil
- def checkAssoc(offset: Int, op: Name, leftAssoc: Boolean) =
- if (isLeftAssoc(op) != leftAssoc)
- syntaxError(
- "left- and right-associative operators with same precedence may not be mixed", offset)
+ def checkAssoc(offset: Token, op1: Name, op2: Name, op2LeftAssoc: Boolean): Unit =
+ if (isLeftAssoc(op1) != op2LeftAssoc)
+ syntaxError(MixedLeftAndRightAssociativeOps(op1, op2, op2LeftAssoc), offset)
- def reduceStack(base: List[OpInfo], top: Tree, prec: Int, leftAssoc: Boolean): Tree = {
+ def reduceStack(base: List[OpInfo], top: Tree, prec: Int, leftAssoc: Boolean, op2: Name): Tree = {
if (opStack != base && precedence(opStack.head.operator.name) == prec)
- checkAssoc(opStack.head.offset, opStack.head.operator.name, leftAssoc)
+ checkAssoc(opStack.head.offset, opStack.head.operator.name, op2, leftAssoc)
def recur(top: Tree): Tree = {
if (opStack == base) top
else {
@@ -449,20 +444,20 @@ object Parsers {
var top = first
while (isIdent && in.name != notAnOperator) {
val op = if (isType) typeIdent() else termIdent()
- top = reduceStack(base, top, precedence(op.name), isLeftAssoc(op.name))
+ top = reduceStack(base, top, precedence(op.name), isLeftAssoc(op.name), op.name)
opStack = OpInfo(top, op, in.offset) :: opStack
newLineOptWhenFollowing(canStartOperand)
if (maybePostfix && !canStartOperand(in.token)) {
val topInfo = opStack.head
opStack = opStack.tail
- val od = reduceStack(base, topInfo.operand, 0, true)
+ val od = reduceStack(base, topInfo.operand, 0, true, in.name)
return atPos(startOffset(od), topInfo.offset) {
PostfixOp(od, topInfo.operator)
}
}
top = operand()
}
- reduceStack(base, top, 0, true)
+ reduceStack(base, top, 0, true, in.name)
}
/* -------- IDENTIFIERS AND LITERALS ------------------------------------------- */
@@ -474,7 +469,7 @@ object Parsers {
in.nextToken()
name
} else {
- syntaxErrorOrIncomplete(expectedMsg(IDENTIFIER))
+ syntaxErrorOrIncomplete(ExpectedTokenButFound(IDENTIFIER, in.token, in.name))
nme.ERROR
}
@@ -1055,7 +1050,7 @@ object Parsers {
case Block(Nil, EmptyTree) =>
assert(handlerStart != -1)
syntaxError(
- new EmptyCatchBlock(body),
+ EmptyCatchBlock(body),
Position(handlerStart, endOffset(handler))
)
case _ =>
diff --git a/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala b/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
index 20b655a19..09d1b20b1 100644
--- a/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
@@ -55,7 +55,6 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(implicit ctx: Cont
val _buf: TermName = "$buf"
val _md: TermName = "$md"
val _plus: TermName = "$amp$plus"
- val _scope: TermName = "$scope"
val _tmpscope: TermName = "$tmpscope"
val _xml: TermName = "xml"
}
diff --git a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
index 280832ef3..8d42e525a 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Tokens.scala
@@ -17,7 +17,7 @@ abstract class TokensCommon {
def showToken(token: Int) = {
val str = tokenString(token)
- if (keywords contains token) s"'$str'" else str
+ if (isKeyword(token)) s"'$str'" else str
}
val tokenString, debugString = new Array[String](maxToken + 1)
@@ -114,6 +114,8 @@ abstract class TokensCommon {
val keywords: TokenSet
+ def isKeyword(token: Token): Boolean = keywords contains token
+
/** parentheses */
final val LPAREN = 90; enter(LPAREN, "'('")
final val RPAREN = 91; enter(RPAREN, "')'")
diff --git a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 5b75df6b2..3d952f425 100644
--- a/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -126,8 +126,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case AppliedType(tycon, args) =>
val cls = tycon.typeSymbol
if (tycon.isRepeatedParam) return toTextLocal(args.head) ~ "*"
- if (defn.isFunctionClass(cls)) return toTextFunction(args, isImplicit = false)
- if (defn.isImplicitFunctionClass(cls)) return toTextFunction(args, isImplicit = true)
+ if (defn.isFunctionClass(cls)) return toTextFunction(args, cls.name.isImplicitFunction)
if (defn.isTupleClass(cls)) return toTextTuple(args)
return (toTextLocal(tycon) ~ "[" ~ Text(args map argText, ", ") ~ "]").close
case tp: TypeRef =>
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/Reporter.scala b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
index 26c1e5ebc..b2c7abec9 100644
--- a/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -171,22 +171,6 @@ trait Reporting { this: Context =>
throw ex
}
}
-
- /** Implements a fold that applies the function `f` to the result of `op` if
- * there are no new errors in the reporter
- *
- * @param op operation checked for errors
- * @param f function applied to result of op
- * @return either the result of `op` if it had errors or the result of `f`
- * applied to it
- */
- def withNoError[A, B >: A](op: => A)(f: A => B): B = {
- val before = reporter.errorCount
- val op0 = op
-
- if (reporter.errorCount > before) op0
- else f(op0)
- }
}
/**
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..c74130b44
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java
@@ -0,0 +1,58 @@
+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,
+ MixedLeftAndRightAssociativeOpsID;
+
+ 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 2497fb216..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,17 +115,17 @@ 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 = ""
+
+ override def toString(): String = s"NoExplanation($msg)"
}
/** The extractor for `NoExplanation` can be used to check whether any error
* 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 4d61f21cf..7fccebef9 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -4,12 +4,20 @@ package reporting
package diagnostic
import dotc.core._
-import Contexts.Context, Decorators._, Symbols._, Names._, NameOps._, Types._
+import Contexts.Context
+import Decorators._
+import Symbols._
+import Names._
+import NameOps._
+import Types._
import util.SourcePosition
import config.Settings.Setting
-import interfaces.Diagnostic.{ERROR, WARNING, INFO}
+import interfaces.Diagnostic.{ERROR, INFO, WARNING}
+import dotc.parsing.Scanners.Token
+import dotc.parsing.Tokens
import printing.Highlighting._
import printing.Formatting
+import ErrorMessageID._
object messages {
@@ -87,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) => "{}"
@@ -124,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
@@ -132,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
@@ -140,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"""
@@ -151,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"""
@@ -165,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}`"
@@ -192,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"
@@ -205,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)
@@ -220,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
@@ -286,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"
@@ -332,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"""
@@ -362,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"}"""
@@ -375,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"}"""
@@ -393,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"""
@@ -409,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"""
@@ -431,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 = {
@@ -449,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 =
@@ -482,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 = {
@@ -500,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 =
@@ -512,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"
@@ -545,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"}"""
@@ -584,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."
@@ -608,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
@@ -654,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 = {
@@ -683,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 =
@@ -696,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 = {
@@ -717,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 =
@@ -732,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 =
@@ -758,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 =
@@ -773,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.
@@ -785,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 = {
@@ -815,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 = {
@@ -895,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 -
@@ -923,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 =
@@ -967,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"}"""
@@ -1004,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"""
@@ -1016,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"""
@@ -1035,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}`"
@@ -1053,4 +1067,64 @@ object messages {
|""".stripMargin
}
+ case class ExpectedTokenButFound(expected: Token, found: Token, foundName: TermName)(implicit ctx: Context)
+ extends Message(ExpectedTokenButFoundID) {
+ val kind = "Syntax"
+
+ private val expectedText =
+ if (Tokens.isIdentifier(expected)) "an identifier"
+ else Tokens.showToken(expected)
+
+ private val foundText =
+ if (foundName != null) hl"`${foundName.show}`"
+ else Tokens.showToken(found)
+
+ val msg = hl"""${expectedText} expected, but ${foundText} found"""
+
+ private val ifKeyword =
+ if (Tokens.isIdentifier(expected) && Tokens.isKeyword(found))
+ s"""
+ |If you necessarily want to use $foundText as identifier, you may put it in backticks.""".stripMargin
+ else
+ ""
+
+ val explanation =
+ s"""|The text ${foundText} may not occur at that position, the compiler expected ${expectedText}.$ifKeyword
+ |""".stripMargin
+ }
+
+ case class MixedLeftAndRightAssociativeOps(op1: Name, op2: Name, op2LeftAssoc: Boolean)(implicit ctx: Context)
+ extends Message(MixedLeftAndRightAssociativeOpsID) {
+ val kind = "Syntax"
+ val op1Asso = if (op2LeftAssoc) "which is right-associative" else "which is left-associative"
+ val op2Asso = if (op2LeftAssoc) "which is left-associative" else "which is right-associative"
+ val msg = s"`${op1}` (${op1Asso}) and `${op2}` ($op2Asso) have same precedence and may not be mixed"
+ val explanation =
+ s"""|The operators ${op1} and ${op2} are used as infix operators in the same expression,
+ |but they bind to different sides:
+ |${op1} is applied to the operand to its ${if (op2LeftAssoc) "right" else "left"}
+ |${op2} is applied to the operand to its ${if (op2LeftAssoc) "left" else "right"}
+ |As both have the same precedence the compiler can't decide which to apply first.
+ |
+ |You may use parenthesis to make the application order explicit,
+ |or use method application syntax `operand1.${op1}(operand2)`.
+ |
+ |Operators ending in a colon `:` are right-associative. All other operators are left-associative.
+ |
+ |Infix operator precedence is determined by the operator's first character. Characters are listed
+ |below in increasing order of precedence, with characters on the same line having the same precedence.
+ | (all letters)
+ | |
+ | ^
+ | &
+ | = !
+ | < >
+ | :
+ | + -
+ | * / %
+ | (all other special characters)
+ |Operators starting with a letter have lowest precedence, followed by operators starting with `|`, etc.
+ |""".stripMargin
+ }
+
}
diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
index bba97c4c2..3857b405f 100644
--- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
@@ -349,10 +349,8 @@ object Erasure extends TypeTestsCasts{
if ((owner eq defn.AnyClass) || (owner eq defn.AnyValClass)) {
assert(sym.isConstructor, s"${sym.showLocated}")
defn.ObjectClass
- } else if (defn.isXXLFunctionClass(owner))
- defn.FunctionXXLClass
- else if (defn.isImplicitFunctionClass(owner))
- recur(defn.FunctionClass(owner.name.functionArity))
+ } else if (defn.isSyntheticFunctionClass(owner))
+ defn.erasedFunctionClass(owner)
else
owner
recur(sym.owner)
@@ -417,7 +415,7 @@ object Erasure extends TypeTestsCasts{
if (tree.symbol == ctx.owner.lexicallyEnclosingClass || tree.symbol.isStaticOwner) promote(tree)
else {
ctx.log(i"computing outer path from ${ctx.owner.ownersIterator.toList}%, % to ${tree.symbol}, encl class = ${ctx.owner.enclosingClass}")
- outer.path(tree.symbol)
+ outer.path(toCls = tree.symbol)
}
private def runtimeCallWithProtoArgs(name: Name, pt: Type, args: Tree*)(implicit ctx: Context): Tree = {
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index c2aacf826..d75c32fcc 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -60,7 +60,8 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
/** Convert a selection of the form `qual.C_<OUTER>` to an outer path from `qual` to `C` */
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
if (tree.name.isOuterSelect)
- outer.path(tree.tpe.widen.classSymbol, tree.qualifier).ensureConforms(tree.tpe)
+ outer.path(start = tree.qualifier, count = tree.name.outerSelectHops)
+ .ensureConforms(tree.tpe)
else tree
/** First, add outer accessors if a class does not have them yet and it references an outer this.
@@ -354,24 +355,32 @@ object ExplicitOuter {
} else Nil
}
- /** The path of outer accessors that references `toCls.this` starting from
- * the context owner's this node.
+ /** A path of outer accessors starting from node `start`. `start` defaults to the
+ * context owner's this node. There are two alternative conditions that determine
+ * where the path ends:
+ *
+ * - if the initial `count` parameter is non-negative: where the number of
+ * outer accessors reaches count.
+ * - if the initial `count` parameter is negative: where the class symbol of
+ * the type of the reached tree matches `toCls`.
*/
- def path(toCls: Symbol, start: Tree = This(ctx.owner.lexicallyEnclosingClass.asClass)): Tree = try {
- def loop(tree: Tree): Tree = {
+ def path(start: Tree = This(ctx.owner.lexicallyEnclosingClass.asClass),
+ toCls: Symbol = NoSymbol,
+ count: Int = -1): Tree = try {
+ def loop(tree: Tree, count: Int): Tree = {
val treeCls = tree.tpe.widen.classSymbol
val outerAccessorCtx = ctx.withPhaseNoLater(ctx.lambdaLiftPhase) // lambdalift mangles local class names, which means we cannot reliably find outer acessors anymore
ctx.log(i"outer to $toCls of $tree: ${tree.tpe}, looking for ${outerAccName(treeCls.asClass)(outerAccessorCtx)} in $treeCls")
- if (treeCls == toCls) tree
+ if (count == 0 || count < 0 && treeCls == toCls) tree
else {
val acc = outerAccessor(treeCls.asClass)(outerAccessorCtx)
assert(acc.exists,
i"failure to construct path from ${ctx.owner.ownersIterator.toList}%/% to `this` of ${toCls.showLocated};\n${treeCls.showLocated} does not have an outer accessor")
- loop(tree.select(acc).ensureApplied)
+ loop(tree.select(acc).ensureApplied, count - 1)
}
}
ctx.log(i"computing outerpath to $toCls from ${ctx.outersIterator.map(_.owner).toList}")
- loop(start)
+ loop(start, count)
} catch {
case ex: ClassCastException =>
throw new ClassCastException(i"no path exists from ${ctx.owner.enclosingClass} to $toCls")
diff --git a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
index 19fb3dd0c..b603a53dc 100644
--- a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -440,10 +440,10 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
singleton(clazz.thisType)
else if (ctx.owner.isConstructor)
outerParam.get(ctx.owner) match {
- case Some(param) => outer.path(clazz, Ident(param.termRef))
- case _ => outer.path(clazz)
+ case Some(param) => outer.path(start = Ident(param.termRef), toCls = clazz)
+ case _ => outer.path(toCls = clazz)
}
- else outer.path(clazz)
+ else outer.path(toCls = clazz)
transformFollowingDeep(qual.select(sym))
}
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
index eee429a87..7a4af647f 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -12,6 +12,7 @@ import core.Types._
import core.Flags._
import core.Constants._
import core.StdNames._
+import core.NameOps._
import core.Decorators._
import core.TypeErasure.isErasedType
import core.Phases.Phase
@@ -81,7 +82,7 @@ class TreeChecker extends Phase with SymTransformer {
val sym = symd.symbol
if (sym.isClass && !sym.isAbsent) {
- val validSuperclass = sym.isPrimitiveValueClass || defn.syntheticCoreClasses.contains(sym) ||
+ val validSuperclass = sym.isPrimitiveValueClass || defn.syntheticCoreClasses.contains(sym) ||
(sym eq defn.ObjectClass) || (sym is NoSuperClass) || (sym.asClass.superClass.exists)
if (!validSuperclass)
printError(s"$sym has no superclass set")
@@ -336,7 +337,10 @@ class TreeChecker extends Phase with SymTransformer {
assert(tree.isTerm || !ctx.isAfterTyper, tree.show + " at " + ctx.phase)
val tpe = tree.typeOpt
val sym = tree.symbol
- if (!tpe.isInstanceOf[WithFixedSym] && sym.exists && !sym.is(Private)) {
+ if (!tpe.isInstanceOf[WithFixedSym] &&
+ sym.exists && !sym.is(Private) &&
+ !tree.name.isOuterSelect // outer selects have effectively fixed symbols
+ ) {
val qualTpe = tree.qualifier.typeOpt
val member =
if (sym.is(Private)) qualTpe.member(tree.name)
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/Inliner.scala b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
index cfc0003c6..27c7d0c2f 100644
--- a/compiler/src/dotty/tools/dotc/typer/Inliner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Inliner.scala
@@ -27,7 +27,7 @@ import transform.TypeUtils._
object Inliner {
import tpd._
- /** Adds accessors accessors for all non-public term members accessed
+ /** Adds accessors for all non-public term members accessed
* from `tree`. Non-public type members are currently left as they are.
* This means that references to a private type will lead to typing failures
* on the code when it is inlined. Less than ideal, but hard to do better (see below).
@@ -190,7 +190,8 @@ object Inliner {
val inlineCtx = ctx
sym.updateAnnotation(LazyBodyAnnotation { _ =>
implicit val ctx = inlineCtx
- ctx.withNoError(treeExpr(ctx))(makeInlineable)
+ val body = treeExpr(ctx)
+ if (ctx.reporter.hasErrors) body else makeInlineable(body)
})
}
}
@@ -233,8 +234,10 @@ object Inliner {
* and body that replace it.
*/
def inlineCall(tree: Tree, pt: Type)(implicit ctx: Context): Tree =
- if (enclosingInlineds.length < ctx.settings.xmaxInlines.value)
- new Inliner(tree, bodyToInline(tree.symbol)).inlined(pt)
+ if (enclosingInlineds.length < ctx.settings.xmaxInlines.value) {
+ val body = bodyToInline(tree.symbol) // can typecheck the tree and thereby produce errors
+ if (ctx.reporter.hasErrors) tree else new Inliner(tree, body).inlined(pt)
+ }
else errorTree(
tree,
i"""|Maximal number of successive inlines (${ctx.settings.xmaxInlines.value}) exceeded,
@@ -396,24 +399,29 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
def classOf(selfSym: Symbol) = selfSym.info.widen.classSymbol
// The name of the outer selector that computes the rhs of `selfSym`
- def outerSelector(selfSym: Symbol): TermName = classOf(selfSym).name.toTermName ++ nme.OUTER_SELECT
+ def outerSelector(n: Int): TermName = n.toString.toTermName ++ nme.OUTER_SELECT
// The total nesting depth of the class represented by `selfSym`.
def outerLevel(selfSym: Symbol): Int = classOf(selfSym).ownersIterator.length
- // All needed this-proxies, sorted by nesting depth of the classes they represent (innermost first)
- val accessedSelfSyms = thisProxy.values.toList.map(_.symbol).sortBy(-outerLevel(_))
+ // All needed this-proxies, paired-with and sorted-by nesting depth of
+ // the classes they represent (innermost first)
+ val sortedProxies = thisProxy.toList.map {
+ case (cls, proxy) => (outerLevel(cls), proxy.symbol)
+ } sortBy (-_._1)
// Compute val-definitions for all this-proxies and append them to `bindingsBuf`
var lastSelf: Symbol = NoSymbol
- for (selfSym <- accessedSelfSyms) {
+ var lastLevel: Int = 0
+ for ((level, selfSym) <- sortedProxies) {
val rhs =
if (!lastSelf.exists)
prefix
else
- untpd.Select(ref(lastSelf), outerSelector(selfSym)).withType(selfSym.info)
+ untpd.Select(ref(lastSelf), outerSelector(lastLevel - level)).withType(selfSym.info)
bindingsBuf += ValDef(selfSym.asTerm, rhs)
lastSelf = selfSym
+ lastLevel = level
}
// The type map to apply to the inlined tree. This maps references to this-types
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index ded8993fb..26f7bc65b 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -351,6 +351,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val ownType =
if (rawType.exists)
ensureAccessible(rawType, superAccess = false, tree.pos)
+ else if (name == nme._scope) {
+ // gross hack to support current xml literals.
+ // awaiting a better implicits based solution for library-supported xml
+ return ref(defn.XMLTopScopeModuleRef)
+ }
else
errorType(new MissingIdent(tree, kind, name.show), tree.pos)
@@ -518,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,
@@ -538,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)
@@ -664,9 +676,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = track("typedFunction") {
val untpd.Function(args, body) = tree
if (ctx.mode is Mode.Type) {
- val funCls =
- if (tree.isInstanceOf[untpd.ImplicitFunction]) defn.ImplicitFunctionClass(args.length)
- else defn.FunctionClass(args.length)
+ val funCls = defn.FunctionClass(args.length, tree.isInstanceOf[untpd.ImplicitFunction])
typed(cpy.AppliedTypeTree(tree)(
untpd.TypeTree(funCls.typeRef), args :+ body), pt)
}
@@ -1118,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)
@@ -1937,7 +1945,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
!untpd.isImplicitClosure(tree) &&
!isApplyProto(pt) &&
!ctx.isAfterTyper) {
- typr.println("insert apply on implicit $tree")
+ typr.println(i"insert apply on implicit $tree")
typed(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt)
}
else if (ctx.mode is Mode.Pattern) {
@@ -1956,7 +1964,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (Inliner.hasBodyToInline(tree.symbol) &&
!ctx.owner.ownersIterator.exists(_.isInlineMethod) &&
!ctx.settings.YnoInline.value &&
- !ctx.isAfterTyper)
+ !ctx.isAfterTyper &&
+ !ctx.reporter.hasErrors)
adapt(Inliner.inlineCall(tree, pt), pt)
else if (ctx.typeComparer.GADTused && pt.isValueType)
// Insert an explicit cast, so that -Ycheck in later phases succeeds.