aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-02-08 21:01:41 +1100
committerGitHub <noreply@github.com>2017-02-08 21:01:41 +1100
commitb77c24cde0caa59472108a068b4d802606ad5d1b (patch)
tree1b8740978f51f75ba7d6dc25e00a17734e189437 /compiler/src/dotty/tools
parentda7d7231b7f21fe1085abc569eb783590074a359 (diff)
parent56d32fa7bd548870c8382824fe748c5c5fde1d27 (diff)
downloaddotty-b77c24cde0caa59472108a068b4d802606ad5d1b.tar.gz
dotty-b77c24cde0caa59472108a068b4d802606ad5d1b.tar.bz2
dotty-b77c24cde0caa59472108a068b4d802606ad5d1b.zip
Merge pull request #1918 from dotty-staging/fix-implicits-generic
Improvements to implicits
Diffstat (limited to 'compiler/src/dotty/tools')
-rw-r--r--compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala10
-rw-r--r--compiler/src/dotty/tools/dotc/core/TyperState.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/parsing/Parsers.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala18
-rw-r--r--compiler/src/dotty/tools/dotc/printing/Printer.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Implicits.scala22
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala3
7 files changed, 51 insertions, 22 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 42df53fed..3aa20f15b 100644
--- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -79,12 +79,12 @@ trait ConstraintHandling {
if (Config.failOnInstantiationToNothing) assert(false, msg)
else ctx.log(msg)
}
- constr.println(i"adding $description")
+ constr.println(i"adding $description in ${ctx.typerState.hashesStr}")
val lower = constraint.lower(param)
val res =
addOneBound(param, bound, isUpper = true) &&
lower.forall(addOneBound(_, bound, isUpper = true))
- constr.println(i"added $description = $res")
+ constr.println(i"added $description = $res in ${ctx.typerState.hashesStr}")
res
}
@@ -95,7 +95,7 @@ trait ConstraintHandling {
val res =
addOneBound(param, bound, isUpper = false) &&
upper.forall(addOneBound(_, bound, isUpper = false))
- constr.println(i"added $description = $res")
+ constr.println(i"added $description = $res in ${ctx.typerState.hashesStr}")
res
}
@@ -108,12 +108,12 @@ trait ConstraintHandling {
val up2 = p2 :: constraint.exclusiveUpper(p2, p1)
val lo1 = constraint.nonParamBounds(p1).lo
val hi2 = constraint.nonParamBounds(p2).hi
- constr.println(i"adding $description down1 = $down1, up2 = $up2")
+ constr.println(i"adding $description down1 = $down1, up2 = $up2 ${ctx.typerState.hashesStr}")
constraint = constraint.addLess(p1, p2)
down1.forall(addOneBound(_, hi2, isUpper = true)) &&
up2.forall(addOneBound(_, lo1, isUpper = false))
}
- constr.println(i"added $description = $res")
+ constr.println(i"added $description = $res ${ctx.typerState.hashesStr}")
res
}
diff --git a/compiler/src/dotty/tools/dotc/core/TyperState.scala b/compiler/src/dotty/tools/dotc/core/TyperState.scala
index 5c476c1cb..206438d86 100644
--- a/compiler/src/dotty/tools/dotc/core/TyperState.scala
+++ b/compiler/src/dotty/tools/dotc/core/TyperState.scala
@@ -79,6 +79,9 @@ class TyperState(r: Reporter) extends DotClass with Showable {
def tryWithFallback[T](op: => T)(fallback: => T)(implicit ctx: Context): T = unsupported("tryWithFallBack")
override def toText(printer: Printer): Text = "ImmutableTyperState"
+
+ /** A string showing the hashes of all nested mutable typerstates */
+ def hashesStr: String = ""
}
class MutableTyperState(previous: TyperState, r: Reporter, override val isCommittable: Boolean)
@@ -207,4 +210,7 @@ extends TyperState(r) {
}
override def toText(printer: Printer): Text = constraint.toText(printer)
+
+ override def hashesStr: String = hashCode.toString + " -> " + previous.hashesStr
+
}
diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
index f62093db0..a733eb65d 100644
--- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -1765,12 +1765,8 @@ object Parsers {
TypeTree() // XX-METHOD-INFER
} else {
accept(COLON)
- if (in.token == ARROW) {
- if (owner.isTypeName && !(mods is Local))
- syntaxError(s"${if (mods is Mutable) "`var'" else "`val'"} parameters may not be call-by-name")
- else if (imods.hasFlags)
- syntaxError("implicit parameters may not be call-by-name")
- }
+ if (in.token == ARROW && owner.isTypeName && !(mods is Local))
+ syntaxError(s"${if (mods is Mutable) "`var'" else "`val'"} parameters may not be call-by-name")
paramType()
}
val default =
diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
index 61f23c214..ac25f7cfd 100644
--- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
+++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
@@ -6,6 +6,7 @@ import Texts._, Types._, Flags._, Names._, Symbols._, NameOps._, Constants._, De
import Contexts.Context, Scopes.Scope, Denotations.Denotation, Annotations.Annotation
import StdNames.{nme, tpnme}
import ast.Trees._, ast._
+import typer.Implicits._
import config.Config
import java.lang.Integer.toOctalString
import config.Config.summarizeDepth
@@ -484,6 +485,23 @@ class PlainPrinter(_ctx: Context) extends Printer {
}
}.close // todo: override in refined printer
+ def toText(result: SearchResult): Text = result match {
+ case result: SearchSuccess =>
+ "SearchSuccess: " ~ toText(result.ref) ~ " via " ~ toText(result.tree)
+ case result: NonMatchingImplicit =>
+ "NoImplicitMatches"
+ case result: DivergingImplicit =>
+ "Diverging Implicit"
+ case result: ShadowedImplicit =>
+ "Shadowed Implicit"
+ case result: FailedImplicit =>
+ "Failed Implicit"
+ case result: AmbiguousImplicits =>
+ "Ambiguous Implicit: " ~ toText(result.alt1) ~ " and " ~ toText(result.alt2)
+ case _ =>
+ "?Unknown Implicit Result?"
+ }
+
private var maxSummarized = Int.MaxValue
def summarized[T](depth: Int)(op: => T): T = {
diff --git a/compiler/src/dotty/tools/dotc/printing/Printer.scala b/compiler/src/dotty/tools/dotc/printing/Printer.scala
index 14b63012e..506773a4b 100644
--- a/compiler/src/dotty/tools/dotc/printing/Printer.scala
+++ b/compiler/src/dotty/tools/dotc/printing/Printer.scala
@@ -5,6 +5,7 @@ import core._
import Texts._, ast.Trees._
import Types.Type, Symbols.Symbol, Contexts.Context, Scopes.Scope, Constants.Constant,
Names.Name, Denotations._, Annotations.Annotation
+import typer.Implicits.SearchResult
/** The base class of all printers
*/
@@ -94,7 +95,10 @@ abstract class Printer {
/** Textual representation of tree */
def toText[T >: Untyped](tree: Tree[T]): Text
- /** Perform string or text-producing operation `op` so that only a
+ /** Textual representation of implicit search result */
+ def toText(result: SearchResult): Text
+
+ /** Perform string or text-producing operation `op` so that only a
* summarized text with given recursion depth is shown
*/
def summarized[T](depth: Int)(op: => T): T
diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
index 592e80048..183dff282 100644
--- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala
@@ -6,7 +6,8 @@ import core._
import ast.{Trees, untpd, tpd, TreeInfo}
import util.Positions._
import util.Stats.{track, record, monitored}
-import printing.Showable
+import printing.{Showable, Printer}
+import printing.Texts._
import Contexts._
import Types._
import Flags._
@@ -219,14 +220,16 @@ object Implicits {
}
/** The result of an implicit search */
- abstract class SearchResult
+ abstract class SearchResult extends Showable {
+ def toText(printer: Printer): Text = printer.toText(this)
+ }
/** A successful search
* @param ref The implicit reference that succeeded
* @param tree The typed tree that needs to be inserted
* @param ctx The context after the implicit search
*/
- case class SearchSuccess(tree: tpd.Tree, ref: TermRef, level: Int, tstate: TyperState) extends SearchResult {
+ case class SearchSuccess(tree: tpd.Tree, ref: TermRef, level: Int, tstate: TyperState) extends SearchResult with Showable {
override def toString = s"SearchSuccess($tree, $ref, $level)"
}
@@ -256,7 +259,7 @@ object Implicits {
}
/** An ambiguous implicits failure */
- class AmbiguousImplicits(alt1: TermRef, alt2: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
+ class AmbiguousImplicits(val alt1: TermRef, val alt2: TermRef, val pt: Type, val argument: tpd.Tree) extends ExplainedSearchFailure {
def explanation(implicit ctx: Context): String =
em"both ${err.refStr(alt1)} and ${err.refStr(alt2)} $qualify"
override def postscript(implicit ctx: Context) =
@@ -380,7 +383,9 @@ trait ImplicitRunInfo { self: RunInfo =>
EmptyTermRefSet // on the other hand, the refs of `tp` are now not accurate, so `tp` is marked incomplete.
} else {
seen += t
- iscope(t).companionRefs
+ val is = iscope(t)
+ if (!implicitScopeCache.contains(t)) incomplete += tp
+ is.companionRefs
}
}
@@ -436,10 +441,8 @@ trait ImplicitRunInfo { self: RunInfo =>
if (ctx.typerState.ephemeral)
record("ephemeral cache miss: implicitScope")
else if (canCache &&
- ((tp eq rootTp) || // first type traversed is always cached
- !incomplete.contains(tp) && // other types are cached if they are not incomplete
- result.companionRefs.forall( // and all their companion refs are cached
- implicitScopeCache.contains)))
+ ((tp eq rootTp) || // first type traversed is always cached
+ !incomplete.contains(tp))) // other types are cached if they are not incomplete
implicitScopeCache(tp) = result
result
}
@@ -604,6 +607,7 @@ trait Implicits { self: Typer =>
result match {
case result: SearchSuccess =>
result.tstate.commit()
+ implicits.println(i"committing ${result.tstate.constraint} yielding ${ctx.typerState.constraint} ${ctx.typerState.hashesStr}")
result
case result: AmbiguousImplicits =>
val deepPt = pt.deepenProto
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 59df98a93..18ae790b7 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1879,7 +1879,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
def implicitArgError(msg: String => String) =
errors += (() => msg(em"parameter $pname of $methodStr"))
- inferImplicitArg(formal, implicitArgError, tree.pos.endPos)
+ if (errors.nonEmpty) EmptyTree
+ else inferImplicitArg(formal.widenExpr, implicitArgError, tree.pos.endPos)
}
if (errors.nonEmpty) {
// If there are several arguments, some arguments might already