diff options
author | Martin Odersky <odersky@gmail.com> | 2017-03-01 22:00:41 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-03-01 22:08:17 +0100 |
commit | 58b71ca50ded400efa92ac8d92f4378844baaf7d (patch) | |
tree | dd0814ee5d73996ef6e91e7d4e12c82af883d80b /compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | |
parent | e01ca04c28e242a5f602dffc28a1b1eae358ecaf (diff) | |
download | dotty-58b71ca50ded400efa92ac8d92f4378844baaf7d.tar.gz dotty-58b71ca50ded400efa92ac8d92f4378844baaf7d.tar.bz2 dotty-58b71ca50ded400efa92ac8d92f4378844baaf7d.zip |
Fix handling of dependent method types
Need to use fresh PolyParams instead of WildcardTypes
if constraint is committable.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala')
-rw-r--r-- | compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala b/compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala index 4d88fc4f5..17f13d7c1 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 => - constrainResult(mt.resultTypeApprox, pt.resultType) + constrainResult(resultTypeApprox(mt), pt.resultType) case _ => true } @@ -389,6 +389,26 @@ object ProtoTypes { /** Same as `constrained(pt, EmptyTree)`, but returns just the created polytype */ def constrained(pt: PolyType)(implicit ctx: Context): PolyType = constrained(pt, EmptyTree)._1 + /** Create a new polyparam that represents a dependent method parameter singleton */ + def newDepPolyParam(tp: Type)(implicit ctx: Context): PolyParam = { + val poly = PolyType(ctx.freshName(nme.DEP_PARAM_PREFIX).toTypeName :: Nil, 0 :: Nil)( + pt => TypeBounds.upper(AndType(tp, defn.SingletonType)) :: Nil, + pt => defn.AnyType) + ctx.typeComparer.addToConstraint(poly, Nil) + PolyParam(poly, 0) + } + + /** The result type of `mt`, where all references to parameters of `mt` are + * replaced by either wildcards (if typevarsMissContext) or polyparams. + */ + def resultTypeApprox(mt: MethodType)(implicit ctx: Context): Type = + if (mt.isDependent) { + def replacement(tp: Type) = + if (ctx.mode.is(Mode.TypevarsMissContext)) WildcardType else newDepPolyParam(tp) + mt.resultType.substParams(mt, mt.paramTypes.map(replacement)) + } + else mt.resultType + /** The normalized form of a type * - unwraps polymorphic types, tracking their parameters in the current constraint * - skips implicit parameters; if result type depends on implicit parameter, @@ -408,7 +428,7 @@ object ProtoTypes { tp.widenSingleton match { case poly: PolyType => normalize(constrained(poly).resultType, pt) case mt: MethodType => - if (mt.isImplicit) mt.resultTypeApprox + if (mt.isImplicit) resultTypeApprox(mt) else if (mt.isDependent) tp else { val rt = normalize(mt.resultType, pt) |