Skip to content

Remove patter matches on ImplicitMethodType and JavaMethodType #3212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
toDenot(fun.symbol).owner == defn.ArrayClass.linkedClass && fun.symbol.name == nme_apply =>
val arrAnnotV: AnnotationVisitor = av.visitArray(name)

var actualArgs = if (fun.tpe.isInstanceOf[ImplicitMethodType]) {
var actualArgs = if (fun.tpe.isImplicitMethod) {
// generic array method, need to get implicit argument out of the way
fun.asInstanceOf[Apply].args
} else args
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/ast/TreeInfo.scala
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
*/
def mayBeVarGetter(sym: Symbol)(implicit ctx: Context): Boolean = {
def maybeGetterType(tpe: Type): Boolean = tpe match {
case _: ExprType | _: ImplicitMethodType => true
case _: ExprType => true
case tpe: MethodType => tpe.isImplicitMethod
case tpe: PolyType => maybeGetterType(tpe.resultType)
case _ => false
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def valueParamss(tp: Type): (List[List[TermSymbol]], Type) = tp match {
case tp: MethodType =>
def valueParam(name: TermName, info: Type): TermSymbol = {
val maybeImplicit = if (tp.isInstanceOf[ImplicitMethodType]) Implicit else EmptyFlags
val maybeImplicit = if (tp.isImplicitMethod) Implicit else EmptyFlags
ctx.newSymbol(sym, name, TermParam | maybeImplicit, info)
}
val params = (tp.paramNames, tp.paramInfos).zipped.map(valueParam)
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Denotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ object Denotations {
if (tp1.isInstanceOf[PolyType] && tp2.isInstanceOf[MethodType]) tp2
else if (tp2.isInstanceOf[PolyType] && tp1.isInstanceOf[MethodType]) tp1
else if (ctx.typeComparer.matchingParams(tp1, tp2) &&
tp1.isImplicit == tp2.isImplicit)
tp1.isImplicitMethod == tp2.isImplicitMethod)
tp1.derivedLambdaType(
mergeParamNames(tp1, tp2), tp1.paramInfos,
infoMeet(tp1.resultType, tp2.resultType.subst(tp2, tp1)))
Expand Down Expand Up @@ -481,7 +481,7 @@ object Denotations {
tp2 match {
case tp2: MethodOrPoly
if ctx.typeComparer.matchingParams(tp1, tp2) &&
tp1.isImplicit == tp2.isImplicit =>
tp1.isImplicitMethod == tp2.isImplicitMethod =>
tp1.derivedLambdaType(
mergeParamNames(tp1, tp2), tp1.paramInfos,
tp1.resultType | tp2.resultType.subst(tp2, tp1))
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/core/TypeComparer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp1: MethodOrPoly =>
(tp1.signature consistentParams tp2.signature) &&
matchingParams(tp1, tp2) &&
tp1.isImplicit == tp2.isImplicit &&
tp1.isImplicitMethod == tp2.isImplicitMethod &&
isSubType(tp1.resultType, tp2.resultType.subst(tp2, tp1))
case _ =>
false
Expand Down Expand Up @@ -1136,8 +1136,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case formal2 :: rest2 =>
val formal2a = if (lam2.isParamDependent) formal2.subst(lam2, lam1) else formal2
(isSameTypeWhenFrozen(formal1, formal2a)
|| lam1.isJava && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
|| lam2.isJava && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
|| lam1.isJavaMethod && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
|| lam2.isJavaMethod && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
loop(rest1, rest2)
case nil =>
false
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ object TypeErasure {
!tp.symbol.is(JavaDefined)
case tp: TypeParamRef =>
!tp.derivesFrom(defn.ObjectClass) &&
!tp.binder.resultType.isInstanceOf[JavaMethodType]
!tp.binder.resultType.isJavaMethod
case tp: TypeAlias => isUnboundedGeneric(tp.alias)
case tp: TypeBounds => !tp.hi.derivesFrom(defn.ObjectClass)
case tp: TypeProxy => isUnboundedGeneric(tp.underlying)
Expand Down Expand Up @@ -398,7 +398,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
ctx.typeComparer.orType(this(tp1), this(tp2), erased = true)
case tp: MethodType =>
def paramErasure(tpToErase: Type) =
erasureFn(tp.isJava, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
erasureFn(tp.isJavaMethod, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
val (names, formals0) =
if (tp.paramInfos.exists(_.isPhantom)) tp.paramNames.zip(tp.paramInfos).filterNot(_._2.isPhantom).unzip
else (tp.paramNames, tp.paramInfos)
Expand Down
60 changes: 22 additions & 38 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ object Types {
/** Is this an alias TypeBounds? */
final def isAlias: Boolean = this.isInstanceOf[TypeAlias]

/** Is this a MethodType which is from Java */
def isJavaMethod: Boolean = false

/** Is this a MethodType which has implicit parameters */
def isImplicitMethod: Boolean = false

// ----- Higher-order combinators -----------------------------------

/** Returns true if there is a part of this type that satisfies predicate `p`.
Expand Down Expand Up @@ -1317,7 +1323,7 @@ object Types {
case mt: MethodType if !mt.isDependent || ctx.mode.is(Mode.AllowDependentFunctions) =>
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
defn.FunctionOf(
formals1 mapConserve (_.underlyingIfRepeated(mt.isJava)), mt.resultType, mt.isImplicit && !ctx.erasedTypes)
formals1 mapConserve (_.underlyingIfRepeated(mt.isJavaMethod)), mt.resultType, mt.isImplicitMethod && !ctx.erasedTypes)
}

/** The signature of this type. This is by default NotAMethod,
Expand Down Expand Up @@ -2552,9 +2558,6 @@ object Types {

override def resultType(implicit ctx: Context) = resType

def isJava: Boolean = false
def isImplicit = false

def isDependent(implicit ctx: Context): Boolean
def isParamDependent(implicit ctx: Context): Boolean

Expand Down Expand Up @@ -2708,12 +2711,17 @@ object Types {

type This = MethodType

def companion: MethodTypeCompanion

final override def isJavaMethod: Boolean = companion eq JavaMethodType
final override def isImplicitMethod: Boolean = companion eq ImplicitMethodType

val paramInfos = paramInfosExp(this)
val resType = resultTypeExp(this)
assert(resType.exists)

def computeSignature(implicit ctx: Context): Signature =
resultSignature.prepend(paramInfos, isJava)
resultSignature.prepend(paramInfos, isJavaMethod)

final override def computeHash = doHash(paramNames, resType, paramInfos)

Expand All @@ -2740,24 +2748,8 @@ object Types {
protected def prefixString = "MethodType"
}

final class CachedMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
extends MethodType(paramNames)(paramInfosExp, resultTypeExp) {
def companion = MethodType
}

final class JavaMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
extends MethodType(paramNames)(paramInfosExp, resultTypeExp) {
def companion = JavaMethodType
override def isJava = true
override protected def prefixString = "JavaMethodType"
}

final class ImplicitMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)
extends MethodType(paramNames)(paramInfosExp, resultTypeExp) {
def companion = ImplicitMethodType
override def isImplicit = true
override protected def prefixString = "ImplicitMethodType"
}
final class CachedMethodType(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type, val companion: MethodTypeCompanion)
extends MethodType(paramNames)(paramInfosExp, resultTypeExp)

abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType] {
def syntheticParamName(n: Int): N
Expand Down Expand Up @@ -2802,7 +2794,7 @@ object Types {
def syntheticParamName(n: Int) = tpnme.syntheticTypeParamName(n)
}

abstract class MethodTypeCompanion extends TermLambdaCompanion[MethodType] {
abstract class MethodTypeCompanion extends TermLambdaCompanion[MethodType] { self =>

/** Produce method type from parameter symbols, with special mappings for repeated
* and inline parameters:
Expand Down Expand Up @@ -2833,6 +2825,9 @@ object Types {
tl => tl.integrate(params, resultType))
}

final def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
checkValid(new CachedMethodType(paramNames)(paramInfosExp, resultTypeExp, self))

def checkValid(mt: MethodType)(implicit ctx: Context): mt.type = {
if (Config.checkMethodTypes)
for ((paramInfo, idx) <- mt.paramInfos.zipWithIndex)
Expand All @@ -2844,20 +2839,9 @@ object Types {
}
}

object MethodType extends MethodTypeCompanion {
def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
checkValid(unique(new CachedMethodType(paramNames)(paramInfosExp, resultTypeExp)))
}

object JavaMethodType extends MethodTypeCompanion {
def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
unique(new JavaMethodType(paramNames)(paramInfosExp, resultTypeExp))
}

object ImplicitMethodType extends MethodTypeCompanion {
def apply(paramNames: List[TermName])(paramInfosExp: MethodType => List[Type], resultTypeExp: MethodType => Type)(implicit ctx: Context): MethodType =
checkValid(unique(new ImplicitMethodType(paramNames)(paramInfosExp, resultTypeExp)))
}
object MethodType extends MethodTypeCompanion
object JavaMethodType extends MethodTypeCompanion
object ImplicitMethodType extends MethodTypeCompanion

/** A ternary extractor for MethodType */
object MethodTpe {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
case tp: MethodType =>
def paramText(name: TermName, tp: Type) = toText(name) ~ ": " ~ toText(tp)
changePrec(GlobalPrec) {
(if (tp.isImplicit) "(implicit " else "(") ~
(if (tp.isImplicitMethod) "(implicit " else "(") ~
Text((tp.paramNames, tp.paramInfos).zipped map paramText, ", ") ~
(if (tp.resultType.isInstanceOf[MethodType]) ")" else "): ") ~
toText(tp.resultType)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
val params = (pnames, ptypes, defaults).zipped.map((pname, ptype, isDefault) =>
new api.MethodParameter(pname.toString, apiType(ptype),
isDefault, api.ParameterModifier.Plain))
new api.ParameterList(params.toArray, mt.isImplicit) :: paramLists(restpe, params.length)
new api.ParameterList(params.toArray, mt.isImplicitMethod) :: paramLists(restpe, params.length)
case _ =>
Nil
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
val resultType1 = elimRepeated(resultType)
val paramTypes1 =
if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam) {
val last = paramTypes.last.underlyingIfRepeated(tp.isJava)
val last = paramTypes.last.underlyingIfRepeated(tp.isJavaMethod)
paramTypes.init :+ last
} else paramTypes
tp.derivedLambdaType(paramNames, paramTypes1, resultType1)
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
typedArgBuf.trimEnd(n)
val elemtpt = TypeTree(elemFormal)
val seqLit =
if (methodType.isJava) JavaSeqLiteral(args, elemtpt)
if (methodType.isJavaMethod) JavaSeqLiteral(args, elemtpt)
else SeqLiteral(args, elemtpt)
typedArgBuf += seqToRepeated(seqLit)
}
Expand Down Expand Up @@ -1149,7 +1149,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>

/** Drop any implicit parameter section */
def stripImplicit(tp: Type): Type = tp match {
case mt: ImplicitMethodType =>
case mt: MethodType if mt.isImplicitMethod =>
resultTypeApprox(mt)
case pt: PolyType =>
pt.derivedLambdaType(pt.paramNames, pt.paramInfos, stripImplicit(pt.resultType))
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ object ErrorReporting {
def dropJavaMethod(tp: Type): Type = tp match {
case tp: PolyType =>
tp.derivedLambdaType(resType = dropJavaMethod(tp.resultType))
case tp: JavaMethodType =>
case tp: MethodType if tp.isJavaMethod =>
MethodType(tp.paramNames, tp.paramInfos, dropJavaMethod(tp.resultType))
case tp => tp
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/EtaExpansion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ object EtaExpansion {
ids = ids.init :+ repeated(ids.last)
var body: Tree = Apply(lifted, ids)
mt.resultType match {
case rt: MethodType if !rt.isImplicit => body = PostfixOp(body, Ident(nme.WILDCARD))
case rt: MethodType if !rt.isImplicitMethod => body = PostfixOp(body, Ident(nme.WILDCARD))
case _ =>
}
val fn = untpd.Function(params, body)
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ object Implicits {

def discardForView(tpw: Type, argType: Type): Boolean = tpw match {
case mt: MethodType =>
mt.isImplicit ||
mt.isImplicitMethod ||
mt.paramInfos.length != 1 ||
!ctx.typerState.test(argType relaxed_<:< mt.paramInfos.head)
case poly: PolyType =>
// We do not need to call ProtoTypes#constrained on `poly` because
// `refMatches` is always called with mode TypevarsMissContext enabled.
poly.resultType match {
case mt: MethodType =>
mt.isImplicit ||
mt.isImplicitMethod ||
mt.paramInfos.length != 1 ||
!ctx.typerState.test(argType relaxed_<:< wildApprox(mt.paramInfos.head, null, Set.empty))
case rtp =>
Expand Down Expand Up @@ -109,7 +109,7 @@ object Implicits {
}

def discardForValueType(tpw: Type): Boolean = tpw.stripPoly match {
case tpw: MethodType => !tpw.isImplicit
case tpw: MethodType => !tpw.isImplicitMethod
case _ => false
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/ProtoTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ object ProtoTypes {
case poly: PolyType =>
normalize(constrained(poly).resultType, pt)
case mt: MethodType =>
if (mt.isImplicit) normalize(resultTypeApprox(mt), pt)
if (mt.isImplicitMethod) normalize(resultTypeApprox(mt), pt)
else if (mt.isDependent) tp
else {
val rt = normalize(mt.resultType, pt)
Expand Down
11 changes: 6 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1345,7 +1345,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
* @param cinfo The info of its constructor
*/
def maybeCall(ref: Tree, psym: Symbol, cinfo: Type): Tree = cinfo.stripPoly match {
case cinfo @ MethodType(Nil) if cinfo.resultType.isInstanceOf[ImplicitMethodType] =>
case cinfo @ MethodType(Nil) if cinfo.resultType.isImplicitMethod =>
val icall = New(ref).select(nme.CONSTRUCTOR).appliedToNone
typedExpr(untpd.TypedSplice(icall))(superCtx)
case cinfo @ MethodType(Nil) if !cinfo.resultType.isInstanceOf[MethodType] =>
Expand Down Expand Up @@ -1990,7 +1990,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
}

def adaptNoArgsImplicitMethod(wtp: ImplicitMethodType): Tree = {
def adaptNoArgsImplicitMethod(wtp: MethodType): Tree = {
assert(wtp.isImplicitMethod)
val tvarsToInstantiate = tvarsInParams(tree)
wtp.paramInfos.foreach(instantiateSelected(_, tvarsToInstantiate))
val constr = ctx.typerState.constraint
Expand Down Expand Up @@ -2085,7 +2086,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
typed(etaExpand(tree, wtp, arity), pt)
else if (wtp.paramInfos.isEmpty && isAutoApplied(tree.symbol))
adaptInterpolated(tpd.Apply(tree, Nil), pt)
else if (wtp.isImplicit)
else if (wtp.isImplicitMethod)
err.typeMismatch(tree, pt)
else
missingArgs(wtp)
Expand Down Expand Up @@ -2148,8 +2149,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
wtp match {
case wtp: ExprType =>
adaptInterpolated(tree.withType(wtp.resultType), pt)
case wtp: ImplicitMethodType
if constrainResult(wtp, followAlias(pt)) || !functionExpected =>
case wtp: MethodType
if wtp.isImplicitMethod && (constrainResult(wtp, followAlias(pt)) || !functionExpected) =>
adaptNoArgsImplicitMethod(wtp)
case wtp: MethodType if !pt.isInstanceOf[SingletonType] =>
val arity =
Expand Down
2 changes: 1 addition & 1 deletion doc-tool/src/dotty/tools/dottydoc/model/factories.scala
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ object factories {
isByName = tpe.isInstanceOf[ExprType],
isRepeated = tpe.isRepeatedParam
)
}, mt.isImplicit) :: paramLists(mt.resultType)
}, mt.isImplicitMethod) :: paramLists(mt.resultType)

case mp: TermParamRef =>
paramLists(mp.underlying)
Expand Down