diff options
Diffstat (limited to 'src/mir/check.cpp')
-rw-r--r-- | src/mir/check.cpp | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/src/mir/check.cpp b/src/mir/check.cpp index 186e93fb..0c428c64 100644 --- a/src/mir/check.cpp +++ b/src/mir/check.cpp @@ -14,6 +14,7 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, const ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type) { + TRACE_FUNCTION_F(path); Span sp; ::MIR::TypeResolve state { sp, resolve, FMT_CB(ss, ss << path;), ret_type, args, fcn }; // Validation rules: @@ -107,6 +108,14 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path { } + bool operator==(const ValStates& x) const { + if( ret_state != x.ret_state ) return false; + if( arguments != x.arguments ) return false; + if( temporaries != x.temporaries ) return false; + if( variables != x.variables ) return false; + return true; + } + bool empty() const { return arguments.empty() && temporaries.empty() && variables.empty(); } @@ -221,6 +230,15 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path }; ::std::vector< ValStates> block_start_states( fcn.blocks.size() ); ::std::vector< ::std::pair<unsigned int, ValStates> > to_visit_blocks; + + auto add_to_visit = [&](auto idx, auto vs) { + for(const auto& b : to_visit_blocks) + if( b.first == idx && b.second == vs) + return ; + if( block_start_states.at(idx) == vs ) + return ; + to_visit_blocks.push_back( ::std::make_pair(idx, mv$(vs)) ); + }; to_visit_blocks.push_back( ::std::make_pair(0, ValStates{ args.size(), fcn.temporaries.size(), fcn.named_variables.size() }) ); while( to_visit_blocks.size() > 0 ) { @@ -265,7 +283,9 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path val_state.ensure_valid(state, se.val); ), (Cast, - val_state.move_val(state, se.val); + // Well.. it's not exactly moved... + val_state.ensure_valid(state, se.val); + //val_state.move_val(state, se.val); ), (BinOp, val_state.move_val(state, se.val_l); @@ -335,21 +355,35 @@ void MIR_Validate(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path ), (Goto, // Push block with the new state - to_visit_blocks.push_back( ::std::make_pair(e, ::std::move(val_state)) ); + add_to_visit( e, mv$(val_state) ); ), (Panic, // What should be done here? ), (If, // Push blocks - to_visit_blocks.push_back( ::std::make_pair(e.bb0, val_state) ); - to_visit_blocks.push_back( ::std::make_pair(e.bb1, ::std::move(val_state)) ); + val_state.ensure_valid( state, e.cond ); + add_to_visit( e.bb0, val_state ); + add_to_visit( e.bb1, mv$(val_state) ); ), (Switch, - // TODO: Push blocks + val_state.ensure_valid( state, e.val ); + for(const auto& tgt : e.targets) + { + add_to_visit( tgt, val_state ); + } ), (Call, - // TODO: Push blocks (with return valid only in one) + if( e.fcn.is_Value() ) + val_state.ensure_valid( state, e.fcn.as_Value() ); + for(const auto& arg : e.args) + val_state.ensure_valid( state, arg ); + // Push blocks (with return valid only in one) + add_to_visit(e.panic_block, val_state); + + // TODO: If the function returns !, don't follow the ret_block + val_state.mark_validity( state, e.ret_val, true ); + add_to_visit(e.ret_block, mv$(val_state)); ) ) } |