mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 07:14:46 +00:00
Wrap content that is unwrapped and passes through a type alias correctly
Closes #2592
This commit is contained in:
parent
67658ed7b5
commit
4742847ba9
3 changed files with 55 additions and 2 deletions
|
@ -1862,6 +1862,14 @@ impl UnionTags {
|
||||||
slice.length == 1
|
slice.length == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_newtype_wrapper_of_global_tag(&self, subs: &Subs) -> bool {
|
||||||
|
self.is_newtype_wrapper(subs) && {
|
||||||
|
let tags = &subs.tag_names[self.tag_names().indices()];
|
||||||
|
debug_assert_eq!(tags.len(), 1);
|
||||||
|
matches!(tags[0], TagName::Global(_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_tag_name_index(index: SubsIndex<TagName>) -> Self {
|
pub fn from_tag_name_index(index: SubsIndex<TagName>) -> Self {
|
||||||
Self::from_slices(
|
Self::from_slices(
|
||||||
SubsSlice::new(index.index, 1),
|
SubsSlice::new(index.index, 1),
|
||||||
|
|
|
@ -70,6 +70,7 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum NewtypeKind<'a> {
|
enum NewtypeKind<'a> {
|
||||||
Tag(&'a TagName),
|
Tag(&'a TagName),
|
||||||
RecordField(&'a str),
|
RecordField(&'a str),
|
||||||
|
@ -89,10 +90,11 @@ fn unroll_newtypes<'a>(
|
||||||
mut content: &'a Content,
|
mut content: &'a Content,
|
||||||
) -> (Vec<'a, NewtypeKind<'a>>, &'a Content) {
|
) -> (Vec<'a, NewtypeKind<'a>>, &'a Content) {
|
||||||
let mut newtype_containers = Vec::with_capacity_in(1, env.arena);
|
let mut newtype_containers = Vec::with_capacity_in(1, env.arena);
|
||||||
|
let mut force_alias_content = None;
|
||||||
loop {
|
loop {
|
||||||
match content {
|
match content {
|
||||||
Content::Structure(FlatType::TagUnion(tags, _))
|
Content::Structure(FlatType::TagUnion(tags, _))
|
||||||
if tags.is_newtype_wrapper(env.subs) =>
|
if tags.is_newtype_wrapper_of_global_tag(env.subs) =>
|
||||||
{
|
{
|
||||||
let (tag_name, vars): (&TagName, &[Variable]) = tags
|
let (tag_name, vars): (&TagName, &[Variable]) = tags
|
||||||
.unsorted_iterator(env.subs, Variable::EMPTY_TAG_UNION)
|
.unsorted_iterator(env.subs, Variable::EMPTY_TAG_UNION)
|
||||||
|
@ -113,7 +115,20 @@ fn unroll_newtypes<'a>(
|
||||||
let field_var = *field.as_inner();
|
let field_var = *field.as_inner();
|
||||||
content = env.subs.get_content_without_compacting(field_var);
|
content = env.subs.get_content_without_compacting(field_var);
|
||||||
}
|
}
|
||||||
_ => return (newtype_containers, content),
|
Content::Alias(_, _, real_var) => {
|
||||||
|
// We need to pass through aliases too, because their underlying types may have
|
||||||
|
// unrolled newtypes. In such cases return the list of unrolled newtypes, but keep
|
||||||
|
// the content as the alias for readability. For example,
|
||||||
|
// T : { a : Str }
|
||||||
|
// v : T
|
||||||
|
// v = { a : "value" }
|
||||||
|
// v
|
||||||
|
// Here we need the newtype container to be `[RecordField(a)]`, but the content to
|
||||||
|
// remain as the alias `T`.
|
||||||
|
force_alias_content = Some(content);
|
||||||
|
content = env.subs.get_content_without_compacting(*real_var);
|
||||||
|
}
|
||||||
|
_ => return (newtype_containers, force_alias_content.unwrap_or(content)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -975,3 +975,33 @@ fn issue_2343_complete_mono_with_shadowed_vars() {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn record_with_type_behind_alias() {
|
||||||
|
expect_success(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
T : { a: Str }
|
||||||
|
v : T
|
||||||
|
v = { a: "value" }
|
||||||
|
v
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
r#"{ a: "value" } : T"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn tag_with_type_behind_alias() {
|
||||||
|
expect_success(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
T : [ A Str ]
|
||||||
|
v : T
|
||||||
|
v = A "value"
|
||||||
|
v
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
r#"A "value" : T"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue