mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Merge pull request #2259 from rtfeldman/i/2227-record-layout-hang
Turn invalid record field types into runtime errors
This commit is contained in:
commit
db44d03e66
10 changed files with 162 additions and 65 deletions
|
@ -519,7 +519,8 @@ fn write_flat_type(env: &Env, flat_type: &FlatType, subs: &Subs, buf: &mut Strin
|
|||
let RecordStructure {
|
||||
fields: sorted_fields,
|
||||
ext,
|
||||
} = gather_fields(subs, *fields, *ext_var);
|
||||
} = gather_fields(subs, *fields, *ext_var)
|
||||
.expect("Something ended up weird in this record type");
|
||||
let ext_var = ext;
|
||||
|
||||
if fields.is_empty() {
|
||||
|
|
|
@ -2010,7 +2010,8 @@ impl RecordFields {
|
|||
subs: &'a Subs,
|
||||
ext: Variable,
|
||||
) -> impl Iterator<Item = (&Lowercase, RecordField<Variable>)> + 'a {
|
||||
let (it, _) = crate::types::gather_fields_unsorted_iter(subs, *self, ext);
|
||||
let (it, _) = crate::types::gather_fields_unsorted_iter(subs, *self, ext)
|
||||
.expect("Something weird ended up in a record type");
|
||||
|
||||
it
|
||||
}
|
||||
|
@ -2045,7 +2046,8 @@ impl RecordFields {
|
|||
ext,
|
||||
)
|
||||
} else {
|
||||
let record_structure = crate::types::gather_fields(subs, *self, ext);
|
||||
let record_structure = crate::types::gather_fields(subs, *self, ext)
|
||||
.expect("Something ended up weird in this record type");
|
||||
|
||||
(
|
||||
Box::new(record_structure.fields.into_iter()),
|
||||
|
|
|
@ -1701,14 +1701,20 @@ pub fn name_type_var(letters_used: u32, taken: &mut MutSet<Lowercase>) -> (Lower
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct RecordFieldsError;
|
||||
|
||||
pub fn gather_fields_unsorted_iter(
|
||||
subs: &Subs,
|
||||
other_fields: RecordFields,
|
||||
mut var: Variable,
|
||||
) -> (
|
||||
impl Iterator<Item = (&Lowercase, RecordField<Variable>)> + '_,
|
||||
Variable,
|
||||
) {
|
||||
) -> Result<
|
||||
(
|
||||
impl Iterator<Item = (&Lowercase, RecordField<Variable>)> + '_,
|
||||
Variable,
|
||||
),
|
||||
RecordFieldsError,
|
||||
> {
|
||||
use crate::subs::Content::*;
|
||||
use crate::subs::FlatType::*;
|
||||
|
||||
|
@ -1733,7 +1739,7 @@ pub fn gather_fields_unsorted_iter(
|
|||
// TODO investigate apparently this one pops up in the reporting tests!
|
||||
RigidVar(_) => break,
|
||||
|
||||
other => unreachable!("something weird ended up in a record type: {:?}", other),
|
||||
_ => return Err(RecordFieldsError),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1749,11 +1755,15 @@ pub fn gather_fields_unsorted_iter(
|
|||
(field_name, record_field)
|
||||
});
|
||||
|
||||
(it, var)
|
||||
Ok((it, var))
|
||||
}
|
||||
|
||||
pub fn gather_fields(subs: &Subs, other_fields: RecordFields, var: Variable) -> RecordStructure {
|
||||
let (it, ext) = gather_fields_unsorted_iter(subs, other_fields, var);
|
||||
pub fn gather_fields(
|
||||
subs: &Subs,
|
||||
other_fields: RecordFields,
|
||||
var: Variable,
|
||||
) -> Result<RecordStructure, RecordFieldsError> {
|
||||
let (it, ext) = gather_fields_unsorted_iter(subs, other_fields, var)?;
|
||||
|
||||
let mut result: Vec<_> = it
|
||||
.map(|(ref_label, field)| (ref_label.clone(), field))
|
||||
|
@ -1761,10 +1771,10 @@ pub fn gather_fields(subs: &Subs, other_fields: RecordFields, var: Variable) ->
|
|||
|
||||
result.sort_by(|(a, _), (b, _)| a.cmp(b));
|
||||
|
||||
RecordStructure {
|
||||
Ok(RecordStructure {
|
||||
fields: result,
|
||||
ext,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn gather_tags_unsorted_iter(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue