diff options
author | Martin Odersky <odersky@gmail.com> | 2014-04-29 17:09:22 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-05-08 21:51:46 +0200 |
commit | 90aa3ba1df70fea42b4a1cafe6551e7c3204f012 (patch) | |
tree | 3beef6d0fb8a80bbf636657100614ea1f7c63706 /src | |
parent | 15345390b10e60d0cffd0c1eb01a61a9ef28b6d1 (diff) | |
download | dotty-90aa3ba1df70fea42b4a1cafe6551e7c3204f012.tar.gz dotty-90aa3ba1df70fea42b4a1cafe6551e7c3204f012.tar.bz2 dotty-90aa3ba1df70fea42b4a1cafe6551e7c3204f012.zip |
Better wildcard type approximation
1) PolyParams are now approximated with a bounded wildcardtype representing
the bounds in the current constraint, rather than the bounds in the parameter's
declaration. That makes them consistent with the handling of TypeVars.
2) Wildcard types are taken into consideration when result types are constrained.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index aeba02648..4aba4fb59 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -46,7 +46,7 @@ object ProtoTypes { * fits the given expected result type. */ def constrainResult(mt: Type, pt: Type)(implicit ctx: Context): Boolean = pt match { - case FunProto(_, result, _) => + case _: FunProto => mt match { case mt: MethodType => mt.isDependent || constrainResult(mt.resultType, pt.resultType) @@ -60,6 +60,8 @@ object ProtoTypes { case _ => isCompatible(mt, pt) } + case _: WildcardType => + isCompatible(mt, pt) case _ => true } @@ -217,9 +219,8 @@ object ProtoTypes { */ abstract case class ViewProto(argType: Type, override val resultType: Type)(implicit ctx: Context) extends CachedGroundType with ApplyingProto { - def isMatchedBy(tp: Type)(implicit ctx: Context): Boolean = /*ctx.conditionalTraceIndented(lookingForInfo, i"?.info isMatchedBy $tp ${tp.getClass}")*/ { + def isMatchedBy(tp: Type)(implicit ctx: Context): Boolean = ctx.typer.isApplicable(tp, argType :: Nil, resultType) - } def derivedViewProto(argType: Type, resultType: Type)(implicit ctx: Context) = if ((argType eq this.argType) && (resultType eq this.resultType)) this @@ -352,17 +353,15 @@ object ProtoTypes { tp.derivedRefinedType(wildApprox(tp.parent, theMap), tp.refinedName, wildApprox(tp.refinedInfo, theMap)) case tp: TypeBounds if tp.lo eq tp.hi => // default case, inlined for speed tp.derivedTypeAlias(wildApprox(tp.lo, theMap)) - case PolyParam(pt, pnum) => - WildcardType(wildApprox(pt.paramBounds(pnum)).bounds) + case tp @ PolyParam(poly, pnum) => + ctx.typerState.constraint.at(tp) match { + case bounds: TypeBounds => wildApprox(WildcardType(bounds)) + case _ => WildcardType(wildApprox(poly.paramBounds(pnum)).bounds) + } case MethodParam(mt, pnum) => WildcardType(TypeBounds.upper(wildApprox(mt.paramTypes(pnum)))) case tp: TypeVar => - val inst = tp.instanceOpt - if (inst.exists) wildApprox(inst) - else ctx.typerState.constraint.at(tp.origin) match { - case bounds: TypeBounds => wildApprox(WildcardType(bounds)) - case NoType => WildcardType - } + wildApprox(tp.underlying) case tp: AndType => val tp1a = wildApprox(tp.tp1) val tp2a = wildApprox(tp.tp2) |