summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mir/from_hir.cpp67
-rw-r--r--src/mir/from_hir.hpp1
-rw-r--r--src/mir/mir.hpp2
-rw-r--r--src/mir/mir_builder.cpp6
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();