diff options
Diffstat (limited to 'src/mir/cleanup.cpp')
| -rw-r--r-- | src/mir/cleanup.cpp | 40 | 
1 files changed, 40 insertions, 0 deletions
| diff --git a/src/mir/cleanup.cpp b/src/mir/cleanup.cpp index 49739e28..c5a8c5b9 100644 --- a/src/mir/cleanup.cpp +++ b/src/mir/cleanup.cpp @@ -692,6 +692,7 @@ void MIR_Cleanup_LValue(const ::MIR::TypeResolve& state, MirMutator& mutator, ::  void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path, ::MIR::Function& fcn, const ::HIR::Function::args_t& args, const ::HIR::TypeRef& ret_type)  {      Span    sp; +    TRACE_FUNCTION_F(path);      ::MIR::TypeResolve   state { sp, resolve, FMT_CB(ss, ss << path;), ret_type, args, fcn };      MirMutator  mutator { fcn, 0, 0 }; @@ -778,6 +779,45 @@ void MIR_Cleanup(const StaticTraitResolve& resolve, const ::HIR::ItemPath& path,                      )                  ) +                if( se.src.is_Borrow() && se.src.as_Borrow().val.is_Field() ) +                { +                    auto& e = se.src.as_Borrow(); +                    // TODO: If borrowing a !Sized value via a field access, create the DST +                    ::HIR::TypeRef  tmp; +                    const auto& src_ty = state.get_lvalue_type(tmp, e.val); +                     +                    if( !resolve.type_is_sized(sp, src_ty) && !src_ty.m_data.is_Generic() ) +                    { +                        auto ty_unit_ptr = ::HIR::TypeRef::new_borrow( e.type, ::HIR::TypeRef::new_unit() ); +                        if( se.dst.is_Temporary() && state.get_lvalue_type(tmp, se.dst) == ty_unit_ptr ) +                        { +                            // Assigning fat pointer to a &() temporary, only happens if this has already happend +                        } +                        else +                        { +                            // Unwrap field accesses, next lvalue should be a deref +                            const ::MIR::LValue* lv = &e.val; +                            while( lv->is_Field() ) +                                lv = &*lv->as_Field().val; +                            MIR_ASSERT(state, lv->is_Deref(), "Access of !Sized field not via a deref"); +                             +                            const auto& dst_val_lval = *lv; +                             +                            auto meta_rval = ::MIR::RValue::make_DstMeta({ dst_val_lval.clone() }); +                            // TODO: How can the thin pointer to the field be obtained without tripping this twice? +                            auto ptr_rval = mv$( se.src ); +                             +                            // TODO: Get the metadata type. +                            auto meta_ty = ::HIR::TypeRef( ::HIR::CoreType::Usize ); +                            auto meta_lval = mutator.in_temporary( mv$(meta_ty), mv$(meta_rval) ); +                             +                            // HACK: Store the pointer as &() +                            auto ptr_lval = mutator.in_temporary( mv$(ty_unit_ptr), mv$(ptr_rval) ); +                            se.src = ::MIR::RValue::make_MakeDst({ mv$(ptr_lval), mv$(meta_lval) }); +                        } +                    } +                } +                                  if( se.src.is_Cast() )                  {                      auto& e = se.src.as_Cast(); | 
