-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Compare types as capture sets in mergeRefinedOrApplied #23045
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
base: main
Are you sure you want to change the base?
Conversation
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 seems good and makes sense (pending the CI)! But I fail to see the connection to "capture sets" (a term used by the experimental capture checking feature) and suggest using a more appropriate title.
I used this title because I assumed that |
@@ -278,7 +278,7 @@ object TypeOps: | |||
} | |||
case AndType(tp11, tp12) => | |||
mergeRefinedOrApplied(tp11, tp2) & mergeRefinedOrApplied(tp12, tp2) | |||
case tp1: TypeParamRef if tp1 == tp2 => tp1 |
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.
=:=
uses TypeComparer
to check two types are equivalent (subtypes of each other), which is expensive and we need to be careful when using it.
The reason we have one TypeParamRef
and one TypeVar
is because we choose to widen tp1
in approximateOr
.
I would like to try the following:
case tp1: TypeParamRef =>
tp2.stripTypeVar match
case tp2: TypeParamRef if tp1 == tp2 => tp1
case _ => fail
case tp1: TypeVar =>
tp2 match
case tp2: TypeVar if tp1 == tp2 => tp1
case tp2: TypeParamRef if tp1.stripTypeVar == tp2 => tp2
case _ => fail
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.
Your suggested change works. I also decided to experiment with other solutions and found out that either adding the following case:
case tp1 if tp1.stripTypeVar == tp2.stripTypeVar => tp1
or applying the following patch
- case tp1: TypeParamRef if tp1 == tp2 => tp1
+ case tp1: TypeParamRef if tp1 == tp2.stripTypeVar => tp1
also fix the issue. So my questions are:
- Is it possible to hit
case tp1: TypeVar
branch? - is adding
.stripTypeVar
also a valid solution?
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.
case tp1: TypeVar
can be hit iftp1
isTypeVar
andtp2
isTypeParamRef
, although it may not happen here because the left branch of a union type is widened first inapproximateOr
if both sides widening succeed (see2.6
). Since the ordering is arbitary, I think it's better to cover all possibilities in case the algorithm is changed.- I would match a specific type (
TypeParamRef
andTypeVar
) beforestripTypeVar
, to avoid covering unintended types.
Related PR: #20090 |
Closes #23032.