diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-17 18:32:11 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-17 18:32:37 +0100 |
commit | c1c933d6f936a7975ca316c69d7639145eed36e7 (patch) | |
tree | 5ea46185fa361532d0914336c7eda1fddb7c8b5b /src/dotty/tools/dotc/typer | |
parent | d0b09e431ad6974c7ebc0a7734d46050ec712fa1 (diff) | |
download | dotty-c1c933d6f936a7975ca316c69d7639145eed36e7.tar.gz dotty-c1c933d6f936a7975ca316c69d7639145eed36e7.tar.bz2 dotty-c1c933d6f936a7975ca316c69d7639145eed36e7.zip |
Fixes for by-name arguments
Previously, we did not strip off the => when comparing against expected type.
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 14 |
3 files changed, 11 insertions, 13 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 857ff31ff..6f65cd231 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -360,7 +360,7 @@ trait Applications extends Compatibility { self: Typer => init() def addArg(arg: Tree, formal: Type): Unit = - typedArgBuf += adaptInterpolated(arg, formal) + typedArgBuf += adaptInterpolated(arg, formal.widenByName) def makeVarArg(n: Int, elemFormal: Type): Unit = { val args = typedArgBuf.takeRight(n).toList @@ -411,7 +411,7 @@ trait Applications extends Compatibility { self: Typer => val result = { var typedArgs = typedArgBuf.toList - val ownType = ctx.traceIndented(i"apply $methRef to $typedArgs%, %", show = true) { + val ownType = if (!success) ErrorType else { if (!sameSeq(args, orderedArgs)) { @@ -426,7 +426,6 @@ trait Applications extends Compatibility { self: Typer => typedArgs = args.asInstanceOf[List[Tree]] methodType.instantiate(typedArgs.tpes) } - } wrapDefs(liftedDefs, cpy.Apply(app, normalizedFun, typedArgs).withType(ownType)) } } @@ -434,7 +433,7 @@ trait Applications extends Compatibility { self: Typer => /** Subclass of Application for type checking an Apply node with untyped arguments. */ class ApplyToUntyped(app: untpd.Apply, fun: Tree, methRef: TermRef, proto: FunProto, resultType: Type)(implicit ctx: Context) extends TypedApply(app, fun, methRef, proto.args, resultType) { - def typedArg(arg: untpd.Tree, formal: Type): TypedArg = proto.typedArg(arg, formal) + def typedArg(arg: untpd.Tree, formal: Type): TypedArg = proto.typedArg(arg, formal.widenByName) def treeToArg(arg: Tree): untpd.Tree = untpd.TypedSplice(arg) } diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 48b8bafe0..a6cbd58d1 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -263,13 +263,14 @@ trait Implicits { self: Typer => */ def inferImplicit(pt: Type, argument: Tree, pos: Position)(implicit ctx: Context): SearchResult = track("inferImplicit") { ctx.traceIndented(s"search implicit ${pt.show}, arg = ${argument.show}: ${argument.tpe.show}", show = true) { + assert(!(pt isRef defn.ByNameParamClass)) val isearch = if (ctx.settings.explaintypes.value) new ExplainedImplicitSearch(pt, argument, pos) else new ImplicitSearch(pt, argument, pos) val result = isearch.bestImplicit result match { case success: SearchSuccess => - println(s"committing to ${success.tstate.show}") + // println(s"committing to ${success.tstate.show}") success.tstate.commit() case _ => } diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 4d418fe97..418bf44d1 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -29,11 +29,8 @@ object Inferencing { * 2. `pt` is by name parameter type, and `tp` is compatible with its underlying type * 3. there is an implicit conversion from `tp` to `pt`. */ - def isCompatible(tp: Type, pt: Type)(implicit ctx: Context): Boolean = { - def skipByName(tp: Type): Type = - if (tp isRef defn.ByNameParamClass) tp.typeArgs.head else tp - skipByName(tp) <:< skipByName(pt) || viewExists(tp, pt) - } + def isCompatible(tp: Type, pt: Type)(implicit ctx: Context): Boolean = + tp.widenByName <:< pt.widenByName || viewExists(tp, pt) /** Test compatibility after normalization in a fresh typerstate */ def normalizedCompatible(tp: Type, pt: Type)(implicit ctx: Context) = { @@ -313,18 +310,19 @@ object Inferencing { val tp = tree.tpe.widen val constraint = ctx.typerState.constraint + /* !!! DEBUG println(s"interpolate undet vars in ${tp.show}, pos = ${tree.pos}, mode = ${ctx.mode}, undets = ${constraint.uninstVars map (tvar => s"${tvar.show}@${tvar.owningTree.pos}")}") println(s"qualifying undet vars: ${constraint.uninstVars filter qualifies map (_.show)}") println(s"fulltype: $tp") // !!! DEBUG println(s"constraint: ${constraint.show}") + */ def qualifies(tvar: TypeVar) = tree contains tvar.owningTree val vs = tp.variances(tvar => (constraint contains tvar) && qualifies(tvar)) - println(s"variances = $vs") var changed = false vs foreachBinding { (tvar, v) => if (v != 0) { - println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}") + //println(s"interpolate ${if (v == 1) "co" else "contra"}variant ${tvar.show} in ${tp.show}") tvar.instantiate(fromBelow = v == 1) changed = true } @@ -334,7 +332,7 @@ object Inferencing { else constraint.foreachUninstVar { tvar => if (!(vs contains tvar) && qualifies(tvar)) { - println(s"instantiating non-occurring $tvar in $tp") + //println(s"instantiating non-occurring $tvar in $tp") tvar.instantiate(fromBelow = true) } } |