aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/Driver.scala12
-rw-r--r--src/dotty/tools/dotc/Resident.scala2
-rw-r--r--src/dotty/tools/dotc/Run.scala3
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala16
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala2
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala10
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala10
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala35
-rw-r--r--src/dotty/tools/dotc/core/TyperState.scala4
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala1
-rw-r--r--src/dotty/tools/dotc/parsing/JavaParsers.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala1
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala11
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala7
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala32
-rw-r--r--src/dotty/tools/dotc/reporting/StoreReporter.scala7
-rw-r--r--src/dotty/tools/dotc/reporting/ThrowingReporter.scala2
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala32
22 files changed, 130 insertions, 67 deletions
diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala
index 7e9d4a5e4..3b382da58 100644
--- a/src/dotty/tools/dotc/Driver.scala
+++ b/src/dotty/tools/dotc/Driver.scala
@@ -12,7 +12,7 @@ abstract class Driver extends DotClass {
protected def newCompiler(): Compiler
- protected def emptyReporter: Reporter = new StoreReporter
+ protected def emptyReporter: Reporter = new StoreReporter(null)
protected def doCompile(compiler: Compiler, fileNames: List[String])(implicit ctx: Context): Reporter =
if (fileNames.nonEmpty)
@@ -24,7 +24,7 @@ abstract class Driver extends DotClass {
catch {
case ex: FatalError =>
ctx.error(ex.getMessage) // signals that we should fail compilation.
- ctx.typerState.reporter
+ ctx.reporter
}
else emptyReporter
@@ -44,8 +44,14 @@ abstract class Driver extends DotClass {
doCompile(newCompiler(), fileNames)(ctx)
}
+ // We overload `process` instead of using a default argument so that we
+ // can easily call this method using reflection from `RawCompiler` in sbt.
+ def process(args: Array[String]): Reporter = {
+ process(args, initCtx)
+ }
+
def main(args: Array[String]): Unit =
- sys.exit(if (process(args, initCtx).hasErrors) 1 else 0)
+ sys.exit(if (process(args).hasErrors) 1 else 0)
}
class FatalError(msg: String) extends Exception
diff --git a/src/dotty/tools/dotc/Resident.scala b/src/dotty/tools/dotc/Resident.scala
index 9578e7d2c..3ae369f27 100644
--- a/src/dotty/tools/dotc/Resident.scala
+++ b/src/dotty/tools/dotc/Resident.scala
@@ -47,7 +47,7 @@ class Resident extends Driver {
nextCtx = rootCtx
line = getLine()
}
- if (line.startsWith(quit)) ctx.typerState.reporter
+ if (line.startsWith(quit)) ctx.reporter
else loop(line split "\\s+", nextCtx)
}
loop(args, rootCtx)
diff --git a/src/dotty/tools/dotc/Run.scala b/src/dotty/tools/dotc/Run.scala
index 553805d95..ba86e3e70 100644
--- a/src/dotty/tools/dotc/Run.scala
+++ b/src/dotty/tools/dotc/Run.scala
@@ -50,6 +50,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
}
protected def compileUnits() = Stats.monitorHeartBeat {
+ ctx.checkSingleThreaded()
val phases = ctx.squashPhases(ctx.phasePlan,
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, ctx.settings.YstopAfter.value, ctx.settings.Ycheck.value)
ctx.usePhases(phases)
@@ -84,7 +85,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
/** Print summary; return # of errors encountered */
def printSummary(): Reporter = {
ctx.runInfo.printMaxConstraint()
- val r = ctx.typerState.reporter
+ val r = ctx.reporter
r.printSummary
r
}
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index d1f101283..1ef883bf2 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -556,14 +556,20 @@ object desugar {
DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(synthetic),
Closure(Nil, Ident(nme.ANON_FUN), EmptyTree))
- /** Expand partial function
+ /** If `nparams` == 1, expand partial function
+ *
* { cases }
* ==>
- * x$0 => x$0 match { cases }
+ * x$1 => x$1 match { cases }
+ *
+ * If `nparams` != 1, expand instead to
+ *
+ * (x$1, ..., x$n) => (x$0, ..., x${n-1}) match { cases }
*/
- def makeCaseLambda(cases: List[CaseDef])(implicit ctx: Context) = {
- val param = makeSyntheticParameter()
- Function(param :: Nil, Match(Ident(param.name), cases))
+ def makeCaseLambda(cases: List[CaseDef], nparams: Int = 1)(implicit ctx: Context) = {
+ val params = (1 to nparams).toList.map(makeSyntheticParameter(_))
+ val selector = makeTuple(params.map(p => Ident(p.name)))
+ Function(params, Match(selector, cases))
}
/** Add annotation with class `cls` to tree:
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index a10dfaa16..54ace3be4 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -146,7 +146,7 @@ object Trees {
* type. (Overridden by empty trees)
*/
def withType(tpe: Type)(implicit ctx: Context): ThisTree[Type] = {
- if (tpe == ErrorType) assert(ctx.errorsReported)
+ if (tpe == ErrorType) assert(ctx.reporter.errorsReported)
withTypeUnchecked(tpe)
}
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index f9d64b2cc..d5fdba1af 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -611,6 +611,16 @@ object Contexts {
superIdOfClass.clear()
lastSuperId = -1
}
+
+ // Test that access is single threaded
+
+ /** The thread on which `checkSingleThreaded was invoked last */
+ @sharable private var thread: Thread = null
+
+ /** Check that we are on the same thread as before */
+ def checkSingleThreaded() =
+ if (thread == null) thread = Thread.currentThread()
+ else assert(thread == Thread.currentThread(), "illegal multithreaded access to ContextBase")
}
object Context {
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index bd03cc056..65df55a9d 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -193,9 +193,11 @@ object Denotations {
*/
def requiredSymbol(p: Symbol => Boolean, source: AbstractFile = null, generateStubs: Boolean = true)(implicit ctx: Context): Symbol =
disambiguate(p) match {
- case MissingRef(ownerd, name) =>
- if (generateStubs)
+ case m @ MissingRef(ownerd, name) =>
+ if (generateStubs) {
+ m.ex.printStackTrace()
ctx.newStubSymbol(ownerd.symbol, name, source)
+ }
else NoSymbol
case NoDenotation | _: NoQualifyingRef =>
throw new TypeError(s"None of the alternatives of $this satisfies required predicate")
@@ -858,7 +860,9 @@ object Denotations {
/** An error denotation that provides more info about the missing reference.
* Produced by staticRef, consumed by requiredSymbol.
*/
- case class MissingRef(val owner: SingleDenotation, name: Name)(implicit ctx: Context) extends ErrorDenotation
+ case class MissingRef(val owner: SingleDenotation, name: Name)(implicit ctx: Context) extends ErrorDenotation {
+ val ex: Exception = new Exception
+ }
/** An error denotation that provides more info about alternatives
* that were found but that do not qualify.
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index f2a4c9e1e..684e9cbfd 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -123,7 +123,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
pendingSubTypes = new mutable.HashSet[(Type, Type)]
ctx.log(s"!!! deep subtype recursion involving ${tp1.show} <:< ${tp2.show}, constraint = ${state.constraint.show}")
ctx.log(s"!!! constraint = ${constraint.show}")
- assert(!ctx.settings.YnoDeepSubtypes.value)
+ if (ctx.settings.YnoDeepSubtypes.value) throw new Error("deep subtype")
if (Config.traceDeepSubTypeRecursions && !this.isInstanceOf[ExplainingTypeComparer])
ctx.log(TypeComparer.explained(implicit ctx => ctx.typeComparer.isSubType(tp1, tp2)))
}
@@ -197,8 +197,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
val cls1 = tp1.cls
cls1.classInfo.selfType.derivesFrom(cls2) &&
cls2.classInfo.selfType.derivesFrom(cls1)
- case tp1: TermRef if tp2.cls eq tp1.symbol.moduleClass =>
- isSubType(tp1.prefix, cls2.owner.thisType)
+ case tp1: TermRef if cls2.is(Module) && cls2.eq(tp1.widen.typeSymbol) =>
+ cls2.isStaticOwner ||
+ isSubType(tp1.prefix, cls2.owner.thisType) ||
+ secondTry(tp1, tp2)
case _ =>
secondTry(tp1, tp2)
}
@@ -257,9 +259,12 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
}
comparePolyParam
case tp1: ThisType =>
+ val cls1 = tp1.cls
tp2 match {
- case tp2: TermRef if tp1.cls eq tp2.symbol.moduleClass =>
- isSubType(tp1.cls.owner.thisType, tp2.prefix)
+ case tp2: TermRef if cls1.is(Module) && cls1.eq(tp2.widen.typeSymbol) =>
+ cls1.isStaticOwner ||
+ isSubType(cls1.owner.thisType, tp2.prefix) ||
+ thirdTry(tp1, tp2)
case _ =>
thirdTry(tp1, tp2)
}
@@ -779,8 +784,24 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
else {
val t2 = mergeIfSub(tp2, tp1)
if (t2.exists) t2
- else andType(tp1, tp2)
- }
+ else tp1 match {
+ case tp1: ConstantType =>
+ tp2 match {
+ case tp2: ConstantType =>
+ // Make use of the fact that the intersection of two constant types
+ // types which are not subtypes of each other is known to be empty.
+ // Note: The same does not apply to singleton types in general.
+ // E.g. we could have a pattern match against `x.type & y.type`
+ // which might succeed if `x` and `y` happen to be the same ref
+ // at run time. It would not work to replace that with `Nothing`.
+ // However, maybe we can still apply the replacement to
+ // types which are not explicitly written.
+ defn.NothingType
+ case _ => andType(tp1, tp2)
+ }
+ case _ => andType(tp1, tp2)
+ }
+ }
}
}
}
diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala
index 5617f568a..36f026107 100644
--- a/src/dotty/tools/dotc/core/TyperState.scala
+++ b/src/dotty/tools/dotc/core/TyperState.scala
@@ -98,7 +98,7 @@ extends TyperState(r) {
override def fresh(isCommittable: Boolean): TyperState =
- new MutableTyperState(this, new StoreReporter, isCommittable)
+ new MutableTyperState(this, new StoreReporter(reporter), isCommittable)
override def withReporter(reporter: Reporter) =
new MutableTyperState(this, reporter, isCommittable)
@@ -169,7 +169,7 @@ extends TyperState(r) {
* found a better solution.
*/
override def tryWithFallback[T](op: => T)(fallback: => T)(implicit ctx: Context): T = {
- val storeReporter = new StoreReporter
+ val storeReporter = new StoreReporter(myReporter)
val savedReporter = myReporter
myReporter = storeReporter
val savedConstraint = myConstraint
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index c7df3c400..cdb733efa 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -405,6 +405,7 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
// println(owner.info.decls.toList.map(_.debugString).mkString("\n ")) // !!! DEBUG
// }
// (5) Create a stub symbol to defer hard failure a little longer.
+ new Exception().printStackTrace()
ctx.newStubSymbol(owner, name, source)
}
}
diff --git a/src/dotty/tools/dotc/parsing/JavaParsers.scala b/src/dotty/tools/dotc/parsing/JavaParsers.scala
index 297f3c0f9..7b9d29ce3 100644
--- a/src/dotty/tools/dotc/parsing/JavaParsers.scala
+++ b/src/dotty/tools/dotc/parsing/JavaParsers.scala
@@ -356,7 +356,7 @@ object JavaParsers {
// assumed true unless we see public/private/protected
var isPackageAccess = true
var annots: List[Tree] = Nil
- def addAnnot(sym: ClassSymbol) = annots :+= New(TypeTree(sym.typeRef))
+ def addAnnot(sym: ClassSymbol) = annots :+= New(TypeTree(sym.typeRef)).withPos(Position(in.offset))
while (true) {
in.token match {
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 4b22eac95..caa15c7ff 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -322,6 +322,7 @@ object Parsers {
case Ident(name1) => placeholderParams.nonEmpty && name1 == placeholderParams.head.name
case Typed(t1, _) => isWildcard(t1)
case Annotated(t1, _) => isWildcard(t1)
+ case Parens(t1) => isWildcard(t1)
case _ => false
}
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index a46665ec0..d50b551fa 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -45,8 +45,10 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
override def nameString(name: Name): String = name.decode.toString
- override protected def simpleNameString(sym: Symbol): String =
- sym.name.decode.toString
+ override protected def simpleNameString(sym: Symbol): String = {
+ val name = sym.originalName
+ nameString(if (sym is ExpandedTypeParam) name.asTypeName.unexpandedName else name)
+ }
override protected def fullNameOwner(sym: Symbol) = {
val owner = super.fullNameOwner(sym)
@@ -86,10 +88,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
else {
val tsym = tp.parent.member(tp.refinedName).symbol
if (!tsym.exists) super.refinementNameString(tp)
- else {
- val name = tsym.originalName
- nameString(if (tsym is ExpandedTypeParam) name.asTypeName.unexpandedName else name)
- }
+ else simpleNameString(tsym)
}
override def toText(tp: Type): Text = controlled {
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index 26e6324eb..3e2aaa880 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -40,8 +40,9 @@ class ConsoleReporter(
}
}
- override def doReport(d: Diagnostic)(implicit ctx: Context): Unit =
- if (!d.isSuppressed || !hasErrors) d match {
+ override def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = {
+ val issue = !(d.isSuppressed && hasErrors)
+ if (issue) d match {
case d: Error =>
printMessageAndPos(s"error: ${d.msg}", d.pos)
if (ctx.settings.prompt.value) displayPrompt()
@@ -51,6 +52,8 @@ class ConsoleReporter(
case _ =>
printMessageAndPos(d.msg, d.pos)
}
+ issue
+ }
def displayPrompt(): Unit = {
writer.print("\na)bort, s)tack, r)esume: ")
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index 086575fb4..0358f71f6 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -173,8 +173,6 @@ trait Reporting { this: Context =>
throw ex
}
}
-
- def errorsReported: Boolean = outersIterator exists (_.reporter.hasErrors)
}
/**
@@ -183,8 +181,10 @@ trait Reporting { this: Context =>
*/
abstract class Reporter {
- /** Report a diagnostic */
- def doReport(d: Diagnostic)(implicit ctx: Context): Unit
+ /** Report a diagnostic, unless it is suppressed because it is nonsensical
+ * @return a diagnostic was reported.
+ */
+ def doReport(d: Diagnostic)(implicit ctx: Context): Boolean
/** Whether very long lines can be truncated. This exists so important
* debugging information (like printing the classpath) is not rendered
@@ -213,20 +213,24 @@ abstract class Reporter {
def hasErrors = errorCount > 0
def hasWarnings = warningCount > 0
+ /** Have errors been reported by this reporter, or in the
+ * case where this is a StoreReporter, by an outer reporter?
+ */
+ def errorsReported = hasErrors
+
val unreportedWarnings = new mutable.HashMap[String, Int] {
override def default(key: String) = 0
}
- def report(d: Diagnostic)(implicit ctx: Context): Unit = if (!isHidden(d)) {
- doReport(d)(ctx.addMode(Mode.Printing))
- d match {
- case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1
- case d: Warning => warningCount += 1
- case d: Error => errorCount += 1
- case d: Info => // nothing to do here
- // match error if d is something else
- }
- }
+ def report(d: Diagnostic)(implicit ctx: Context): Unit =
+ if (!isHidden(d) && doReport(d)(ctx.addMode(Mode.Printing)))
+ d match {
+ case d: ConditionalWarning if !d.enablingOption.value => unreportedWarnings(d.enablingOption.name) += 1
+ case d: Warning => warningCount += 1
+ case d: Error => errorCount += 1
+ case d: Info => // nothing to do here
+ // match error if d is something else
+ }
def incomplete(d: Diagnostic)(implicit ctx: Context): Unit =
incompleteHandler(d)(ctx)
diff --git a/src/dotty/tools/dotc/reporting/StoreReporter.scala b/src/dotty/tools/dotc/reporting/StoreReporter.scala
index 51d3df110..8209839eb 100644
--- a/src/dotty/tools/dotc/reporting/StoreReporter.scala
+++ b/src/dotty/tools/dotc/reporting/StoreReporter.scala
@@ -10,14 +10,15 @@ import config.Printers._
/**
* This class implements a Reporter that stores all messages
*/
-class StoreReporter extends Reporter {
+class StoreReporter(outer: Reporter) extends Reporter {
private var infos: mutable.ListBuffer[Diagnostic] = null
- def doReport(d: Diagnostic)(implicit ctx: Context): Unit = {
+ def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = {
typr.println(s">>>> StoredError: ${d.msg}") // !!! DEBUG
if (infos == null) infos = new mutable.ListBuffer
infos += d
+ true
}
override def hasPending: Boolean = infos != null && {
@@ -33,4 +34,6 @@ class StoreReporter extends Reporter {
infos foreach ctx.reporter.report
infos = null
}
+
+ override def errorsReported = hasErrors || outer.errorsReported
}
diff --git a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala
index 026453036..7c63383e9 100644
--- a/src/dotty/tools/dotc/reporting/ThrowingReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ThrowingReporter.scala
@@ -11,7 +11,7 @@ import Reporter._
* info to the underlying reporter.
*/
class ThrowingReporter(reportInfo: Reporter) extends Reporter {
- def doReport(d: Diagnostic)(implicit ctx: Context): Unit = d match {
+ def doReport(d: Diagnostic)(implicit ctx: Context): Boolean = d match {
case _: Error => throw d
case _ => reportInfo.doReport(d)
}
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index 2296ae658..1f47b4486 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -118,7 +118,7 @@ class TreeChecker extends Phase with SymTransformer {
val squahsedPhase = ctx.squashed(prevPhase)
ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
val checkingCtx = ctx.fresh
- .setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.typerState.reporter)))
+ .setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.reporter)))
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
catch {
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 87ad0831c..0fee17bcd 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -153,7 +153,7 @@ trait Applications extends Compatibility { self: Typer =>
def ok = _ok
def ok_=(x: Boolean) = {
- assert(x || ctx.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG
+ assert(x || ctx.reporter.errorsReported || !ctx.typerState.isCommittable) // !!! DEBUG
_ok = x
}
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 5444dddb0..e3626fe20 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -495,7 +495,7 @@ trait Implicits { self: Typer =>
case _ => false
}
}
- if (ctx.typerState.reporter.hasErrors)
+ if (ctx.reporter.hasErrors)
nonMatchingImplicit(ref)
else if (contextual && !ctx.mode.is(Mode.ImplicitShadowing) &&
!shadowing.tpe.isError && !refMatches(shadowing)) {
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index f414d3bce..ac4ad1b35 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -141,7 +141,7 @@ object Inferencing {
if (toTest.isEmpty) acc
else tree match {
case Apply(fn, _) =>
- fn.tpe match {
+ fn.tpe.widen match {
case mtp: MethodType =>
val (occ, nocc) = toTest.partition(tvar => mtp.paramTypes.exists(tvar.occursIn))
occurring(fn, nocc, occ ::: acc)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 745eee8f8..60ecaac0b 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -200,7 +200,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
*/
def isDefinedInCurrentUnit(denot: Denotation): Boolean = denot match {
case MultiDenotation(d1, d2) => isDefinedInCurrentUnit(d1) || isDefinedInCurrentUnit(d2)
- case denot: SingleDenotation => denot.symbol.sourceFile == ctx.source
+ case denot: SingleDenotation => denot.symbol.sourceFile == ctx.source.file
}
/** Is `denot` the denotation of a self symbol? */
@@ -502,6 +502,16 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
assignType(cpy.If(tree)(cond1, thenp2, elsep2), thenp2, elsep2)
}
+ private def decomposeProtoFunction(pt: Type, defaultArity: Int)(implicit ctx: Context): (List[Type], Type) = pt match {
+ case _ if defn.isFunctionType(pt) =>
+ (pt.dealias.argInfos.init, pt.dealias.argInfos.last)
+ case SAMType(meth) =>
+ val mt @ MethodType(_, paramTypes) = meth.info
+ (paramTypes, mt.resultType)
+ case _ =>
+ (List.range(0, defaultArity) map alwaysWildcardType, WildcardType)
+ }
+
def typedFunction(tree: untpd.Function, pt: Type)(implicit ctx: Context) = track("typedFunction") {
val untpd.Function(args, body) = tree
if (ctx.mode is Mode.Type)
@@ -509,15 +519,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
untpd.TypeTree(defn.FunctionClass(args.length).typeRef), args :+ body), pt)
else {
val params = args.asInstanceOf[List[untpd.ValDef]]
- val (protoFormals, protoResult): (List[Type], Type) = pt match {
- case _ if defn.isFunctionType(pt) =>
- (pt.dealias.argInfos.init, pt.dealias.argInfos.last)
- case SAMType(meth) =>
- val mt @ MethodType(_, paramTypes) = meth.info
- (paramTypes, mt.resultType)
- case _ =>
- (params map alwaysWildcardType, WildcardType)
- }
+ val (protoFormals, protoResult) = decomposeProtoFunction(pt, params.length)
def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match {
case Ident(name) => name == param.name
@@ -563,7 +565,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val pos = params indexWhere (_.name == param.name)
if (pos < mtpe.paramTypes.length) {
val ptype = mtpe.paramTypes(pos)
- if (isFullyDefined(ptype, ForceDegree.none)) return ptype
+ if (isFullyDefined(ptype, ForceDegree.noBottom)) return ptype
}
case _ =>
}
@@ -629,7 +631,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = track("typedMatch") {
tree.selector match {
case EmptyTree =>
- typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt)
+ val (protoFormals, _) = decomposeProtoFunction(pt, 1)
+ typed(desugar.makeCaseLambda(tree.cases, protoFormals.length) withPos tree.pos, pt)
case _ =>
val sel1 = typedExpr(tree.selector)
val selType = widenForMatchSelector(
@@ -1000,7 +1003,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
*/
def ensureConstrCall(cls: ClassSymbol, parents: List[Tree])(implicit ctx: Context): List[Tree] = {
val firstParent :: otherParents = parents
- if (firstParent.isType && !(cls is Trait))
+ if (firstParent.isType && !(cls is Trait) && !cls.is(JavaDefined))
typed(untpd.New(untpd.TypedSplice(firstParent), Nil)) :: otherParents
else parents
}
@@ -1238,7 +1241,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def adapt(tree: Tree, pt: Type, original: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context) = /*>|>*/ track("adapt") /*<|<*/ {
/*>|>*/ ctx.traceIndented(i"adapting $tree of type ${tree.tpe} to $pt", typr, show = true) /*<|<*/ {
- interpolateUndetVars(tree, if (tree.isDef) tree.symbol else NoSymbol)
+ if (tree.isDef) interpolateUndetVars(tree, tree.symbol)
+ else if (!tree.tpe.widen.isInstanceOf[MethodOrPoly]) interpolateUndetVars(tree, NoSymbol)
tree.overwriteType(tree.tpe.simplified)
adaptInterpolated(tree, pt, original)
}