diff options
author | John Hodge <tpg@mutabah.net> | 2016-12-10 10:11:20 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-12-10 10:11:20 +0800 |
commit | fa042b606fc09e69e10c5f31092935ea7067f391 (patch) | |
tree | 13d52794c1176b75760b4a752026bab773c676ab /src | |
parent | 138104dae328ca5f551d003e9c6c2426d7c58196 (diff) | |
download | mrust-fa042b606fc09e69e10c5f31092935ea7067f391.tar.gz |
MIR - Cast PhandomData fields when doing CoerceUnsized
Diffstat (limited to 'src')
-rw-r--r-- | src/hir_typeck/static.cpp | 18 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 3 | ||||
-rw-r--r-- | src/mir/cleanup.cpp | 33 | ||||
-rw-r--r-- | src/trans/codegen_c.cpp | 13 |
4 files changed, 59 insertions, 8 deletions
diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index b9a302a6..d1dbc42e 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -1382,3 +1382,21 @@ const ::HIR::TypeRef* StaticTraitResolve::is_type_owned_box(const ::HIR::TypeRef // TODO: Properly assert? return &pe.m_params.m_types.at(0); } +const ::HIR::TypeRef* StaticTraitResolve::is_type_phantom_data(const ::HIR::TypeRef& ty) const +{ + if( ! ty.m_data.is_Path() ) { + return nullptr; + } + const auto& te = ty.m_data.as_Path(); + + if( ! te.path.m_data.is_Generic() ) { + return nullptr; + } + const auto& pe = te.path.m_data.as_Generic(); + + if( pe.m_path != m_lang_PhantomData ) { + return nullptr; + } + // TODO: Properly assert? + return &pe.m_params.m_types.at(0); +} diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp index dd35df15..1fd1d51c 100644 --- a/src/hir_typeck/static.hpp +++ b/src/hir_typeck/static.hpp @@ -28,6 +28,7 @@ private: ::HIR::SimplePath m_lang_FnMut; ::HIR::SimplePath m_lang_FnOnce; ::HIR::SimplePath m_lang_Box; + ::HIR::SimplePath m_lang_PhantomData; public: StaticTraitResolve(const ::HIR::Crate& crate): @@ -41,6 +42,7 @@ public: m_lang_FnMut = m_crate.get_lang_item_path_opt("fn_mut"); m_lang_FnOnce = m_crate.get_lang_item_path_opt("fn_once"); m_lang_Box = m_crate.get_lang_item_path_opt("owned_box"); + m_lang_PhantomData = m_crate.get_lang_item_path_opt("phantom_data"); prep_indexes(); } @@ -170,5 +172,6 @@ public: bool type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) const; const ::HIR::TypeRef* is_type_owned_box(const ::HIR::TypeRef& ty) const; + const ::HIR::TypeRef* is_type_phantom_data(const ::HIR::TypeRef& ty) const; }; diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index 88096704..c2394adb 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -264,8 +264,16 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR auto ty_s = monomorphise_type_with(state.sp, se[i].ent, monomorph_cb_s, false); auto new_rval = MIR_Cleanup_CoerceUnsized(state, mutator, ty_d, ty_s, ::MIR::LValue::make_Field({ box$(value.clone()), i })); - auto new_lval = mutator.new_temporary( mv$(ty_d) ); - mutator.push_statement( ::MIR::Statement::make_Assign({ new_lval.clone(), mv$(new_rval) }) ); + auto new_lval = mutator.in_temporary( mv$(ty_d), mv$(new_rval) ); + + ents.push_back( mv$(new_lval) ); + } + else if( state.m_resolve.is_type_phantom_data( se[i].ent ) ) + { + auto ty_d = monomorphise_type_with(state.sp, se[i].ent, monomorph_cb_d, false); + + auto new_rval = ::MIR::RValue::make_Cast({ ::MIR::LValue::make_Field({ box$(value.clone()), i }), ty_d.clone() }); + auto new_lval = mutator.in_temporary( mv$(ty_d), mv$(new_rval) ); ents.push_back( mv$(new_lval) ); } @@ -279,7 +287,8 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR ents.reserve( se.size() ); for(unsigned int i = 0; i < se.size(); i++) { - if( i == str.m_markings.coerce_unsized_index ) { + if( i == str.m_markings.coerce_unsized_index ) + { auto ty_d = monomorphise_type_with(state.sp, se[i].second.ent, monomorph_cb_d, false); auto ty_s = monomorphise_type_with(state.sp, se[i].second.ent, monomorph_cb_s, false); @@ -289,7 +298,17 @@ const ::HIR::Literal* MIR_Cleanup_GetConstant(const Span& sp, const StaticTraitR ents.push_back( mv$(new_lval) ); } - else { + else if( state.m_resolve.is_type_phantom_data( se[i].second.ent ) ) + { + auto ty_d = monomorphise_type_with(state.sp, se[i].second.ent, monomorph_cb_d, false); + + auto new_rval = ::MIR::RValue::make_Cast({ ::MIR::LValue::make_Field({ box$(value.clone()), i }), ty_d.clone() }); + auto new_lval = mutator.in_temporary( mv$(ty_d), mv$(new_rval) ); + + ents.push_back( mv$(new_lval) ); + } + else + { ents.push_back( ::MIR::LValue::make_Field({ box$(value.clone()), i}) ); } } @@ -439,6 +458,12 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, // (&-ptr being destination is otherwise invalid) // TODO Share with the CoerceUnsized handling? ) + // Casts to PhantomData are only valid from PhandomData, and are added by _CoerceUnsized + else if( state.m_resolve.is_type_phantom_data(e.type) ) + { + // Leave + MIR_ASSERT(state, state.m_resolve.is_type_phantom_data(src_ty) != nullptr, "PhandomData can only cast from PhantomData"); + } // - CoerceUnsized should re-create the inner type if known. else TU_IFLET( ::HIR::TypeRef::Data, e.type.m_data, Path, te, TU_IFLET( ::HIR::TypeRef::Data, src_ty.m_data, Path, ste, diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 37c96a83..1a0ba042 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -425,6 +425,11 @@ namespace { } ), (Cast, + if( m_resolve.is_type_phantom_data(ve.type) ) { + m_of << "/* PhandomData cast */\n"; + continue ; + } + emit_lvalue(e.dst); m_of << " = "; m_of << "("; emit_ctype(ve.type); m_of << ")"; @@ -758,10 +763,10 @@ namespace { m_of << " " << inner; ), (Path, - if( const auto* ity = m_resolve.is_type_owned_box(ty) ) { - emit_ctype_ptr(*ity, inner); - return ; - } + //if( const auto* ity = m_resolve.is_type_owned_box(ty) ) { + // emit_ctype_ptr(*ity, inner); + // return ; + //} TU_MATCHA( (te.binding), (tpb), (Struct, m_of << "struct s_" << Trans_Mangle(te.path); |