@@ -101,6 +101,14 @@ pub enum TypeCheckError {
101
101
lhs : Type ,
102
102
rhs : Type ,
103
103
} ,
104
+ WriteWrongAddr {
105
+ addr : Type ,
106
+ tpe : Type ,
107
+ } ,
108
+ WriteWrongValue {
109
+ tpe : Type ,
110
+ value : Type ,
111
+ } ,
104
112
}
105
113
pub fn typecheck_err_to_string (
106
114
root_idx : super :: RootIdx ,
@@ -122,8 +130,8 @@ pub fn typecheck_err_to_string(
122
130
. collect ( ) ;
123
131
let root_string = root. display ( asm, sig, locals) ;
124
132
match root. typecheck ( sig, locals, asm) {
125
- Ok ( ok) => format ! ( "digraph G{{edge [dir=\" back\" ];\n {nodes} r{root_idx} [label = \" {root_string:? }\" color = \" green\" ] r{root_idx} ->{root_connections}}}" , root_idx = root_idx. as_bimap_index( ) ) ,
126
- Err ( err) => format ! ( "digraph G{{edge [dir=\" back\" ];\\ n{nodes} r{root_idx} [label = \" {root_string:? }\n {err:?}\" color = \" red\" ] r{root_idx} ->{root_connections}}}" , root_idx = root_idx. as_bimap_index( ) ) ,
133
+ Ok ( ok) => format ! ( "digraph G{{edge [dir=\" back\" ];\n {nodes} r{root_idx} [label = \" {root_string}\" color = \" green\" ] r{root_idx} ->{root_connections}}}" , root_idx = root_idx. as_bimap_index( ) ) ,
134
+ Err ( err) => format ! ( "digraph G{{edge [dir=\" back\" ];\\ n{nodes} r{root_idx} [label = \" {root_string}\n {err:?}\" color = \" red\" ] r{root_idx} ->{root_connections}}}" , root_idx = root_idx. as_bimap_index( ) ) ,
127
135
}
128
136
}
129
137
pub fn display_typecheck_err (
@@ -856,6 +864,33 @@ impl CILRoot {
856
864
Ok ( ( ) )
857
865
}
858
866
}
867
+ Self :: StInd ( boxed) => {
868
+ let ( addr, value, tpe, _) = boxed. as_ref ( ) ;
869
+ let addr = asm[ * addr] . clone ( ) . typecheck ( sig, locals, asm) ?;
870
+ let value = asm[ * value] . clone ( ) . typecheck ( sig, locals, asm) ?;
871
+ let Some ( addr_points_to) = addr. pointed_to ( ) . map ( |tpe| asm[ tpe] ) else {
872
+ return Err ( TypeCheckError :: WriteWrongAddr { addr, tpe : * tpe } ) ;
873
+ } ;
874
+ if !( tpe. is_assignable_to ( addr_points_to, asm)
875
+ || addr_points_to
876
+ . as_int ( )
877
+ . zip ( tpe. as_int ( ) )
878
+ . is_some_and ( |( a, b) | a. as_unsigned ( ) == b. as_unsigned ( ) )
879
+ || addr_points_to == Type :: Bool && * tpe == Type :: Int ( Int :: I8 ) )
880
+ {
881
+ return Err ( TypeCheckError :: WriteWrongAddr { addr, tpe : * tpe } ) ;
882
+ }
883
+ if !( value. is_assignable_to ( * tpe, asm)
884
+ || value
885
+ . as_int ( )
886
+ . zip ( tpe. as_int ( ) )
887
+ . is_some_and ( |( a, b) | a. as_unsigned ( ) == b. as_unsigned ( ) )
888
+ || value == Type :: Bool && * tpe == Type :: Int ( Int :: I8 ) )
889
+ {
890
+ return Err ( TypeCheckError :: WriteWrongValue { tpe : * tpe, value } ) ;
891
+ }
892
+ Ok ( ( ) )
893
+ }
859
894
_ => {
860
895
for node in self . nodes ( ) {
861
896
asm. get_node ( * node) . clone ( ) . typecheck ( sig, locals, asm) ?;
0 commit comments