summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mir/from_hir.cpp24
-rw-r--r--src/mir/from_hir.hpp3
-rw-r--r--src/mir/mir_builder.cpp25
3 files changed, 49 insertions, 3 deletions
diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp
index 4a540c14..5a0ca03a 100644
--- a/src/mir/from_hir.cpp
+++ b/src/mir/from_hir.cpp
@@ -929,7 +929,13 @@ namespace {
}
else
{
- TODO(node.span(), "Support emitting CoerceUnsized-based _Unsize ops in MIR - " << ty_in << " -> " << ty_out);
+ // NOTES: (from IRC: eddyb)
+ // < eddyb> they're required that T and U are the same struct definition (with different type parameters) and exactly one field differs in type between T and U (ignoring PhantomData)
+ // < eddyb> Mutabah: I forgot to mention that the field that differs in type must also impl CoerceUnsized
+
+ // TODO: Just emit a cast and leave magic handling to codegen
+ // - This code _could_ do inspection of the types and insert a destructure+unsize+restructure, but that does't handle direct `T: CoerceUnsize<U>`
+ m_builder.set_result( node.span(), ::MIR::RValue::make_Cast({ mv$(ptr_lval), node.m_res_type.clone() }) );
}
}
void visit(::HIR::ExprNode_Index& node) override
@@ -1002,13 +1008,25 @@ namespace {
TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_val.m_data), (te),
(
+ if( m_builder.lang_Box() )
+ {
+ if( ty_val.m_data.is_Path()
+ && ty_val.m_data.as_Path().path.m_data.is_Generic()
+ && ty_val.m_data.as_Path().path.m_data.as_Generic().m_path == *m_builder.lang_Box()
+ )
+ {
+ // Box magically derefs.
+ // HACK: Break out of the switch used for TU_MATCH_DEF
+ break;
+ }
+ }
BUG(sp, "Deref on unsupported type - " << ty_val);
),
- //(Array,
- // ),
(Pointer,
+ // Deref on a pointer - TODO: Requires unsafe
),
(Borrow,
+ // Deref on a borrow - Always valid... assuming borrowck is there :)
)
)
diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp
index c5106bd0..1f9007a5 100644
--- a/src/mir/from_hir.hpp
+++ b/src/mir/from_hir.hpp
@@ -78,6 +78,8 @@ class MirBuilder
const ::HIR::Function::args_t& m_args;
::MIR::Function& m_output;
+ const ::HIR::SimplePath* m_lang_Box;
+
unsigned int m_current_block;
bool m_block_active;
@@ -111,6 +113,7 @@ public:
MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const ::HIR::Function::args_t& args, ::MIR::Function& output);
~MirBuilder();
+ const ::HIR::SimplePath* lang_Box() const { return m_lang_Box; }
const ::HIR::Crate& crate() const { return m_resolve.m_crate; }
// - Values
diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp
index 89141042..eb40f58b 100644
--- a/src/mir/mir_builder.cpp
+++ b/src/mir/mir_builder.cpp
@@ -16,10 +16,15 @@ MirBuilder::MirBuilder(const Span& sp, const StaticTraitResolve& resolve, const
m_resolve(resolve),
m_args(args),
m_output(output),
+ m_lang_Box(nullptr),
m_block_active(false),
m_result_valid(false),
m_fcn_scope(*this, 0)
{
+ if( resolve.m_crate.m_lang_items.count("owned_box") > 0 ) {
+ m_lang_Box = &resolve.m_crate.m_lang_items.at("owned_box");
+ }
+
set_cur_block( new_bb_unlinked() );
m_scopes.push_back( ScopeDef { sp } );
m_scope_stack.push_back( 0 );
@@ -652,6 +657,25 @@ void MirBuilder::with_val_type(const Span& sp, const ::MIR::LValue& val, ::std::
(
BUG(sp, "Deref on unexpected type - " << ty);
),
+ (Path,
+ if( m_lang_Box )
+ {
+ TU_IFLET( ::HIR::Path::Data, te.path.m_data, Generic, e,
+ if( e.m_path == *m_lang_Box ) {
+ cb( e.m_params.m_types.at(0) );
+ }
+ else {
+ BUG(sp, "Deref on unexpected type - " << ty);
+ }
+ )
+ else {
+ BUG(sp, "Deref on unexpected type - " << ty);
+ }
+ }
+ else {
+ BUG(sp, "Deref on unexpected type - " << ty);
+ }
+ ),
(Pointer,
cb(*te.inner);
),
@@ -910,6 +934,7 @@ void MirBuilder::moved_lvalue(const Span& sp, const ::MIR::LValue& lv)
if( lvalue_is_copy(sp, lv) ) {
}
else {
+ // TODO: Move out of owned_box _is_ valid, and marks the box slot for shallow drop
BUG(sp, "Move out of deref with non-Copy values - &move? - " << lv);
moved_lvalue(sp, *e.val);
}