summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hir_expand/annotate_value_usage.cpp5
-rw-r--r--src/hir_typeck/expr_cs.cpp31
-rw-r--r--src/mir/from_hir.cpp4
3 files changed, 32 insertions, 8 deletions
diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp
index fe511f21..0650e52c 100644
--- a/src/hir_expand/annotate_value_usage.cpp
+++ b/src/hir_expand/annotate_value_usage.cpp
@@ -369,8 +369,9 @@ namespace {
return ::HIR::ValueUsage::Borrow;
),
(Box,
- TODO(sp, "Box");
- //return get_usage_for_pattern(sp, *pe.inner, [&](const auto&){ if(tmp == ::HIR::TypeRef()) tmp = m_resolve.deref_type(sp, get_ty()); return tmp; });
+ // NOTE: Specific to `owned_box`
+ const auto& sty = ty.m_data.as_Path().path.m_data.as_Generic().m_params.m_types.at(0);
+ return get_usage_for_pattern(sp, *pe.sub, sty);
),
(Ref,
return get_usage_for_pattern(sp, *pe.sub, *ty.m_data.as_Borrow().inner);
diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp
index 482c95c6..aba57f61 100644
--- a/src/hir_typeck/expr_cs.cpp
+++ b/src/hir_typeck/expr_cs.cpp
@@ -104,9 +104,12 @@ struct Context
::std::vector< IVarPossible> possible_ivar_vals;
+ const ::HIR::SimplePath m_lang_Box;
+
Context(const ::HIR::Crate& crate, const ::HIR::GenericParams* impl_params, const ::HIR::GenericParams* item_params):
m_crate(crate),
- m_resolve(m_ivars, crate, impl_params, item_params)
+ m_resolve(m_ivars, crate, impl_params, item_params),
+ m_lang_Box( crate.get_lang_item_path_opt("owned_box") )
{
}
@@ -2180,7 +2183,7 @@ namespace {
// HACK: Add a possibility of the result type being ``Box<`data_ty`>``
// - This only happens if the `owned_box` lang item is present and this node is a `box` operation
- const auto& lang_Boxed = this->context.m_crate.get_lang_item_path_opt("owned_box");
+ const auto& lang_Boxed = this->context.m_lang_Box;
if( ! lang_Boxed.m_components.empty() && node_ty == ::HIR::ExprNode_Emplace::Type::Boxer )
{
// NOTE: `owned_box` shouldn't point to anything but a struct
@@ -2589,7 +2592,7 @@ namespace {
const auto& box_ty = this->context.get_type(node_ptr->m_res_type);
TU_IFLET(::HIR::TypeRef::Data, box_ty.m_data, Path, e,
TU_IFLET(::HIR::Path::Data, e.path.m_data, Generic, pe,
- if( pe.m_path == this->context.m_crate.get_lang_item_path(sp, "owned_box") ) {
+ if( pe.m_path == context.m_lang_Box ) {
}
else {
ERROR(sp, E0000, "Calling Box receiver method on non-box - " << box_ty);
@@ -3253,7 +3256,27 @@ void Context::add_binding(const Span& sp, ::HIR::Pattern& pat, const ::HIR::Type
H::handle_value(*this, sp, type, e.end);
),
(Box,
- TODO(sp, "Box pattern");
+ if( m_lang_Box == ::HIR::SimplePath() )
+ ERROR(sp, E0000, "Use of `box` pattern without the `owned_box` lang item");
+ const auto& ty = this->get_type(type);
+ // Two options:
+ // 1. Enforce that the current type must be "owned_box"
+ // 2. Make a new ivar for the inner and emit an associated type bound on Deref
+
+ // Taking option 1 for now
+ TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Path, te,
+ if( te.path.m_data.is_Generic() && te.path.m_data.as_Generic().m_path == m_lang_Box ) {
+ // Box<T>
+ const auto& inner = te.path.m_data.as_Generic().m_params.m_types.at(0);
+ this->add_binding(sp, *e.sub, inner);
+ break ;
+ }
+ )
+
+ auto inner = this->m_ivars.new_ivar_tr();
+ this->add_binding(sp, *e.sub, inner);
+ ::HIR::GenericPath path { m_lang_Box, ::HIR::PathParams(mv$(inner)) };
+ this->equate_types( sp, type, ::HIR::TypeRef::new_path(mv$(path), ::HIR::TypeRef::TypePathBinding(&m_crate.get_struct_by_path(sp, m_lang_Box))) );
),
(Ref,
const auto& ty = this->get_type(type);
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 27c7d4cf..80915304 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -57,7 +57,7 @@ namespace {
(Any,
),
(Box,
- TODO(sp, "Destructure using " << pat);
+ define_vars_from(sp, *e.sub);
),
(Ref,
define_vars_from(sp, *e.sub);
@@ -168,7 +168,7 @@ namespace {
(Any,
),
(Box,
- TODO(sp, "Destructure using Box - " << pat);
+ destructure_from_ex(sp, *e.sub, ::MIR::LValue::make_Deref({ box$( mv$(lval) ) }), allow_refutable);
),
(Ref,
destructure_from_ex(sp, *e.sub, ::MIR::LValue::make_Deref({ box$( mv$(lval) ) }), allow_refutable);