diff options
Diffstat (limited to 'src/dotty/tools/dotc/typer')
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 7 |
3 files changed, 18 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 6e78a570d..7a742112b 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -553,6 +553,16 @@ trait Applications extends Compatibility { self: Typer with Dynamic => // a modified tree but this would be more convoluted and less efficient. if (proto.isTupled) proto = proto.tupled + // If some of the application's arguments are function literals without explicitly declared + // parameter types, and the expected type is a value type, relate the + // normalized result type of the application with the expected type through `<:<`. + // This can add more constraints which help sharpen the inferred parameter + // types for the argument function literal(s). + // This tweak is needed to make i1348 compile. + if (tree.args.exists(untpd.isFunctionWithImplicitParamType(_))) + if (!constrainResult(fun1.tpe.widen, proto.derivedFunProto(resultType = pt))) + typr.println(i"result failure for $tree with type ${fun1.tpe.widen}, expected = $pt") + fun1.tpe match { case ErrorType => tree.withType(ErrorType) case TryDynamicCallType => diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index a430d5f75..767ccbe7d 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -175,7 +175,7 @@ object ProtoTypes { def isMatchedBy(tp: Type)(implicit ctx: Context) = typer.isApplicable(tp, Nil, typedArgs, resultType) - def derivedFunProto(args: List[untpd.Tree], resultType: Type, typer: Typer) = + def derivedFunProto(args: List[untpd.Tree] = this.args, resultType: Type, typer: Typer = this.typer) = if ((args eq this.args) && (resultType eq this.resultType) && (typer eq this.typer)) this else new FunProto(args, resultType, typer) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 11a7b6753..13b6167b1 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -597,6 +597,13 @@ 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]] + + pt match { + case pt: TypeVar if untpd.isFunctionWithImplicitParamType(tree) => + isFullyDefined(pt, ForceDegree.noBottom) + case _ => + } + val (protoFormals, protoResult) = decomposeProtoFunction(pt, params.length) def refersTo(arg: untpd.Tree, param: untpd.ValDef): Boolean = arg match { |