@@ -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 `.
22022204fn 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