-
Notifications
You must be signed in to change notification settings - Fork 39
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
internal: keep composite type-classes unresolved #864
internal: keep composite type-classes unresolved #864
Conversation
Instead of storing a fully instantiated meta-type (`tyGenericInst` containing type variables) in the last position of `tyCompositeTypeClass`, use a `tyGenericInvocation`. This removes the last usage of `semtypinst`'s "meta-types allowed" mode. Rendering of `tyCompositeTypeClass` (`typesrenderer`), their type- relation logic (`sigmatch`), and `inferWithMetatype` are adjusted to account for this change. Not skipping the first generic instance of a `tyCompositeTypeClass` in `typeRel` also fixes a type relation bug with generic types.
Invocations of parametric user-type classes not collapsed into `tyUserTypeClassInst` weren't properly considered and simply used the fall-through case. They're now special-cased in `tyGenericInvocation`s handling and support for passing `tyGenericInvocation`s (which is more or less identical to `tyUserTypeClassInst` in the case of `tyUserTypeClass`) is added to `matchUserTypeClass`.
In simple cases (e.g., `type Typ[T] = distinct T`), it should work the same as it did before, but in more complex cases, it likely doesn't.
Since the matching `tyCompositeTypeClass` doesn't skip the invocation/ instance anymore.
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.
The new behaviour where different generic types don't match makes sense, it's not very clear when we should use nominal vs structural matching and the nominal behaviour is a good default.
I'm really glad to see the meta types allowed mode being dropped. 🚀
/merge |
Merge requested by: @saem Contents after the first section break of the PR description has been removed and preserved below:
|
Summary
Change composite type-classes (
tyCompositeTypeClass
) to store anunresolved type application (
tyGenericInvocation
) instead of a fullyresolved and instantiated meta-type (
tyGenericInst
). This removes thelast usage of
semtypinst
's "meta-types allowed" mode, meaning thatthe latter can be removed now.
As part of the change, a type relation bug is fixed: generic
instantiations were incorrectly treated as having a 'generic'
relationship with composite type-classes of different generics that had
the same structure. For example,
A[int] is B
returned 'true' whenA[T] = (T,)
andB[T] = (T,)
.Details
tyCompositeTypeClass
liftParamType
), don't resolve the invocation liftedfrom the
tyGenericBody
, but instead store the invocation in thetyCompositeTypeClass
directlytypesrenderer
to render atyCompositeTypeClass
as theoriginal type expression (which is stored in the first slot)
tyCompositeTypeClass
when skipping them during
.borrow
handling, approximating howthe skipped type would have looked previously
Parametric aliases of parametric
concept
s(
concept
) withmatchUserTypeClass
typeRel
, dispatch tomatchUserTypeClass
when matching againstsuch invocations
Invocations of parametric
concept
s without arguments are lifted intotyUserTypeClassInst
instead oftyCompositeTypeClass
, but forparametric aliases of parametric
concept
s (e.g.,Type[T] = Concept[T]
where aConcept
is a parametric concept), thisis not case, meaning that
tyGenericInvocation
s where the body is atyUserTypeClass
reachtypeRel
.Parametric aliases of parametric
concept
s in the composite type-classcase were previously handled by way of them being resolved to
tyUserTypeClassInst
as part ofinstGenericContainer
, but without thelatter, they now need to be handled in
typeRel
, which is what changesdetailed above implement.
However, there is a problem. A
tyUserTypeClassInst
can bind typesfor later retrieval, while a
tyGenericInvocation
cannot. While asolution is going to be needed at some point, no user-facing regression
is introduced with the changes here, as
tyCompositeTypeClass
types inroutine signatures act as type variables (they're replaced with their
bound type during instantiation) and for conversions-to-composite-type-
classes (e.g.,
Generic(x)
), the type bound to the resolvedtyUserTypeClassInst
was already ignored previously.Type relation changes
The
typeRel
logic fortyCompositeTypeClass
is changed back to how itwas prior to e97d640, which is both
now-necessary (for proper matching against a
tyGenericInvocation
's)and fixes a type relation bug. By skipping the first instance, that
commit changed generic instantiation to be treated as having a 'generic'
relationship with different but structurally equal generic types, which
seems to have been an unintended side-effect. A test is added for the
fixed behaviour is added.
Coercions to distinct generic types are kept working by allowing generic
instances to be matched against the partially-resolved body of a
generic distinct type -- if
coerceDistincts
is 'false', the call totypeRel
withformal = tyDistinct
is going to returnisNone
.