diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mir/from_hir.cpp | 67 | ||||
-rw-r--r-- | src/mir/from_hir.hpp | 1 | ||||
-rw-r--r-- | src/mir/mir.hpp | 2 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 6 |
4 files changed, 69 insertions, 7 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 6d801007..b21c8fc5 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -107,10 +107,23 @@ namespace { } ), (Slice, - TODO(sp, "Destructure using " << pat); + for(const auto& subpat : e.sub_patterns) + { + define_vars_from(sp, subpat); + } ), (SplitSlice, - TODO(sp, "Destructure using " << pat); + for(const auto& subpat : e.leading) + { + define_vars_from(sp, subpat); + } + if( e.extra_bind.is_valid() ) { + m_builder.define_variable( e.extra_bind.m_slot ); + } + for(const auto& subpat : e.trailing) + { + define_vars_from(sp, subpat); + } ) ) } @@ -155,7 +168,7 @@ namespace { (Any, ), (Box, - TODO(sp, "Destructure using " << pat); + TODO(sp, "Destructure using Box - " << pat); ), (Ref, destructure_from_ex(sp, *e.sub, ::MIR::LValue::make_Deref({ box$( mv$(lval) ) }), allow_refutable); @@ -217,12 +230,52 @@ namespace { } ), (Slice, - ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected - " << pat); - TODO(sp, "Destructure using " << pat); + // These are only refutable if T is [T] + bool ty_is_array = false; + m_builder.with_val_type(sp, lval, [&ty_is_array](const auto& ty){ + ty_is_array = ty.m_data.is_Array(); + }); + if( ty_is_array ) + { + // TODO: Assert array size + for(unsigned int i = 0; i < e.sub_patterns.size(); i ++) + { + const auto& subpat = e.sub_patterns[i]; + destructure_from_ex(sp, subpat, ::MIR::LValue::make_Field({ box$(lval.clone()), i }), allow_refutable ); + } + } + else + { + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected - " << pat); + TODO(sp, "Destructure slice using " << pat); + } ), (SplitSlice, - ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected - " << pat); - TODO(sp, "Destructure using " << pat); + // These are only refutable if T is [T] + bool ty_is_array = false; + m_builder.with_val_type(sp, lval, [&ty_is_array](const auto& ty){ + ty_is_array = ty.m_data.is_Array(); + }); + if( ty_is_array ) + { + // TODO: Assert array size + //for(unsigned int i = 0; i < e.leading.size(); i ++) + //{ + // auto idx = 0 + i; + // destructure_from_ex(sp, e.leading[i], ::MIR::LValue::make_Index({ box$( lval.clone() ), box$(lval_idx) }), allow_refutable ); + //} + //for(unsigned int i = 0; i < e.trailing.size(); i ++) + //{ + // auto idx = 0 + i; + // destructure_from_ex(sp, e.leading[i], ::MIR::LValue::make_Index({ box$( lval.clone() ), box$(lval_idx) }), allow_refutable ); + //} + TODO(sp, "Destructure array using SplitSlice - " << pat); + } + else + { + ASSERT_BUG(sp, allow_refutable, "Refutable pattern not expected - " << pat); + TODO(sp, "Destructure slice using SplitSlice - " << pat); + } ) ) } diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index 39890bbf..7e48971f 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -186,6 +186,7 @@ private: void drop_scope_values(const ScopeDef& sd); void complete_scope(ScopeDef& sd); +public: void with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::function<void(const ::HIR::TypeRef&)> cb); bool lvalue_is_copy(const Span& sp, const ::MIR::LValue& lv); }; diff --git a/src/mir/mir.hpp b/src/mir/mir.hpp index 39113acb..c030cc37 100644 --- a/src/mir/mir.hpp +++ b/src/mir/mir.hpp @@ -33,6 +33,7 @@ TAGGED_UNION_EX(LValue, (), Variable, ( // Function return (Return, struct{}), // Field access (tuple, struct, tuple struct, enum field, ...) + // NOTE: Also used to index an array/slice by a compile-time known index (e.g. in destructuring) (Field, struct { ::std::unique_ptr<LValue> val; unsigned int field_index; @@ -42,6 +43,7 @@ TAGGED_UNION_EX(LValue, (), Variable, ( ::std::unique_ptr<LValue> val; }), // Index an array or slice (typeof(val) == [T; n] or [T]) + // NOTE: This is not bounds checked! (Index, struct { ::std::unique_ptr<LValue> val; ::std::unique_ptr<LValue> idx; diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index c5564045..386bd338 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -684,6 +684,12 @@ void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std:: ( BUG(sp, "Field access on unexpected type - " << ty); ), + (Array, + cb( *te.inner ); + ), + (Slice, + cb( *te.inner ); + ), (Path, ASSERT_BUG(sp, te.binding.is_Struct(), "Field on non-Struct - " << ty); const auto& str = *te.binding.as_Struct(); |