Skip to content

Commit f933b16

Browse files
committed
use gen_get_tag
1 parent 8b89ebd commit f933b16

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

src/to_c.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ fn stmt_to_c(
14551455
wln!(
14561456
p,
14571457
"{};",
1458-
pat_to_cond(&lhs.node, &rhs_temp, None, locals, cg)
1458+
pat_to_cond(&lhs.node, &rhs_temp, rhs_ty, None, locals, cg)
14591459
);
14601460
if let Some(result_var) = result_var {
14611461
wln!(
@@ -1799,7 +1799,7 @@ fn expr_to_c(expr: &Expr, loc: &Loc, locals: &[LocalInfo], cg: &mut Cg, p: &mut
17991799
w!(p, " else ");
18001800
}
18011801
// Generate pattern match condition
1802-
let cond = pat_to_cond(&alt.pat.node, &scrut_temp, None, locals, cg);
1802+
let cond = pat_to_cond(&alt.pat.node, &scrut_temp, scrut_ty, None, locals, cg);
18031803
w!(p, "if ({}", cond);
18041804

18051805
// Add guard if present
@@ -1978,7 +1978,7 @@ fn expr_to_c(expr: &Expr, loc: &Loc, locals: &[LocalInfo], cg: &mut Cg, p: &mut
19781978
w!(
19791979
p,
19801980
"if ({}) {{",
1981-
pat_to_cond(&pat.node, &expr_temp, None, locals, cg)
1981+
pat_to_cond(&pat.node, &expr_temp, expr_ty, None, locals, cg)
19821982
);
19831983
p.indent();
19841984
p.nl();
@@ -2196,12 +2196,15 @@ fn gen_variant_conversion(
21962196
///
21972197
/// - `scrutinee` is the expression being matched against.
21982198
///
2199+
/// - `scrutinee_ty` is the type of the scrutinee (used for generating tag checks with `gen_get_tag`).
2200+
///
21992201
/// - `tag_expr` is an optional override for how to get the tag. When `Some`, use that expression
22002202
/// directly (e.g., for variant patterns where we check the variant's `_tag` field). When `None`,
2201-
/// derive the tag from the scrutinee using `get_tag(scrutinee)`.
2203+
/// derive the tag from the scrutinee using `gen_get_tag`.
22022204
fn pat_to_cond(
22032205
pat: &Pat,
22042206
scrutinee: &str,
2207+
scrutinee_ty: &mono::Type,
22052208
tag_expr: Option<&str>,
22062209
locals: &[LocalInfo],
22072210
cg: &mut Cg,
@@ -2224,12 +2227,23 @@ fn pat_to_cond(
22242227
let tag_name = heap_obj_tag_name(cg.pgm, *con);
22252228
let tag_check = match tag_expr {
22262229
Some(expr) => format!("({expr} == {tag_name})"),
2227-
None => format!("(get_tag({scrutinee}) == {tag_name})"),
2230+
None => {
2231+
let get_tag = gen_get_tag(cg.pgm, scrutinee, scrutinee_ty);
2232+
format!("({get_tag} == {tag_name})")
2233+
}
2234+
};
2235+
let field_tys: Vec<mono::Type> = match &cg.pgm.heap_objs[con.as_usize()] {
2236+
HeapObj::Source(source_con) => source_con.fields.clone(),
2237+
HeapObj::Record(record) => record.fields.values().cloned().collect(),
2238+
HeapObj::Builtin(_) => panic!("Builtin constructor {:?} in Pat::Con", con),
2239+
HeapObj::Variant(_) => panic!("Variant in Pat::Con"),
22282240
};
22292241
let mut cond = tag_check;
22302242
for (i, field_pat) in fields.iter().enumerate() {
22312243
let field_expr = format!("(({struct_name}*){scrutinee})->_{i}");
2232-
let field_cond = pat_to_cond(&field_pat.node, &field_expr, None, locals, cg);
2244+
let field_ty = &field_tys[i];
2245+
let field_cond =
2246+
pat_to_cond(&field_pat.node, &field_expr, field_ty, None, locals, cg);
22332247
cond = format!("({cond} && {field_cond})");
22342248
}
22352249
cond
@@ -2246,7 +2260,10 @@ fn pat_to_cond(
22462260
}
22472261
let tag_check = match tag_expr {
22482262
Some(expr) => format!("({expr} == {})", cg.pgm.str_con_idx.0),
2249-
None => format!("(get_tag({scrutinee}) == {})", cg.pgm.str_con_idx.0),
2263+
None => {
2264+
let get_tag = gen_get_tag(cg.pgm, scrutinee, scrutinee_ty);
2265+
format!("({get_tag} == {})", cg.pgm.str_con_idx.0)
2266+
}
22502267
};
22512268
format!(
22522269
"({tag_check} && str_eq((Str*){scrutinee}, \"{escaped}\", {}))",
@@ -2258,14 +2275,17 @@ fn pat_to_cond(
22582275
let tag_name = heap_obj_tag_name(cg.pgm, cg.pgm.char_con_idx);
22592276
let tag_check = match tag_expr {
22602277
Some(expr) => format!("({expr} == {tag_name})"),
2261-
None => format!("(get_tag({scrutinee}) == {tag_name})"),
2278+
None => {
2279+
let get_tag = gen_get_tag(cg.pgm, scrutinee, scrutinee_ty);
2280+
format!("({get_tag} == {tag_name})")
2281+
}
22622282
};
22632283
format!("({tag_check} && ((Char*){scrutinee})->_0 == {})", *c as u32)
22642284
}
22652285

22662286
Pat::Or(p1, p2) => {
2267-
let c1 = pat_to_cond(&p1.node, scrutinee, tag_expr, locals, cg);
2268-
let c2 = pat_to_cond(&p2.node, scrutinee, tag_expr, locals, cg);
2287+
let c1 = pat_to_cond(&p1.node, scrutinee, scrutinee_ty, tag_expr, locals, cg);
2288+
let c2 = pat_to_cond(&p2.node, scrutinee, scrutinee_ty, tag_expr, locals, cg);
22692289
format!("({c1} || {c2})")
22702290
}
22712291

@@ -2277,7 +2297,14 @@ fn pat_to_cond(
22772297
let alt_idx = find_variant_alt_index(pat_ty, variant_ty);
22782298
let inner_expr = format!("({scrutinee})._alt._{alt_idx}");
22792299
let variant_tag_expr = format!("({scrutinee})._tag");
2280-
pat_to_cond(&pat.node, &inner_expr, Some(&variant_tag_expr), locals, cg)
2300+
pat_to_cond(
2301+
&pat.node,
2302+
&inner_expr,
2303+
pat_ty,
2304+
Some(&variant_tag_expr),
2305+
locals,
2306+
cg,
2307+
)
22812308
}
22822309
}
22832310
}

0 commit comments

Comments
 (0)