diff options
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/Types.scala | 11 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/Applications.scala | 24 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | 28 |
3 files changed, 32 insertions, 31 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 200e94a1e..8bd729472 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1686,7 +1686,10 @@ object Types { } else newLikeThis(prefix) } - else newLikeThis(prefix) + else prefix match { + case _: WildcardType => WildcardType + case _ => newLikeThis(prefix) + } /** Create a NamedType of the same kind as this type, but with a new prefix. */ @@ -2391,6 +2394,12 @@ object Types { */ def isDependent(implicit ctx: Context): Boolean = dependencyStatus == TrueDeps + /** The result type where every reference to a parameter is replaced by a Wildcard + */ + def resultTypeApprox(implicit ctx: Context): Type = + if (isDependent) resultType.substParams(this, paramTypes.map(Function.const(WildcardType))) + else resultType + protected def computeSignature(implicit ctx: Context): Signature = resultSignature.prepend(paramTypes, isJava) diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index e9df12b42..bca44997d 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -213,16 +213,14 @@ trait Applications extends Compatibility { self: Typer with Dynamic => protected def init() = methType match { case methType: MethodType => // apply the result type constraint, unless method type is dependent - if (!methType.isDependent) { - val savedConstraint = ctx.typerState.constraint - if (!constrainResult(methType.resultType, resultType)) - if (ctx.typerState.isCommittable) - // defer the problem until after the application; - // it might be healed by an implicit conversion - assert(ctx.typerState.constraint eq savedConstraint) - else - fail(err.typeMismatchMsg(methType.resultType, resultType)) - } + val savedConstraint = ctx.typerState.constraint + if (!constrainResult(methType.resultTypeApprox, resultType)) + if (ctx.typerState.isCommittable) + // defer the problem until after the application; + // it might be healed by an implicit conversion + assert(ctx.typerState.constraint eq savedConstraint) + else + fail(err.typeMismatchMsg(methType.resultType, resultType)) // match all arguments with corresponding formal parameters matchArgs(orderedArgs, methType.paramTypes, 0) case _ => @@ -1100,10 +1098,8 @@ trait Applications extends Compatibility { self: Typer with Dynamic => /** Drop any implicit parameter section */ def stripImplicit(tp: Type): Type = tp match { - case mt: ImplicitMethodType if !mt.isDependent => - mt.resultType - // todo: make sure implicit method types are not dependent? - // but check test case in /tests/pos/depmet_implicit_chaining_zw.scala + case mt: ImplicitMethodType => + mt.resultTypeApprox case pt: PolyType => pt.derivedPolyType(pt.paramNames, pt.paramBounds, stripImplicit(pt.resultType)) case _ => diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 48f79d147..4d88fc4f5 100644 --- a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -57,7 +57,7 @@ object ProtoTypes { case pt: FunProto => mt match { case mt: MethodType => - mt.isDependent || constrainResult(mt.resultType, pt.resultType) + constrainResult(mt.resultTypeApprox, pt.resultType) case _ => true } @@ -408,22 +408,18 @@ object ProtoTypes { tp.widenSingleton match { case poly: PolyType => normalize(constrained(poly).resultType, pt) case mt: MethodType => - if (mt.isImplicit) - if (mt.isDependent) - mt.resultType.substParams(mt, mt.paramTypes.map(Function.const(WildcardType))) - else mt.resultType - else - if (mt.isDependent) tp - else { - val rt = normalize(mt.resultType, pt) - pt match { - case pt: IgnoredProto => mt - case pt: ApplyingProto => mt.derivedMethodType(mt.paramNames, mt.paramTypes, rt) - case _ => - val ft = defn.FunctionOf(mt.paramTypes, rt) - if (mt.paramTypes.nonEmpty || ft <:< pt) ft else rt - } + if (mt.isImplicit) mt.resultTypeApprox + else if (mt.isDependent) tp + else { + val rt = normalize(mt.resultType, pt) + pt match { + case pt: IgnoredProto => mt + case pt: ApplyingProto => mt.derivedMethodType(mt.paramNames, mt.paramTypes, rt) + case _ => + val ft = defn.FunctionOf(mt.paramTypes, rt) + if (mt.paramTypes.nonEmpty || ft <:< pt) ft else rt } + } case et: ExprType => et.resultType case _ => tp } |