diff options
author | John Hodge <tpg@mutabah.net> | 2018-12-27 18:35:54 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2018-12-27 18:35:54 +0800 |
commit | a0bdedaaed4393236877c45bb56692fe05732a56 (patch) | |
tree | fc9914af26382287fdb09e5a3ce8fde4c37da92d | |
parent | 0132d377f8a8e41bf6c92d8461855d7a8febcf10 (diff) | |
download | mrust-a0bdedaaed4393236877c45bb56692fe05732a56.tar.gz |
Lower MIR - Match ergonomics (and a little bit of cleanup/fixes).
- liballoc building, up to libstd
-rw-r--r-- | src/hir/pattern.cpp | 3 | ||||
-rw-r--r-- | src/hir/pattern.hpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 4 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 136 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 2 |
6 files changed, 90 insertions, 59 deletions
diff --git a/src/hir/pattern.cpp b/src/hir/pattern.cpp index da6446d7..a86dbfa7 100644 --- a/src/hir/pattern.cpp +++ b/src/hir/pattern.cpp @@ -46,6 +46,9 @@ namespace HIR { if( x.m_binding.is_valid() ) { os << x.m_binding; } + if( x.m_implicit_deref_count > 0 ) { + os << "&*" << x.m_implicit_deref_count; + } TU_MATCH(Pattern::Data, (x.m_data), (e), (Any, os << "_"; diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index d190db5a..b17ebcb4 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -136,7 +136,7 @@ struct Pattern PatternBinding m_binding; Data m_data; - unsigned m_implicit_deref_count; + unsigned m_implicit_deref_count = 0; Pattern() {} Pattern(PatternBinding pb, Data d): diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 8df54be5..739d0f8b 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -3858,6 +3858,10 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T } TU_ARM(pattern.m_data, Value, pe) { // no-op? + if( pe.val.is_String() ) { + ASSERT_BUG(sp, pattern.m_implicit_deref_count >= 1, ""); + pattern.m_implicit_deref_count -= 1; + } rv = true; } TU_ARM(pattern.m_data, Range, pe) { diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 78ba9024..c3281bd6 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1782,7 +1782,7 @@ namespace { m_builder.end_block(::MIR::Terminator::make_Call({ cast__ok, cast__panic, res.clone(), ::MIR::CallTarget::make_Intrinsic({ "transmute", mv$(transmute_params) }), - {} + make_vec1( ::MIR::Param( mv$(place) ) ) })); m_builder.set_cur_block(cast__panic); m_builder.end_block( ::MIR::Terminator::make_Diverge({}) ); // HACK m_builder.set_cur_block(cast__ok); diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index b8fabdc0..8014ea8e 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -886,9 +886,10 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal ) ) } -void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pat, const ::HIR::TypeRef& ty) +void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pat, const ::HIR::TypeRef& top_ty) { - TRACE_FUNCTION_F("pat="<<pat<<", ty="<<ty<<", m_field_path=[" << m_field_path << "]"); + static ::HIR::Pattern empty_pattern; + TRACE_FUNCTION_F("pat="<<pat<<", ty="<<top_ty<<", m_field_path=[" << m_field_path << "]"); struct H { static uint64_t get_pattern_value_int(const Span& sp, const ::HIR::Pattern& pat, const ::HIR::Pattern::Value& val) { TU_MATCH_DEF( ::HIR::Pattern::Value, (val), (e), @@ -922,6 +923,16 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa } }; + const auto* ty_p = &top_ty; + for(size_t i = 0; i < pat.m_implicit_deref_count; i ++) + { + if( !ty_p->m_data.is_Borrow() ) + BUG(sp, "Deref step " << i << "/" << pat.m_implicit_deref_count << " hit a non-borrow " << *ty_p << " from " << top_ty); + ty_p = &*ty_p->m_data.as_Borrow().inner; + m_field_path.push_back( FIELD_DEREF ); + } + const auto& ty = *ty_p; + // TODO: Outer handling for Value::Named patterns // - Convert them into either a pattern, or just a variant of this function that operates on ::HIR::Literal // > It does need a way of handling unknown-value constants (e.g. <GenericT as Foo>::CONST) @@ -931,6 +942,10 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa if( pve.binding ) { this->append_from_lit(sp, pve.binding->m_value_res, ty); + for(size_t i = 0; i < pat.m_implicit_deref_count; i ++) + { + m_field_path.pop_back(); + } return ; } else @@ -940,20 +955,23 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa ) ) - TU_MATCHA( (ty.m_data), (e), - (Infer, BUG(sp, "Ivar for in match type"); ), - (Diverge, + TU_MATCH_HDR( (ty.m_data), {) + TU_ARM(ty.m_data, Infer, e) { + BUG(sp, "Ivar for in match type"); + } + TU_ARM(ty.m_data, Diverge, e) { // Since ! can never exist, mark this arm as impossible. // TODO: Marking as impossible (and not emitting) leads to exhuaustiveness failure. //this->m_is_impossible = true; - ), - (Primitive, - TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (pe), - ( BUG(sp, "Matching primitive with invalid pattern - " << pat); ), - (Any, + } + TU_ARM(ty.m_data, Primitive, e) { + TU_MATCH_HDR( (pat.m_data), {) + default: + BUG(sp, "Matching primitive with invalid pattern - " << pat); + TU_ARM(pat.m_data, Any, pe) { this->push_rule( PatternRule::make_Any({}) ); - ), - (Range, + } + TU_ARM(pat.m_data, Range, pe) { switch(e) { case ::HIR::CoreType::F32: @@ -994,8 +1012,8 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa BUG(sp, "Hit match over `str` - must be `&str`"); break; } - ), - (Value, + } + TU_ARM(pat.m_data, Value, pe) { switch(e) { case ::HIR::CoreType::F32: @@ -1035,16 +1053,16 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa BUG(sp, "Hit match over `str` - must be `&str`"); break; } - ) - ) - ), - (Tuple, + } + } + } + TU_ARM(ty.m_data, Tuple, e) { m_field_path.push_back(0); TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (pe), ( BUG(sp, "Matching tuple with invalid pattern - " << pat); ), (Any, for(const auto& sty : e) { - this->append_from(sp, pat, sty); + this->append_from(sp, empty_pattern, sty); m_field_path.back() ++; } ), @@ -1070,8 +1088,8 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa ) ) m_field_path.pop_back(); - ), - (Path, + } + TU_ARM(ty.m_data, Path, e) { // This is either a struct destructure or an enum TU_MATCHA( (e.binding), (pbe), (Unbound, @@ -1132,12 +1150,12 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa TU_MATCH_DEF( ::HIR::Pattern::Data, (pat.m_data), (pe), ( BUG(sp, "Match not allowed, " << ty << " with " << pat); ), (Any, - // - Recurse into type and use the same pattern again + // - Recurse into type using an empty pattern for(const auto& fld : sd) { ::HIR::TypeRef tmp; const auto& sty_mono = (monomorphise_type_needed(fld.ent) ? tmp = monomorph(fld.ent) : fld.ent); - this->append_from(sp, pat, sty_mono); + this->append_from(sp, empty_pattern, sty_mono); m_field_path.back() ++; } ), @@ -1166,7 +1184,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa { ::HIR::TypeRef tmp; const auto& sty_mono = (monomorphise_type_needed(fld.second.ent) ? tmp = monomorph(fld.second.ent) : fld.second.ent); - this->append_from(sp, pat, sty_mono); + this->append_from(sp, empty_pattern, sty_mono); m_field_path.back() ++; } m_field_path.pop_back(); @@ -1182,8 +1200,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa auto it = ::std::find_if( pe.sub_patterns.begin(), pe.sub_patterns.end(), [&](const auto& x){ return x.first == fld.first; } ); if( it == pe.sub_patterns.end() ) { - ::HIR::Pattern any_pat {}; - this->append_from(sp, any_pat, sty_mono); + this->append_from(sp, empty_pattern, sty_mono); } else { @@ -1289,8 +1306,8 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa ) ) ) - ), - (Generic, + } + TU_ARM(ty.m_data, Generic, e) { // Generics don't destructure, so the only valid pattern is `_` TU_MATCH_DEF( ::HIR::Pattern::Data, (pat.m_data), (pe), ( BUG(sp, "Match not allowed, " << ty << " with " << pat); ), @@ -1298,29 +1315,29 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa this->push_rule( PatternRule::make_Any({}) ); ) ) - ), - (TraitObject, + } + TU_ARM(ty.m_data, TraitObject, e) { if( pat.m_data.is_Any() ) { } else { ERROR(sp, E0000, "Attempting to match over a trait object"); } - ), - (ErasedType, + } + TU_ARM(ty.m_data, ErasedType, e) { if( pat.m_data.is_Any() ) { } else { ERROR(sp, E0000, "Attempting to match over an erased type"); } - ), - (Array, + } + TU_ARM(ty.m_data, Array, e) { // Sequential match just like tuples. m_field_path.push_back(0); TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (pe), ( BUG(sp, "Matching array with invalid pattern - " << pat); ), (Any, for(unsigned int i = 0; i < e.size_val; i ++) { - this->append_from(sp, pat, *e.inner); + this->append_from(sp, empty_pattern, *e.inner); m_field_path.back() ++; } ), @@ -1336,8 +1353,8 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa ) ) m_field_path.pop_back(); - ), - (Slice, + } + TU_ARM(ty.m_data, Slice, e) { TU_MATCH_DEF(::HIR::Pattern::Data, (pat.m_data), (pe), ( BUG(sp, "Matching over [T] with invalid pattern - " << pat); @@ -1393,18 +1410,19 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa }) ); ) ) - ), - (Borrow, + } + TU_ARM(ty.m_data, Borrow, e) { m_field_path.push_back( FIELD_DEREF ); - TU_MATCH_DEF( ::HIR::Pattern::Data, (pat.m_data), (pe), - ( BUG(sp, "Matching borrow invalid pattern - " << pat); ), - (Any, - this->append_from( sp, pat, *e.inner ); - ), - (Ref, + TU_MATCH_HDR( (pat.m_data), {) + default: + BUG(sp, "Matching borrow invalid pattern - " << ty << " with " << pat); + TU_ARM(pat.m_data, Any, pe) { + this->append_from( sp, empty_pattern, *e.inner ); + } + TU_ARM(pat.m_data, Ref, pe) { this->append_from( sp, *pe.sub, *e.inner ); - ), - (Value, + } + TU_ARM(pat.m_data, Value, pe) { // TODO: Check type? if( pe.val.is_String() ) { const auto& s = pe.val.as_String(); @@ -1423,32 +1441,36 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa else { BUG(sp, "Matching borrow invalid pattern - " << pat); } - ) - ) + } + } m_field_path.pop_back(); - ), - (Pointer, + } + TU_ARM(ty.m_data, Pointer, e) { if( pat.m_data.is_Any() ) { } else { ERROR(sp, E0000, "Attempting to match over a pointer"); } - ), - (Function, + } + TU_ARM(ty.m_data, Function, e) { if( pat.m_data.is_Any() ) { } else { ERROR(sp, E0000, "Attempting to match over a functon pointer"); } - ), - (Closure, + } + TU_ARM(ty.m_data, Closure, e) { if( pat.m_data.is_Any() ) { } else { ERROR(sp, E0000, "Attempting to match over a closure"); } - ) - ) + } + } + for(size_t i = 0; i < pat.m_implicit_deref_count; i ++) + { + m_field_path.pop_back(); + } } namespace { diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index 3e14ce66..a3650919 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -397,6 +397,7 @@ void MirBuilder::push_stmt(const Span& sp, ::MIR::Statement stmt) void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst) { VarState* state_p = nullptr; + // TODO: Tracking of complex asignment states (e.g. assignment of a field) TU_MATCH_DEF(::MIR::LValue, (dst), (e), ( ), @@ -420,6 +421,7 @@ void MirBuilder::mark_value_assigned(const Span& sp, const ::MIR::LValue& dst) drop_value_from_state(sp, *state_p, dst.clone()); *state_p = VarState::make_Valid({}); } + // TODO: What about assigning into non-tracked locations? Should still cause a drop } void MirBuilder::raise_temporaries(const Span& sp, const ::MIR::LValue& val, const ScopeHandle& scope, bool to_above/*=false*/) |