-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Refactor function type logic #18193
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
Refactor function type logic #18193
Changes from 6 commits
c03d69f
d7167b0
63fa75a
a420d71
8a202e5
81f5677
3ea39ea
aca69bd
96af363
21818e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -666,15 +666,17 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling | |
isSubType(info1, info2) | ||
|
||
if defn.isFunctionType(tp2) then | ||
tp1w.widenDealias match | ||
case tp1: RefinedType => | ||
return isSubInfo(tp1.refinedInfo, tp2.refinedInfo) | ||
case _ => | ||
else if tp2.parent.typeSymbol == defn.PolyFunctionClass then | ||
tp1.member(nme.apply).info match | ||
case info1: PolyType => | ||
return isSubInfo(info1, tp2.refinedInfo) | ||
case _ => | ||
if defn.isPolyFunctionType(tp2) then | ||
// TODO should we handle ErasedFunction is this same way? | ||
tp1.member(nme.apply).info match | ||
case info1: PolyType => | ||
return isSubInfo(info1, tp2.refinedInfo) | ||
case _ => | ||
else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure why there is a difference between the two comparisons. Would it work to always use the second one, which tests for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will try to merge the two cases into one (in #18200). |
||
tp1w.widenDealias match | ||
case tp1: RefinedType => | ||
return isSubInfo(tp1.refinedInfo, tp2.refinedInfo) | ||
case _ => | ||
|
||
val skipped2 = skipMatching(tp1w, tp2) | ||
if (skipped2 eq tp2) || !Config.fastPathForRefinedSubtype then | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -708,7 +708,7 @@ object Types { | |
} | ||
findMember(name, pre, required, excluded) | ||
} | ||
|
||
/** The implicit members with given name. If there are none and the denotation | ||
* contains private members, also look for shadowed non-private implicits. | ||
*/ | ||
|
@@ -1875,7 +1875,7 @@ object Types { | |
* @param alwaysDependent if true, always create a dependent function type. | ||
*/ | ||
def toFunctionType(isJava: Boolean, dropLast: Int = 0, alwaysDependent: Boolean = false)(using Context): Type = this match { | ||
case mt: MethodType if !mt.isParamDependent => | ||
case mt: MethodType if !mt.isParamDependent && !mt.hasErasedParams => | ||
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast | ||
val isContextual = mt.isContextualMethod && !ctx.erasedTypes | ||
val result1 = mt.nonDependentResultApprox match { | ||
|
@@ -1888,6 +1888,9 @@ object Types { | |
if alwaysDependent || mt.isResultDependent then | ||
RefinedType(funType, nme.apply, mt) | ||
else funType | ||
case mt: MethodType if !mt.isParamDependent => | ||
assert(mt.hasErasedParams) | ||
RefinedType(defn.ErasedFunctionType, nme.apply, mt) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of adding a case, I suggest changing the existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also moved |
||
case poly @ PolyType(_, mt: MethodType) if !mt.isParamDependent => | ||
RefinedType(defn.PolyFunctionType, nme.apply, poly) | ||
} | ||
|
@@ -4071,9 +4074,9 @@ object Types { | |
def addInto(tp: Type): Type = tp match | ||
case tp @ AppliedType(tycon, args) if tycon.typeSymbol == defn.RepeatedParamClass => | ||
tp.derivedAppliedType(tycon, addInto(args.head) :: Nil) | ||
case tp @ AppliedType(tycon, args) if defn.isFunctionType(tp) => | ||
case tp @ AppliedType(tycon, args) if defn.isFunctionNType(tp) => | ||
wrapConvertible(tp.derivedAppliedType(tycon, args.init :+ addInto(args.last))) | ||
case tp @ RefinedType(parent, rname, rinfo) if defn.isFunctionOrPolyType(tp) => | ||
case tp @ RefinedType(parent, rname, rinfo) if defn.isFunctionType(tp) => | ||
wrapConvertible(tp.derivedRefinedType(parent, rname, addInto(rinfo))) | ||
case tp: MethodOrPoly => | ||
tp.derivedLambdaType(resType = addInto(tp.resType)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"refined function type" is a misleading name because dependent function types also contain a refinement but aren't covered here, so I would call this isPolyOrErasedFunctionType if we can't find something better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used
isPolyOrErasedFunctionType