diff options
Diffstat (limited to 'compiler/src/dotty/tools/dotc')
5 files changed, 27 insertions, 10 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 79e97becb..5a2e26099 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -352,6 +352,7 @@ class Definitions { enterCompleteClassSymbol( ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final, List(AnyClass.typeRef), EmptyScope) + def SingletonType = SingletonClass.typeRef lazy val SeqType: TypeRef = ctx.requiredClassRef("scala.collection.Seq") def SeqClass(implicit ctx: Context) = SeqType.symbol.asClass diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 1e36361f8..0f1b296b1 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -97,6 +97,7 @@ object StdNames { val EMPTY: N = "" val EMPTY_PACKAGE: N = Names.EMPTY_PACKAGE.toString val EVIDENCE_PARAM_PREFIX: N = "evidence$" + val DEP_PARAM_PREFIX = "<param>" val EXCEPTION_RESULT_PREFIX: N = "exceptionResult" val EXPAND_SEPARATOR: N = "$$" val IMPL_CLASS_SUFFIX: N = "$class" diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 8bd729472..36e0dfb0e 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -2394,12 +2394,6 @@ 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 bca44997d..e45924f83 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -213,8 +213,9 @@ 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 + val resultApprox = resultTypeApprox(methType) val savedConstraint = ctx.typerState.constraint - if (!constrainResult(methType.resultTypeApprox, resultType)) + if (!constrainResult(resultApprox, resultType)) if (ctx.typerState.isCommittable) // defer the problem until after the application; // it might be healed by an implicit conversion @@ -1099,7 +1100,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic => /** Drop any implicit parameter section */ def stripImplicit(tp: Type): Type = tp match { case mt: ImplicitMethodType => - mt.resultTypeApprox + resultTypeApprox(mt) 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 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) |