summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-12-10 10:11:20 +0800
committerJohn Hodge <tpg@mutabah.net>2016-12-10 10:11:20 +0800
commitfa042b606fc09e69e10c5f31092935ea7067f391 (patch)
tree13d52794c1176b75760b4a752026bab773c676ab /src
parent138104dae328ca5f551d003e9c6c2426d7c58196 (diff)
downloadmrust-fa042b606fc09e69e10c5f31092935ea7067f391.tar.gz
MIR - Cast PhandomData fields when doing CoerceUnsized
Diffstat (limited to 'src')
-rw-r--r--src/hir_typeck/static.cpp18
-rw-r--r--src/hir_typeck/static.hpp3
-rw-r--r--src/mir/cleanup.cpp33
-rw-r--r--src/trans/codegen_c.cpp13
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);