-
Notifications
You must be signed in to change notification settings - Fork 89
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
Add a subsumption rule between record types and dictionary types #1977
Changes from 2 commits
35ff633
abbbe1f
00a9537
c99634e
bb20fc9
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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2420,7 +2420,29 @@ pub fn subsumption( | |||||||||||
checked: UnifType, | ||||||||||||
) -> Result<(), UnifError> { | ||||||||||||
let inferred_inst = instantiate_foralls(state, &mut ctxt, inferred, ForallInst::UnifVar); | ||||||||||||
checked.unify(inferred_inst, state, &ctxt) | ||||||||||||
match (inferred_inst.clone(), checked.clone()) { | ||||||||||||
( | ||||||||||||
UnifType::Concrete { | ||||||||||||
typ: TypeF::Record(rrows), | ||||||||||||
.. | ||||||||||||
}, | ||||||||||||
UnifType::Concrete { | ||||||||||||
typ: TypeF::Dict { type_fields, .. }, | ||||||||||||
.. | ||||||||||||
}, | ||||||||||||
) => rrows.iter().fold( | ||||||||||||
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. If you don't build anything valuable in a fold, then you can probably get rid of it and just use a good old for row in rrows {
if let GenericUnifRecordRowsIteratorItem::Row(a) = row {
subsumption(state, ctxt.clone(), a.typ.clone(), *type_fields.clone())?;
}
}
Ok(()) |
||||||||||||
Ok(()), | ||||||||||||
|acc, row: GenericUnifRecordRowsIteratorItem<_>| -> Result<(), UnifError> { | ||||||||||||
match (row, &acc) { | ||||||||||||
(GenericUnifRecordRowsIteratorItem::Row(a), Ok(_)) => { | ||||||||||||
subsumption(state, ctxt.clone(), a.typ.clone(), *type_fields.clone()) | ||||||||||||
} | ||||||||||||
_ => acc, | ||||||||||||
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. Now I'm thinking about something that I haven't thought about before. During type inference, we might have open record types, such as If we try to subtype that with a dictionary, as in Interestingly, we can put Anyhow, I'm just thinking out loud. Let's forget that, for now, I don't think we can do better than closing the tail of the record. In practice, this means that we need to also consider the cases:
|
||||||||||||
} | ||||||||||||
}, | ||||||||||||
), | ||||||||||||
(_, _) => checked.unify(inferred_inst, state, &ctxt), | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
||||||||||||
fn check_field<V: TypecheckVisitor>( | ||||||||||||
|
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.
Those early clones are probably not needed. You might need to put a
ref
in the pattern matching though, as in: