-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 dependent function refinement logic #18305
Refactor dependent function refinement logic #18305
Conversation
9504f3c
to
1969f39
Compare
934255f
to
a325ff7
Compare
The current conflict is trivially fixable in a7f1966. I will rebase once I had some feedback on these changes. |
val methodType = if isContextual then ContextualMethodType else MethodType | ||
Some(methodType(argTypes, resultType)) |
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.
This is nice from a conceptual viewpoint, but I'm a bit worried about the performance impact of creating all these method types given that they are uncached types. Maybe the name of the extractor could make it clearer that there's a conversion, e.g. if we call it FromMethod
(and we call have a corresponding apply to go in the other direction).
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.
Followup in #18443
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.
I agree it's good to make the conversion explicit in the name. The performance aspects are probably OK since the alternative is usually to take the list of AppliedType arguments and split it into inits and last, which is also expensive.
* dependent refinements. Optionally returns a triple consisting of the argument | ||
* types `As`, the result type `B` and a whether the type is an erased context function. | ||
*/ | ||
object ContextFunctionType: |
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.
Isn't it still nice for convenience to keep an extractor just for context functions?
approxTp.dealias.stripPoly match | ||
case defn.FunctionOf(mt) | ||
if mt.isContextualMethod && ( | ||
mt.isResultDependent || // in this case `resType` is lying, gives us only the non-dependent upper bound |
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.
Hmm if we have an extractor that returns a MethodType I would really expect it to take dependencies into account properly
Test performance please |
This provides variant to `defn.FunctionOf` that only deals with proper `FunctionN` and `ContextFunctionN` types. This avoids some overhead. A difference between the two `unapply`s is that this one does not dealias the type, it needs to be dealiased at call site. Part of scala#18305
This makes it possible to know for example that if we have a `MethodType` and we use `derivedLambdaType` we get another `MethodType`. Part of #18305
9eb04f0
to
18114f0
Compare
Make `isJava` by default `false` and remove `dropLast` argument. Part of #18305. Note that the use of `toFunctionType` will increase, and most will not be java functions.
This provides variant to `defn.FunctionOf` that only deals with proper `FunctionN` and `ContextFunctionN` types. This avoids some overhead. A difference between the two `unapply`s is that this one does not dealias the type, it needs to be dealiased at call site. Part of scala#18305
18114f0
to
47eb542
Compare
The interpreter was dropping all arguments in the list if one of them was erased. Now we filter out only the erased arguments. Part of #18305
Add `FunctionTypeOfMethod` extractor that matches any kind of function and return its method type. We use this extractor instead of `ContextFunctionType` to all of * `ContextFunctionN[...]` * `ContextFunctionN[...] { def apply(using ...): R }` where `R` might be dependent on the parameters. * `PolyFunction { def apply(using ...): R }` where `R` might be dependent on the parameters. Currently this one would have at least one erased parameter. The naming of the extractor follows the idea in #18305 (comment).
This provides variant to `defn.FunctionOf` that only deals with proper `FunctionN` and `ContextFunctionN` types. This avoids some overhead. A difference between the two `unapply`s is that this one does not dealias the type, it needs to be dealiased at call site. Part of #18305
This provides variant to `defn.FunctionOf` that only deals with proper `FunctionN` and `ContextFunctionN` types. This avoids some overhead. A difference between the two `unapply`s is that this one does not dealias the type, it needs to be dealiased at call site. Part of #18305 [Cherry-picked d78c157][modified]
This fixes inconsistencies with refined dependent function types and poly functions representing methods with erased parameters.
This PR has many commits on purpose. These changes proved to be extremely fragile. Therefore it was decided that it would be better to do smaller incremental changes to be able to pinpoint any undetected regression in the future.The first commits reflect the code to split the logic into base abstractions for function types. These aim to remove ad-hoc behavior of function-type extractors and homogenize them. Once this was done, we moved towards representing function types homogeneously using
MethodType
s as their base representation. This representation is more robust as it forces us to consider dependent function types explicitly. Finally, some fixes were made where we did not handle function types correctly. Some todos are left where we could generalize to dependent function types, but this could go out of the bounds of the current spec for dependent function types (to be followed-up).