diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_expand/ufcs_everything.cpp | 2 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 62 | ||||
-rw-r--r-- | src/mir/from_hir_match.cpp | 1 |
3 files changed, 62 insertions, 3 deletions
diff --git a/src/hir_expand/ufcs_everything.cpp b/src/hir_expand/ufcs_everything.cpp index 0562c418..00e7eee1 100644 --- a/src/hir_expand/ufcs_everything.cpp +++ b/src/hir_expand/ufcs_everything.cpp @@ -615,6 +615,7 @@ namespace { m_replacement = NEWNODE( mv$(node.m_res_type), Deref, sp, mv$(m_replacement) ); } +#if 0 void visit(::HIR::ExprNode_Deref& node) override { const auto& sp = node.span(); @@ -693,6 +694,7 @@ namespace { // - Dereference the result (which is an &-ptr) m_replacement = NEWNODE( mv$(node.m_res_type), Deref, sp, mv$(m_replacement) ); } +#endif diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index df48627f..f3f8f745 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -58,6 +58,7 @@ namespace { const ScopeHandle* m_block_tmp_scope = nullptr; const ScopeHandle* m_borrow_raise_target = nullptr; + bool m_in_borrow = false; public: ExprVisitor_Conv(MirBuilder& builder, const ::std::vector< ::HIR::TypeRef>& var_types): @@ -1141,6 +1142,8 @@ namespace { { TRACE_FUNCTION_F("_Borrow"); + auto _ = save_and_edit(m_in_borrow, true); + const auto& ty_val = node.m_value->m_res_type; this->visit_node_ptr(node.m_value); auto val = m_builder.get_result_in_lvalue(node.m_value->span(), ty_val); @@ -1421,10 +1424,63 @@ namespace { if( m_builder.is_type_owned_box( ty_val ) ) { // Box magically derefs. - // HACK: Break out of the switch used for TU_MATCH_DEF - break; } - BUG(sp, "Deref on unsupported type - " << ty_val); + else + { + // TODO: Do operator replacement here after handling scope-raising for _Borrow + if( m_borrow_raise_target && m_in_borrow ) + { + DEBUG("- Raising deref in borrow to scope " << *m_borrow_raise_target); + m_builder.raise_variables(node.span(), val, *m_borrow_raise_target); + } + + + const char* langitem = nullptr; + const char* method = nullptr; + ::HIR::BorrowType bt; + // - Uses the value's usage beacuse for T: Copy node.m_value->m_usage is Borrow, but node.m_usage is Move + switch( node.m_value->m_usage ) + { + case ::HIR::ValueUsage::Unknown: + BUG(sp, "Unknown usage type of deref value"); + break; + case ::HIR::ValueUsage::Borrow: + bt = ::HIR::BorrowType::Shared; + langitem = method = "deref"; + break; + case ::HIR::ValueUsage::Mutate: + bt = ::HIR::BorrowType::Unique; + langitem = method = "deref_mut"; + break; + case ::HIR::ValueUsage::Move: + TODO(sp, "ValueUsage::Move for desugared Deref of " << node.m_value->m_res_type); + break; + } + // Needs replacement, continue + assert(langitem); + assert(method); + + // - Construct trait path - Index*<IdxTy> + auto method_path = ::HIR::Path(ty_val.clone(), ::HIR::GenericPath(m_builder.resolve().m_crate.get_lang_item_path(node.span(), langitem), {}), method); + + // Store a borrow of the input value + ::std::vector<::MIR::Param> args; + args.push_back( m_builder.lvalue_or_temp(sp, + ::HIR::TypeRef::new_borrow(bt, node.m_value->m_res_type.clone()), + ::MIR::RValue::make_Borrow({0, bt, mv$(val)}) + ) ); + m_builder.moved_lvalue(node.span(), args[0].as_LValue()); + val = m_builder.new_temporary(::HIR::TypeRef::new_borrow(bt, node.m_res_type.clone())); + // Call the above trait method + // Store result of that call in `val` (which will be derefed below) + auto ok_block = m_builder.new_bb_unlinked(); + auto panic_block = m_builder.new_bb_unlinked(); + m_builder.end_block(::MIR::Terminator::make_Call({ ok_block, panic_block, val.clone(), mv$(method_path), mv$(args) })); + m_builder.set_cur_block(panic_block); + m_builder.end_block(::MIR::Terminator::make_Diverge({})); + + m_builder.set_cur_block(ok_block); + } ), (Pointer, // Deref on a pointer - TODO: Requires unsafe diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index ecc8b6e6..2f248f10 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -1387,6 +1387,7 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa sub_builder.m_field_path.back() = 0; if( pe.trailing.size() ) { + // Needs a way of encoding the negative offset in the field path TODO(sp, "SplitSlice on [T] with trailing - " << pat); } auto trailing = mv$(sub_builder.m_rules); |