diff options
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Typer.scala | 17 |
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) |