mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
fix double sorting in record layout
This commit is contained in:
parent
ff505f695c
commit
3ca2140b69
1 changed files with 15 additions and 41 deletions
|
@ -1209,11 +1209,22 @@ fn layout_from_flat_type<'a>(
|
|||
}
|
||||
Record(fields, ext_var) => {
|
||||
// extract any values from the ext_var
|
||||
// TODO short-circuit the sorting here
|
||||
let fields_map: MutMap<_, _> = fields.sorted_iterator(subs, ext_var).collect();
|
||||
|
||||
// discard optional fields
|
||||
let mut layouts = sort_stored_record_fields(env, fields_map);
|
||||
let variables = fields
|
||||
.sorted_iterator(subs, ext_var)
|
||||
.filter_map(|(_, field)| {
|
||||
// drop optional fields
|
||||
match field {
|
||||
RecordField::Optional(_) => None,
|
||||
RecordField::Required(var) => Some(var),
|
||||
RecordField::Demanded(var) => Some(var),
|
||||
}
|
||||
});
|
||||
|
||||
let layouts_it =
|
||||
variables.map(|var| Layout::from_var(env, var).expect("invalid layout from var"));
|
||||
|
||||
let mut layouts = Vec::from_iter_in(layouts_it, arena);
|
||||
|
||||
if layouts.len() == 1 {
|
||||
// If the record has only one field that isn't zero-sized,
|
||||
|
@ -1392,43 +1403,6 @@ fn sort_record_fields_help<'a>(
|
|||
sorted_fields
|
||||
}
|
||||
|
||||
// drops optional fields
|
||||
fn sort_stored_record_fields<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
fields_map: MutMap<Lowercase, RecordField<Variable>>,
|
||||
) -> Vec<'a, Layout<'a>> {
|
||||
// Sort the fields by label
|
||||
let mut sorted_fields = Vec::with_capacity_in(fields_map.len(), env.arena);
|
||||
|
||||
for (label, field) in fields_map {
|
||||
let var = match field {
|
||||
RecordField::Demanded(v) => v,
|
||||
RecordField::Required(v) => v,
|
||||
RecordField::Optional(_) => {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let layout = Layout::from_var(env, var).expect("invalid layout from var");
|
||||
|
||||
sorted_fields.push((label, layout));
|
||||
}
|
||||
|
||||
sorted_fields.sort_by(|(label1, layout1), (label2, layout2)| {
|
||||
let ptr_bytes = 8;
|
||||
|
||||
let size1 = layout1.alignment_bytes(ptr_bytes);
|
||||
let size2 = layout2.alignment_bytes(ptr_bytes);
|
||||
|
||||
size2.cmp(&size1).then(label1.cmp(label2))
|
||||
});
|
||||
|
||||
let mut result = Vec::with_capacity_in(sorted_fields.len(), env.arena);
|
||||
result.extend(sorted_fields.into_iter().map(|t| t.1));
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum UnionVariant<'a> {
|
||||
Never,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue