@@ -1730,6 +1730,25 @@ fn tag_variants(@crate_ctxt cx, ast.def_id id) -> vec[ast.variant] {
1730
1730
fail; // not reached
1731
1731
}
1732
1732
1733
+ // Returns the tag variant with the given ID.
1734
+ fn tag_variant_with_id( @crate_ctxt cx,
1735
+ & ast. def_id tag_id,
1736
+ & ast. def_id variant_id) -> ast. variant {
1737
+ auto variants = tag_variants( cx, tag_id) ;
1738
+
1739
+ auto i = 0 u;
1740
+ while ( i < _vec. len[ ast. variant] ( variants) ) {
1741
+ auto variant = variants. ( i) ;
1742
+ if ( common. def_eq( variant. id, variant_id) ) {
1743
+ ret variant;
1744
+ }
1745
+ i += 1 u;
1746
+ }
1747
+
1748
+ log "tag_variant_with_id(): no variant exists with that ID" ;
1749
+ fail;
1750
+ }
1751
+
1733
1752
// Returns a new plain tag type of the given ID with no type parameters. Don't
1734
1753
// use this function in new code; it's a hack to keep things working for now.
1735
1754
fn mk_plain_tag( ast. def_id tid) -> @ty. t {
@@ -2909,23 +2928,6 @@ fn trans_do_while(@block_ctxt cx, &ast.block body,
2909
2928
2910
2929
// Pattern matching translation
2911
2930
2912
- // Returns a pointer to the union part of the LLVM representation of a tag
2913
- // type, cast to the appropriate type.
2914
- fn get_pat_union_ptr( @block_ctxt cx, vec[ @ast. pat] subpats, ValueRef llval)
2915
- -> ValueRef {
2916
- auto llblobptr = cx. build. GEP ( llval, vec( C_int ( 0 ) , C_int ( 1 ) ) ) ;
2917
-
2918
- // Generate the union type.
2919
- let vec[ TypeRef ] llsubpattys = vec( ) ;
2920
- for ( @ast. pat subpat in subpats) {
2921
- llsubpattys += vec( type_of( cx. fcx. ccx, pat_ty( subpat) ) ) ;
2922
- }
2923
-
2924
- // Recursively check subpatterns.
2925
- auto llunionty = T_struct ( llsubpattys) ;
2926
- ret cx. build. TruncOrBitCast ( llblobptr, T_ptr ( llunionty) ) ;
2927
- }
2928
-
2929
2931
fn trans_pat_match( @block_ctxt cx, @ast. pat pat, ValueRef llval,
2930
2932
@block_ctxt next_cx) -> result {
2931
2933
alt ( pat. node) {
@@ -2943,7 +2945,11 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
2943
2945
}
2944
2946
2945
2947
case ( ast. pat_tag( ?id, ?subpats, ?vdef_opt, ?ann) ) {
2946
- auto lldiscrimptr = cx. build. GEP ( llval, vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
2948
+ auto lltagptr = cx. build. PointerCast ( llval,
2949
+ T_opaque_tag_ptr ( cx. fcx. ccx. tn) ) ;
2950
+
2951
+ auto lldiscrimptr = cx. build. GEP ( lltagptr,
2952
+ vec( C_int ( 0 ) , C_int ( 0 ) ) ) ;
2947
2953
auto lldiscrim = cx. build. Load ( lldiscrimptr) ;
2948
2954
2949
2955
auto vdef = option. get[ ast. variant_def] ( vdef_opt) ;
@@ -2968,13 +2974,15 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval,
2968
2974
cx. build. CondBr ( lleq, matched_cx. llbb, next_cx. llbb) ;
2969
2975
2970
2976
if ( _vec. len[ @ast. pat] ( subpats) > 0 u) {
2971
- auto llunionptr = get_pat_union_ptr ( matched_cx, subpats ,
2972
- llval ) ;
2977
+ auto llblobptr = matched_cx. build . GEP ( lltagptr ,
2978
+ vec ( C_int ( 0 ) , C_int ( 1 ) ) ) ;
2973
2979
auto i = 0 ;
2974
2980
for ( @ast. pat subpat in subpats) {
2975
- auto llsubvalptr = matched_cx. build. GEP ( llunionptr,
2976
- vec( C_int ( 0 ) ,
2977
- C_int ( i) ) ) ;
2981
+ auto rslt = GEP_tag ( matched_cx, llblobptr, variants. ( i) ,
2982
+ i) ;
2983
+ auto llsubvalptr = rslt. val;
2984
+ matched_cx = rslt. bcx;
2985
+
2978
2986
auto llsubval = load_scalar_or_boxed( matched_cx,
2979
2987
llsubvalptr,
2980
2988
pat_ty( subpat) ) ;
@@ -2998,25 +3006,35 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
2998
3006
case ( ast. pat_lit( _, _) ) { ret res( cx, llval) ; }
2999
3007
case ( ast. pat_bind( ?id, ?def_id, ?ann) ) {
3000
3008
auto ty = node_ann_type( cx. fcx. ccx, ann) ;
3001
- auto llty = type_of( cx. fcx. ccx, ty) ;
3002
3009
3003
- auto dst = cx. build. Alloca ( llty) ;
3010
+ auto rslt = alloc_ty( cx, ty) ;
3011
+ auto dst = rslt. val;
3012
+ auto bcx = rslt. bcx;
3013
+
3004
3014
llvm. LLVMSetValueName ( dst, _str. buf( id) ) ;
3005
- cx . fcx. lllocals. insert( def_id, dst) ;
3006
- cx . cleanups += clean( bind drop_slot( _, dst, ty) ) ;
3015
+ bcx . fcx. lllocals. insert( def_id, dst) ;
3016
+ bcx . cleanups += clean( bind drop_slot( _, dst, ty) ) ;
3007
3017
3008
- ret copy_ty( cx , INIT , dst, llval, ty) ;
3018
+ ret copy_ty( bcx , INIT , dst, llval, ty) ;
3009
3019
}
3010
- case ( ast. pat_tag( _, ?subpats, _ , _) ) {
3020
+ case ( ast. pat_tag( _, ?subpats, ?vdef_opt , _) ) {
3011
3021
if ( _vec. len[ @ast. pat] ( subpats) == 0 u) { ret res( cx, llval) ; }
3012
3022
3013
- auto llunionptr = get_pat_union_ptr( cx, subpats, llval) ;
3023
+ // Get the appropriate variant for this tag.
3024
+ auto vdef = option. get[ ast. variant_def] ( vdef_opt) ;
3025
+ auto variant = tag_variant_with_id( cx. fcx. ccx, vdef. _0, vdef. _1) ;
3026
+
3027
+ auto lltagptr = cx. build. PointerCast ( llval,
3028
+ T_opaque_tag_ptr ( cx. fcx. ccx. tn) ) ;
3029
+ auto llblobptr = cx. build. GEP ( lltagptr, vec( C_int ( 0 ) , C_int ( 1 ) ) ) ;
3014
3030
3015
3031
auto this_cx = cx;
3016
3032
auto i = 0 ;
3017
3033
for ( @ast. pat subpat in subpats) {
3018
- auto llsubvalptr = this_cx. build. GEP ( llunionptr,
3019
- vec( C_int ( 0 ) , C_int ( i) ) ) ;
3034
+ auto rslt = GEP_tag ( this_cx, llblobptr, variant, i) ;
3035
+ this_cx = rslt. bcx;
3036
+ auto llsubvalptr = rslt. val;
3037
+
3020
3038
auto llsubval = load_scalar_or_boxed( this_cx, llsubvalptr,
3021
3039
pat_ty( subpat) ) ;
3022
3040
auto subpat_res = trans_pat_binding( this_cx, subpat,
0 commit comments