diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2017-04-09 20:03:15 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-09 20:03:15 +0200 |
commit | 8d22a17c9bce4f730416f0d8e92dde61759b7181 (patch) | |
tree | e914a8195c2ef64f63155d82200ea53047999f13 | |
parent | c82db74c97bec486f3da7cce3128b72711c8cbc3 (diff) | |
parent | 14fde01d3576f60585d59d2b00cce8b3c177b236 (diff) | |
download | dotty-8d22a17c9bce4f730416f0d8e92dde61759b7181.tar.gz dotty-8d22a17c9bce4f730416f0d8e92dde61759b7181.tar.bz2 dotty-8d22a17c9bce4f730416f0d8e92dde61759b7181.zip |
Merge pull request #2208 from dotty-staging/fix-#2192
Fix #2192: Follow supertypes when determining whether an expect type …
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Typer.scala | 14 | ||||
-rw-r--r-- | tests/pos/i2192.scala | 7 |
2 files changed, 19 insertions, 2 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index 2760ceba9..a7b8200b5 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -1932,13 +1932,23 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit adapt(typed(original, WildcardType), pt, EmptyTree) } case wtp: MethodType if !pt.isInstanceOf[SingletonType] => + // Follow proxies and approximate type paramrefs by their upper bound + // in the current constraint in order to figure out robustly + // whether an expected type is some sort of function type. + def underlyingRefined(tp: Type): Type = tp.stripTypeVar match { + case tp: RefinedType => tp + case tp: TypeParamRef => underlyingRefined(ctx.typeComparer.bounds(tp).hi) + case tp: TypeProxy => underlyingRefined(tp.superType) + case _ => tp + } + val ptNorm = underlyingRefined(pt) val arity = - if (defn.isFunctionType(pt)) + if (defn.isFunctionType(ptNorm)) if (!isFullyDefined(pt, ForceDegree.none) && isFullyDefined(wtp, ForceDegree.none)) // if method type is fully defined, but expected type is not, // prioritize method parameter types as parameter types of the eta-expanded closure 0 - else defn.functionArity(pt) + else defn.functionArity(ptNorm) else if (pt eq AnyFunctionProto) wtp.paramInfos.length else -1 if (arity >= 0 && !tree.symbol.isConstructor) diff --git a/tests/pos/i2192.scala b/tests/pos/i2192.scala new file mode 100644 index 000000000..2e85e366e --- /dev/null +++ b/tests/pos/i2192.scala @@ -0,0 +1,7 @@ +object Test { + def foo(x: Int): Int = x + + Some(foo): Option[Int => Int] + // missing arguments for method foo + // follow this method with `_' if you want to treat it as a partially applied function +} |