aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala17
1 files changed, 14 insertions, 3 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 9494bf4eb..ba55dfe30 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -18,6 +18,7 @@ import SymDenotations._
import Annotations._
import Names._
import NameOps._
+import NameKinds._
import Flags._
import Decorators._
import ErrorReporting._
@@ -572,7 +573,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def canAssign(sym: Symbol) = // allow assignments from the primary constructor to class fields
sym.is(Mutable, butNot = Accessor) ||
ctx.owner.isPrimaryConstructor && !sym.is(Method) && sym.owner == ctx.owner.owner ||
- ctx.owner.name.isTraitSetterName || ctx.owner.isStaticConstructor
+ ctx.owner.name.is(TraitSetterName) || ctx.owner.isStaticConstructor
lhsCore.tpe match {
case ref: TermRef if canAssign(ref.symbol) =>
assignType(cpy.Assign(tree)(lhs1, typed(tree.rhs, ref.info)))
@@ -1931,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)