aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala12
-rw-r--r--src/dotty/tools/dotc/typer/ProtoTypes.scala9
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala53
4 files changed, 47 insertions, 29 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 92acb7939..a4c26080d 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -346,7 +346,7 @@ trait Applications extends Compatibility { self: Typer =>
init()
def addArg(arg: Tree, formal: Type): Unit =
- typedArgBuf += adaptInterpolated(arg, formal.widenExpr)
+ typedArgBuf += adaptInterpolated(arg, formal.widenExpr, EmptyTree)
def makeVarArg(n: Int, elemFormal: Type): Unit = {
val args = typedArgBuf.takeRight(n).toList
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index c3f1dcc81..e9195a072 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -404,8 +404,18 @@ class Namer { typer: Typer =>
}
}
- final override def complete(denot: SymDenotation)(implicit ctx: Context) =
+ final override def complete(denot: SymDenotation)(implicit ctx: Context) = {
+ if (completions != noPrinter && ctx.typerState != this.ctx.typerState) {
+ completions.println(completions.getClass.toString)
+ def levels(c: Context): Int =
+ if (c.typerState eq this.ctx.typerState) 0
+ else if (c.typerState == null) -1
+ else if (c.outer.typerState == c.typerState) levels(c.outer)
+ else levels(c.outer) + 1
+ completions.println(s"!!!completing ${denot.symbol.showLocated} in buried typerState, gap = ${levels(ctx)}")
+ }
completeInCreationContext(denot)
+ }
def completeInCreationContext(denot: SymDenotation): Unit =
denot.info = typeSig(denot.symbol)
diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala
index 1438f9e16..a72e98418 100644
--- a/src/dotty/tools/dotc/typer/ProtoTypes.scala
+++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala
@@ -204,7 +204,7 @@ object ProtoTypes {
targ = typer.typedUnadapted(arg, formal)
if (!ctx.reporter.hasPending) myTypedArg = myTypedArg.updated(arg, targ)
}
- typer.adapt(targ, formal)
+ typer.adapt(targ, formal, arg)
}
private var myTupled: Type = NoType
@@ -236,7 +236,7 @@ object ProtoTypes {
*
* []: argType => resultType
*/
- abstract case class ViewProto(argType: Type, override val resultType: Type)(implicit ctx: Context)
+ abstract case class ViewProto(argType: Type, override val resultType: Type)
extends CachedGroundType with ApplyingProto {
def isMatchedBy(tp: Type)(implicit ctx: Context): Boolean =
ctx.typer.isApplicable(tp, argType :: Nil, resultType)
@@ -253,7 +253,7 @@ object ProtoTypes {
override def deepenProto(implicit ctx: Context) = derivedViewProto(argType, resultType.deepenProto)
}
- class CachedViewProto(argType: Type, resultType: Type)(implicit ctx: Context) extends ViewProto(argType, resultType) {
+ class CachedViewProto(argType: Type, resultType: Type) extends ViewProto(argType, resultType) {
override def computeHash = doHash(argType, resultType)
}
@@ -373,7 +373,8 @@ object ProtoTypes {
case tp @ PolyParam(poly, pnum) =>
ctx.typerState.constraint.at(tp) match {
case bounds: TypeBounds => wildApprox(WildcardType(bounds))
- case _ => WildcardType(wildApprox(poly.paramBounds(pnum)).bounds)
+ case NoType => WildcardType(wildApprox(poly.paramBounds(pnum)).bounds)
+ case inst => wildApprox(inst)
}
case MethodParam(mt, pnum) =>
WildcardType(TypeBounds.upper(wildApprox(mt.paramTypes(pnum))))
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 5d477193c..050fcbc76 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -954,7 +954,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typed(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = /*>|>*/ ctx.traceIndented (i"typing $tree", typr, show = true) /*<|<*/ {
if (!tree.isEmpty && ctx.typerState.isGlobalCommittable) assert(tree.pos.exists, i"position not set for $tree")
- try adapt(typedUnadapted(tree, pt), pt)
+ try adapt(typedUnadapted(tree, pt), pt, tree)
catch {
case ex: CyclicReference => errorTree(tree, cyclicErrorMsg(ex))
case ex: FatalTypeError => errorTree(tree, ex.getMessage)
@@ -1036,7 +1036,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
val qualProto = SelectionProto(name, normalizedProto, NoViewsAllowed)
tryEither { implicit ctx =>
- val qual1 = adaptInterpolated(qual, qualProto)
+ val qual1 = adaptInterpolated(qual, qualProto, EmptyTree)
if ((qual eq qual1) || ctx.reporter.hasErrors) tree
else typedSelect(cpy.Select(tree, untpd.TypedSplice(qual1), name), pt)
} { (_, _) => tree
@@ -1044,11 +1044,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case _ => tree
}}
- def adapt(tree: Tree, pt: Type)(implicit ctx: Context) = /*>|>*/ track("adapt") /*<|<*/ {
+ 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)
tree overwriteType tree.tpe.simplified
- adaptInterpolated(tree, pt)
+ adaptInterpolated(tree, pt, original)
}
}
@@ -1090,7 +1090,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
* (14) When in mode EXPRmode, apply a view
* If all this fails, error
*/
- def adaptInterpolated(tree: Tree, pt: Type)(implicit ctx: Context): Tree = {
+ def adaptInterpolated(tree: Tree, pt: Type, original: untpd.Tree)(implicit ctx: Context): Tree = {
assert(pt.exists)
@@ -1104,7 +1104,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def expectedStr = err.expectedTypeStr(pt)
resolveOverloaded(alts, pt) match {
case alt :: Nil =>
- adapt(tree.withType(alt), pt)
+ adapt(tree.withType(alt), pt, original)
case Nil =>
def noMatches =
errorTree(tree,
@@ -1150,24 +1150,31 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def adaptNoArgs(wtp: Type): Tree = wtp match {
case wtp: ExprType =>
- adaptInterpolated(tree.withType(wtp.resultType), pt)
+ adaptInterpolated(tree.withType(wtp.resultType), pt, original)
case wtp: ImplicitMethodType if constrainResult(wtp, pt) =>
- def implicitArgError(msg: => String): Tree = {
- ctx.error(msg, tree.pos.endPos)
- EmptyTree
- }
- val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
- def where = d"parameter $pname of $methodStr"
- inferImplicit(formal, EmptyTree, tree.pos.endPos) match {
- case SearchSuccess(arg, _, _) =>
- adapt(arg, formal)
- case ambi: AmbiguousImplicits =>
- implicitArgError(s"ambiguous implicits: ${ambi.explanation} of $where")
- case failure: SearchFailure =>
- implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript)
+ def addImplicitArgs = {
+ def implicitArgError(msg: => String): Tree = {
+ ctx.error(msg, tree.pos.endPos)
+ EmptyTree
+ }
+ val args = (wtp.paramNames, wtp.paramTypes).zipped map { (pname, formal) =>
+ def where = d"parameter $pname of $methodStr"
+ inferImplicit(formal, EmptyTree, tree.pos.endPos) match {
+ case SearchSuccess(arg, _, _) =>
+ adapt(arg, formal)
+ case ambi: AmbiguousImplicits =>
+ implicitArgError(s"ambiguous implicits: ${ambi.explanation} of $where")
+ case failure: SearchFailure =>
+ implicitArgError(d"no implicit argument of type $formal found for $where" + failure.postscript)
+ }
}
+ adapt(tpd.Apply(tree, args), pt)
}
- adapt(tpd.Apply(tree, args), pt)
+ if ((pt eq WildcardType) || original.isEmpty) addImplicitArgs
+ else
+ ctx.typerState.tryWithFallback(addImplicitArgs) {
+ adapt(typed(original, WildcardType), pt, EmptyTree)
+ }
case wtp: MethodType if !pt.isInstanceOf[SingletonType] =>
val arity =
if (defn.isFunctionType(pt)) defn.functionArity(pt)
@@ -1176,7 +1183,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (arity >= 0 && !tree.symbol.isConstructor)
typed(etaExpand(tree, wtp, arity), pt)
else if (wtp.paramTypes.isEmpty)
- adaptInterpolated(tpd.Apply(tree, Nil), pt)
+ adaptInterpolated(tpd.Apply(tree, Nil), pt, EmptyTree)
else
errorTree(tree,
d"""missing arguments for $methodStr
@@ -1235,7 +1242,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
if (pt.isInstanceOf[PolyProto]) tree
else {
val (_, tvars) = constrained(poly, tree)
- adaptInterpolated(tree appliedToTypes tvars, pt)
+ adaptInterpolated(tree appliedToTypes tvars, pt, original)
}
case wtp =>
pt match {