mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Merge pull request #3904 from roc-lang/fix-as-into-glue
Fix glue for into_ and as_ on single-tag unions
This commit is contained in:
commit
395105ae54
1 changed files with 82 additions and 29 deletions
|
@ -391,58 +391,111 @@ fn add_single_tag_struct(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
{
|
let mut args: Vec<String> = Vec::with_capacity(payload_fields.len());
|
||||||
let mut args: Vec<String> = Vec::with_capacity(payload_fields.len());
|
let mut fields: Vec<String> = Vec::with_capacity(payload_fields.len());
|
||||||
let mut fields: Vec<String> = Vec::with_capacity(payload_fields.len());
|
let mut field_types: Vec<String> = Vec::with_capacity(payload_fields.len());
|
||||||
|
let mut field_access: Vec<String> = Vec::with_capacity(payload_fields.len());
|
||||||
|
|
||||||
for (index, field_id) in payload_fields.iter().enumerate() {
|
for (index, field_id) in payload_fields.iter().enumerate() {
|
||||||
let field_type = type_name(*field_id, types);
|
let field_type = type_name(*field_id, types);
|
||||||
|
|
||||||
args.push(format!("f{index}: {field_type}"));
|
field_access.push(format!("self.f{index}"));
|
||||||
fields.push(format!("{INDENT}{INDENT}{INDENT}f{index},"));
|
args.push(format!("f{index}: {field_type}"));
|
||||||
}
|
fields.push(format!("{INDENT}{INDENT}{INDENT}f{index},"));
|
||||||
|
field_types.push(field_type);
|
||||||
|
}
|
||||||
|
|
||||||
let args = args.join(", ");
|
let args = args.join(", ");
|
||||||
let fields = fields.join("\n");
|
let fields = fields.join("\n");
|
||||||
|
|
||||||
add_decl(
|
add_decl(
|
||||||
impls,
|
impls,
|
||||||
opt_impl.clone(),
|
opt_impl.clone(),
|
||||||
target_info,
|
target_info,
|
||||||
format!(
|
format!(
|
||||||
r#"/// A tag named {tag_name}, with the given payload.
|
r#"/// A tag named {tag_name}, with the given payload.
|
||||||
pub fn {tag_name}({args}) -> Self {{
|
pub fn {tag_name}({args}) -> Self {{
|
||||||
Self {{
|
Self {{
|
||||||
{fields}
|
{fields}
|
||||||
}}
|
}}
|
||||||
}}"#,
|
}}"#,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
{
|
{
|
||||||
|
// Return a tuple
|
||||||
|
let ret_type = {
|
||||||
|
let joined = field_types.join(", ");
|
||||||
|
|
||||||
|
if field_types.len() == 1 {
|
||||||
|
joined
|
||||||
|
} else {
|
||||||
|
format!("({joined})")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let ret_expr = {
|
||||||
|
let joined = field_access.join(", ");
|
||||||
|
|
||||||
|
if field_access.len() == 1 {
|
||||||
|
joined
|
||||||
|
} else {
|
||||||
|
format!("({joined})")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
add_decl(
|
add_decl(
|
||||||
impls,
|
impls,
|
||||||
opt_impl.clone(),
|
opt_impl.clone(),
|
||||||
target_info,
|
target_info,
|
||||||
format!(
|
format!(
|
||||||
r#"/// Other `into_` methods return a payload, but since the {tag_name} tag
|
r#"/// Since `{tag_name}` only has one tag (namely, `{tag_name}`),
|
||||||
/// has no payload, this does nothing and is only here for completeness.
|
/// convert it to `{tag_name}`'s payload.
|
||||||
pub fn into_{tag_name}(self) {{
|
pub fn into_{tag_name}(self) -> {ret_type} {{
|
||||||
()
|
{ret_expr}
|
||||||
}}"#,
|
}}"#,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Return a tuple
|
||||||
|
let ret_type = {
|
||||||
|
let joined = field_types
|
||||||
|
.iter()
|
||||||
|
.map(|field_type| format!("&{field_type}"))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
if field_types.len() == 1 {
|
||||||
|
joined
|
||||||
|
} else {
|
||||||
|
format!("({joined})")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let ret_expr = {
|
||||||
|
let joined = field_access
|
||||||
|
.iter()
|
||||||
|
.map(|field| format!("&{field}"))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
if field_access.len() == 1 {
|
||||||
|
joined
|
||||||
|
} else {
|
||||||
|
format!("({joined})")
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
add_decl(
|
add_decl(
|
||||||
impls,
|
impls,
|
||||||
opt_impl,
|
opt_impl,
|
||||||
target_info,
|
target_info,
|
||||||
format!(
|
format!(
|
||||||
r#"/// Other `as` methods return a payload, but since the {tag_name} tag
|
r#"/// Since `{tag_name}` only has one tag (namely, `{tag_name}`),
|
||||||
/// has no payload, this does nothing and is only here for completeness.
|
/// convert it to `{tag_name}`'s payload.
|
||||||
pub fn as_{tag_name}(&self) {{
|
pub fn as_{tag_name}(&self) -> {ret_type} {{
|
||||||
()
|
{ret_expr}
|
||||||
}}"#,
|
}}"#,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue