diff options
author | John Hodge <tpg@mutabah.net> | 2016-08-23 17:32:29 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-08-23 17:32:29 +0800 |
commit | c2aedab7b60ca3e6c293b7d022897aee0661db21 (patch) | |
tree | c8de400dc1a7d30726d7e7f56c63ac82416a3775 /src | |
parent | 6cf05070d793f95e051046f0a301f6e006bebb50 (diff) | |
download | mrust-c2aedab7b60ca3e6c293b7d022897aee0661db21.tar.gz |
HIR Typecheck - Require span for type_is_copy
Diffstat (limited to 'src')
-rw-r--r-- | src/hir/hir.cpp | 17 | ||||
-rw-r--r-- | src/hir/hir.hpp | 2 | ||||
-rw-r--r-- | src/hir_expand/annotate_value_usage.cpp | 11 | ||||
-rw-r--r-- | src/hir_expand/closures.cpp | 13 | ||||
-rw-r--r-- | src/hir_typeck/static.cpp | 209 | ||||
-rw-r--r-- | src/hir_typeck/static.hpp | 9 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 4 | ||||
-rw-r--r-- | src/mir/from_hir.hpp | 4 | ||||
-rw-r--r-- | src/mir/mir_builder.cpp | 77 |
9 files changed, 187 insertions, 159 deletions
diff --git a/src/hir/hir.cpp b/src/hir/hir.cpp index 3b69e7c2..0b77c022 100644 --- a/src/hir/hir.cpp +++ b/src/hir/hir.cpp @@ -183,6 +183,23 @@ namespace { } } +//::HIR::TypeRef HIR::Function::make_ty(const Span& sp, const ::HIR::PathParams& params) const +//{ +// // TODO: Obtain function type for this function (i.e. a type that is specifically for this function) +// auto fcn_ty_data = ::HIR::FunctionType { +// m_is_unsafe, +// m_abi, +// box$( monomorphise_type(sp, m_params, params, m_return) ), +// {} +// }; +// fcn_ty_data.m_arg_types.reserve( m_args.size() ); +// for(const auto& arg : m_args) +// { +// fcn_ty_data.m_arg_types.push_back( monomorphise_type(sp, m_params, params, arg.second) ); +// } +// return ::HIR::TypeRef( mv$(fcn_ty_data) ); +//} + bool ::HIR::TraitImpl::matches_type(const ::HIR::TypeRef& type, ::HIR::t_cb_resolve_type ty_res) const { return matches_type_int(m_params, m_type, type, ty_res, true); diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index d2a3631b..1eeb5f2f 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -97,6 +97,8 @@ public: TypeRef m_return; ExprPtr m_code; + + //::HIR::TypeRef make_ty(const Span& sp, const ::HIR::PathParams& params) const; }; // -------------------------------------------------------------------- diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 0d8bf891..139814ef 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -215,7 +215,7 @@ namespace { void visit(::HIR::ExprNode_Index& node) override { // TODO: Override to ::Borrow if Res: Copy and moving - if( this->get_usage() == ::HIR::ValueUsage::Move && type_is_copy(node.m_res_type) ) { + if( this->get_usage() == ::HIR::ValueUsage::Move && m_resolve.type_is_copy(node.span(), node.m_res_type) ) { auto _ = push_usage( ::HIR::ValueUsage::Borrow ); this->visit_node_ptr(node.m_value); } @@ -228,7 +228,7 @@ namespace { } void visit(::HIR::ExprNode_Deref& node) override { - if( this->get_usage() == ::HIR::ValueUsage::Move && type_is_copy(node.m_res_type) ) { + if( this->get_usage() == ::HIR::ValueUsage::Move && m_resolve.type_is_copy(node.span(), node.m_res_type) ) { auto _ = push_usage( ::HIR::ValueUsage::Borrow ); this->visit_node_ptr(node.m_value); } @@ -240,7 +240,7 @@ namespace { void visit(::HIR::ExprNode_Field& node) override { // If taking this field by value, but the type is Copy - pretend it's a borrow. - if( this->get_usage() == ::HIR::ValueUsage::Move && type_is_copy(node.m_res_type) ) { + if( this->get_usage() == ::HIR::ValueUsage::Move && m_resolve.type_is_copy(node.span(), node.m_res_type) ) { auto _ = push_usage( ::HIR::ValueUsage::Borrow ); this->visit_node_ptr(node.m_value); } @@ -336,11 +336,6 @@ namespace { // TODO: Detect if a by-value binding exists for a non-Copy type return ::HIR::ValueUsage::Move; } - - bool type_is_copy(const ::HIR::TypeRef& ty) const - { - return m_resolve.type_is_copy(ty); - } }; diff --git a/src/hir_expand/closures.cpp b/src/hir_expand/closures.cpp index a6246a2c..df123dd0 100644 --- a/src/hir_expand/closures.cpp +++ b/src/hir_expand/closures.cpp @@ -550,7 +550,7 @@ namespace { { if( !m_closure_stack.empty() ) { - mark_used_variable(node.m_slot, node.m_usage); + mark_used_variable(node.span(), node.m_slot, node.m_usage); } ::HIR::ExprVisitorDef::visit(node); } @@ -589,11 +589,6 @@ namespace { } private: - bool type_is_copy(const ::HIR::TypeRef& ty) const - { - return m_resolve.type_is_copy(ty); - } - void add_closure_def(unsigned int slot) { assert(m_closure_stack.size() > 0); @@ -677,7 +672,7 @@ namespace { ) ) } - void mark_used_variable(unsigned int slot, ::HIR::ValueUsage usage) + void mark_used_variable(const Span& sp, unsigned int slot, ::HIR::ValueUsage usage) { //for(const auto& closure_rec : m_closure_stack) //{ @@ -702,7 +697,7 @@ namespace { switch( usage ) { case ::HIR::ValueUsage::Unknown: - BUG(Span(), "Unknown usage of variable " << slot); + BUG(sp, "Unknown usage of variable " << slot); case ::HIR::ValueUsage::Borrow: closure.m_class = ::std::max(closure.m_class, ::HIR::ExprNode_Closure::Class::Shared); break; @@ -710,7 +705,7 @@ namespace { closure.m_class = ::std::max(closure.m_class, ::HIR::ExprNode_Closure::Class::Mut); break; case ::HIR::ValueUsage::Move: - if( type_is_copy( m_variable_types.at(slot) ) ) { + if( m_resolve.type_is_copy( sp, m_variable_types.at(slot) ) ) { closure.m_class = ::std::max(closure.m_class, ::HIR::ExprNode_Closure::Class::Shared); } else { diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index ea411a24..786531d8 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -91,6 +91,42 @@ bool StaticTraitResolve::find_impl( TRACE_FUNCTION_F(trait_path << FMT_CB(os, if(trait_params) { os << *trait_params; } else { os << "<?>"; }) << " for " << type); auto cb_ident = [](const auto&ty)->const auto&{return ty;}; + if( trait_path == m_lang_Copy ) { + if( this->type_is_copy(sp, type) ) { + static ::HIR::PathParams null_params; + static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc; + return found_cb( ImplRef(&type, &null_params, &null_assoc) ); + } + } + + bool ret; + + // TODO: A bound can imply something via its associated types. How deep can this go? + // E.g. `T: IntoIterator<Item=&u8>` implies `<T as IntoIterator>::IntoIter : Iterator<Item=&u8>` + ret = this->iterate_bounds([&](const auto& b) { + return this->find_impl__check_bound(sp, trait_path, trait_params, type, found_cb, b); + }); + if(ret) + return true; + + // Search the crate for impls + ret = m_crate.find_trait_impls(trait_path, type, cb_ident, [&](const auto& impl) { + return this->find_impl__check_crate(sp, trait_path, trait_params, type, found_cb, impl); + }); + if(ret) + return true; + + return false; +} + +bool StaticTraitResolve::find_impl__check_bound( + const Span& sp, + const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, + const ::HIR::TypeRef& type, + t_cb_find_impl found_cb, + const ::HIR::GenericBound& bound + ) const +{ struct H { static bool compare_pp(const Span& sp, const ::HIR::PathParams& left, const ::HIR::PathParams& right) { ASSERT_BUG( sp, left.m_types.size() == right.m_types.size(), "Parameter count mismatch" ); @@ -102,6 +138,14 @@ bool StaticTraitResolve::find_impl( return true; } }; + + // Can only get good information out of TraitBound + if( !bound.is_TraitBound() ) { + return false; + } + const auto& e = bound.as_TraitBound(); + + // Obtain a pointer to UfcsKnown for magic later const ::HIR::Path::Data::Data_UfcsKnown* assoc_info = nullptr; TU_IFLET(::HIR::TypeRef::Data, type.m_data, Path, e, TU_IFLET(::HIR::Path::Data, e.path.m_data, UfcsKnown, pe, @@ -109,105 +153,75 @@ bool StaticTraitResolve::find_impl( ) ) - if( trait_path == m_lang_Copy ) { - if( this->type_is_copy(type) ) { - static ::HIR::PathParams null_params; - static ::std::map< ::std::string, ::HIR::TypeRef> null_assoc; - return found_cb( ImplRef(&type, &null_params, &null_assoc) ); + const auto& b_params = e.trait.m_path.m_params; + DEBUG("(bound) - " << e.type << " : " << e.trait); + if( e.type == type ) + { + if( e.trait.m_path.m_path == trait_path ) { + // Check against `params` + if( trait_params ) { + DEBUG("Checking " << *trait_params << " vs " << b_params); + if( !H::compare_pp(sp, *trait_params, b_params) ) + return false; + } + // Hand off to the closure, and return true if it does + if( found_cb(ImplRef(&e.type, &e.trait.m_path.m_params, &e.trait.m_type_bounds)) ) { + return true; + } + } + // HACK: The wrapping closure takes associated types from this bound and applies them to the returned set + // - XXX: This is actually wrong (false-positive) in many cases. FIXME + bool rv = this->find_named_trait_in_trait(sp, + trait_path,b_params, + *e.trait.m_trait_ptr, e.trait.m_path.m_path,e.trait.m_path.m_params, + type, + [&](const auto& params, auto assoc) { + for(const auto& i : e.trait.m_type_bounds) { + // TODO: Only include from above when needed + //if( des_trait_ref.m_types.count(i.first) ) { + assoc.insert( ::std::make_pair(i.first, i.second.clone()) ); + //} + } + return found_cb( ImplRef(type.clone(), params.clone(), mv$(assoc)) ); + }); + if( rv ) { + return true; } } - bool ret; - - // TODO: A bound can imply something via its associated types. How deep can this go? - // E.g. `T: IntoIterator<Item=&u8>` implies `<T as IntoIterator>::IntoIter : Iterator<Item=&u8>` - ret = this->iterate_bounds([&](const auto& b) { - TU_IFLET(::HIR::GenericBound, b, TraitBound, e, - const auto& b_params = e.trait.m_path.m_params; - DEBUG("(bound) - " << e.type << " : " << e.trait); - if( e.type == type ) - { - if( e.trait.m_path.m_path == trait_path ) { - // Check against `params` - if( trait_params ) { - DEBUG("Checking " << *trait_params << " vs " << b_params); - if( !H::compare_pp(sp, *trait_params, b_params) ) - return false; + // If the input type is an associated type controlled by this trait bound, check for added bounds. + // TODO: This just checks a single layer, but it's feasable that there could be multiple layers + if( assoc_info && e.trait.m_path.m_path == assoc_info->trait.m_path && e.type == *assoc_info->type && H::compare_pp(sp, b_params, assoc_info->trait.m_params) ) { + + const auto& trait_ref = *e.trait.m_trait_ptr; + const auto& at = trait_ref.m_types.at(assoc_info->item); + for(const auto& bound : at.m_trait_bounds) { + if( bound.m_path.m_path == trait_path && (!trait_params || H::compare_pp(sp, bound.m_path.m_params, *trait_params)) ) { + DEBUG("- Found an associated type impl"); + + auto tp_mono = monomorphise_traitpath_with(sp, bound, [&assoc_info,&sp](const auto& gt)->const auto& { + const auto& ge = gt.m_data.as_Generic(); + if( ge.binding == 0xFFFF ) { + return *assoc_info->type; } - // Hand off to the closure, and return true if it does - if( found_cb(ImplRef(&e.type, &e.trait.m_path.m_params, &e.trait.m_type_bounds)) ) { - return true; + else { + if( ge.binding >= assoc_info->trait.m_params.m_types.size() ) + BUG(sp, "find_trait_impls_bound - Generic #" << ge.binding << " " << ge.name << " out of range"); + return assoc_info->trait.m_params.m_types[ge.binding]; } + }, false); + // - Expand associated types + for(auto& ty : tp_mono.m_type_bounds) { + this->expand_associated_types(sp, ty.second); } - #if 1 - // HACK: The wrapping closure takes associated types from this bound and applies them to the returned set - // - XXX: This is actually wrong (false-positive) in many cases. FIXME - bool rv = this->find_named_trait_in_trait(sp, - trait_path,b_params, - *e.trait.m_trait_ptr, e.trait.m_path.m_path,e.trait.m_path.m_params, - type, - [&](const auto& params, auto assoc) { - for(const auto& i : e.trait.m_type_bounds) { - // TODO: Only include from above when needed - //if( des_trait_ref.m_types.count(i.first) ) { - assoc.insert( ::std::make_pair(i.first, i.second.clone()) ); - //} - } - return found_cb( ImplRef(type.clone(), params.clone(), mv$(assoc)) ); - }); - if( rv ) { + DEBUG("- tp_mono = " << tp_mono); + // TODO: Instead of using `type` here, build the real type + if( found_cb( ImplRef(type.clone(), mv$(tp_mono.m_path.m_params), mv$(tp_mono.m_type_bounds)) ) ) { return true; } - #endif - } - - // If the input type is an associated type controlled by this trait bound, check for added bounds. - // TODO: This just checks a single layer, but it's feasable that there could be multiple layers - if( assoc_info && e.trait.m_path.m_path == assoc_info->trait.m_path && e.type == *assoc_info->type && H::compare_pp(sp, b_params, assoc_info->trait.m_params) ) { - - const auto& trait_ref = *e.trait.m_trait_ptr; - const auto& at = trait_ref.m_types.at(assoc_info->item); - for(const auto& bound : at.m_trait_bounds) { - if( bound.m_path.m_path == trait_path && (!trait_params || H::compare_pp(sp, bound.m_path.m_params, *trait_params)) ) { - DEBUG("- Found an associated type impl"); - - auto tp_mono = monomorphise_traitpath_with(sp, bound, [&assoc_info,&sp](const auto& gt)->const auto& { - const auto& ge = gt.m_data.as_Generic(); - if( ge.binding == 0xFFFF ) { - return *assoc_info->type; - } - else { - if( ge.binding >= assoc_info->trait.m_params.m_types.size() ) - BUG(sp, "find_trait_impls_bound - Generic #" << ge.binding << " " << ge.name << " out of range"); - return assoc_info->trait.m_params.m_types[ge.binding]; - } - }, false); - // - Expand associated types - for(auto& ty : tp_mono.m_type_bounds) { - this->expand_associated_types(sp, ty.second); - } - DEBUG("- tp_mono = " << tp_mono); - // TODO: Instead of using `type` here, build the real type - if( found_cb( ImplRef(type.clone(), mv$(tp_mono.m_path.m_params), mv$(tp_mono.m_type_bounds)) ) ) { - return true; - } - } - } } - - return false; - ) - return false; - }); - if(ret) - return true; - - // Search the crate for impls - ret = m_crate.find_trait_impls(trait_path, type, cb_ident, [&](const auto& impl) { - return this->find_impl__check_crate(sp, trait_path, trait_params, type, found_cb, impl); - }); - if(ret) - return true; + } + } return false; } @@ -711,18 +725,13 @@ bool StaticTraitResolve::trait_contains_type(const Span& sp, const ::HIR::Generi return false; } -bool StaticTraitResolve::type_is_copy(const ::HIR::TypeRef& ty) const +bool StaticTraitResolve::type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const { - static Span sp; TU_MATCH(::HIR::TypeRef::Data, (ty.m_data), (e), (Generic, return this->iterate_bounds([&](const auto& b) { - TU_IFLET(::HIR::GenericBound, b, TraitBound, e, - if( e.type == ty && e.trait.m_path.m_path == m_lang_Copy ) { - return true; - } - ) - return false; + auto pp = ::HIR::PathParams(); + return this->find_impl__check_bound(sp, m_lang_Copy, &pp, ty, [&](auto ){ return true; }, b); }); ), (Path, @@ -761,7 +770,7 @@ bool StaticTraitResolve::type_is_copy(const ::HIR::TypeRef& ty) const return e != ::HIR::CoreType::Str; ), (Array, - return e.size_val == 0 || type_is_copy(*e.inner); + return e.size_val == 0 || type_is_copy(sp, *e.inner); ), (Slice, // [T] isn't Sized, so isn't Copy ether @@ -773,7 +782,7 @@ bool StaticTraitResolve::type_is_copy(const ::HIR::TypeRef& ty) const ), (Tuple, for(const auto& ty : e) - if( !type_is_copy(ty) ) + if( !type_is_copy(sp, ty) ) return false; return true; ) diff --git a/src/hir_typeck/static.hpp b/src/hir_typeck/static.hpp index b2e112f1..5f24fc11 100644 --- a/src/hir_typeck/static.hpp +++ b/src/hir_typeck/static.hpp @@ -97,6 +97,13 @@ public: ) const; private: + bool find_impl__check_bound( + const Span& sp, + const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, + const ::HIR::TypeRef& type, + t_cb_find_impl found_cb, + const ::HIR::GenericBound& bound + ) const; bool find_impl__check_crate( const Span& sp, const ::HIR::SimplePath& trait_path, const ::HIR::PathParams* trait_params, @@ -132,6 +139,6 @@ public: // -------------- // Common bounds // ------------- - bool type_is_copy(const ::HIR::TypeRef& ty) const; + bool type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) const; }; diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 7c91b34f..49dc0974 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -1028,7 +1028,7 @@ namespace { { this->visit_node_ptr(arg); values.push_back( m_builder.lvalue_or_temp( arg->m_res_type, m_builder.get_result(arg->span()) ) ); - m_builder.moved_lvalue( values.back() ); + m_builder.moved_lvalue( arg->span(), values.back() ); } // TODO: Obtain function type for this function (i.e. a type that is specifically for this function) @@ -1077,7 +1077,7 @@ namespace { { this->visit_node_ptr(arg); values.push_back( m_builder.lvalue_or_temp( arg->m_res_type, m_builder.get_result(arg->span()) ) ); - m_builder.moved_lvalue( values.back() ); + m_builder.moved_lvalue( arg->span(), values.back() ); } diff --git a/src/mir/from_hir.hpp b/src/mir/from_hir.hpp index ae9c80c8..3fd3c055 100644 --- a/src/mir/from_hir.hpp +++ b/src/mir/from_hir.hpp @@ -147,7 +147,7 @@ public: /// Introduce a new variable within the current scope void define_variable(unsigned int idx); // Helper - Marks a variable/... as moved (and checks if the move is valid) - void moved_lvalue(const ::MIR::LValue& lv); + void moved_lvalue(const Span& sp, const ::MIR::LValue& lv); private: VarState get_variable_state(unsigned int idx) const; void set_variable_state(unsigned int idx, VarState state); @@ -158,7 +158,7 @@ private: void complete_scope(ScopeDef& sd); void with_val_type(const ::MIR::LValue& val, ::std::function<void(const ::HIR::TypeRef&)> cb); - bool lvalue_is_copy(const ::MIR::LValue& lv); + bool lvalue_is_copy(const Span& sp, const ::MIR::LValue& lv); }; class MirConverter: diff --git a/src/mir/mir_builder.cpp b/src/mir/mir_builder.cpp index 0aca6b81..db9d3134 100644 --- a/src/mir/mir_builder.cpp +++ b/src/mir/mir_builder.cpp @@ -128,31 +128,32 @@ void MirBuilder::set_result(const Span& sp, ::MIR::RValue val) void MirBuilder::push_stmt_assign(::MIR::LValue dst, ::MIR::RValue val) { - ASSERT_BUG(Span(), m_block_active, "Pushing statement with no active block"); - ASSERT_BUG(Span(), dst.tag() != ::MIR::LValue::TAGDEAD, ""); - ASSERT_BUG(Span(), val.tag() != ::MIR::RValue::TAGDEAD, ""); + static Span sp; + ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); + ASSERT_BUG(sp, dst.tag() != ::MIR::LValue::TAGDEAD, ""); + ASSERT_BUG(sp, val.tag() != ::MIR::RValue::TAGDEAD, ""); TU_MATCHA( (val), (e), (Use, - this->moved_lvalue(e); + this->moved_lvalue(sp, e); ), (Constant, ), (SizedArray, - this->moved_lvalue(e.val); + this->moved_lvalue(sp, e.val); ), (Borrow, if( e.type == ::HIR::BorrowType::Owned ) { - TODO(Span(), "Move using &move"); + TODO(sp, "Move using &move"); // Likely would require a marker that ensures that the memory isn't reused. - this->moved_lvalue(e.val); + this->moved_lvalue(sp, e.val); } else { // Doesn't move } ), (Cast, - this->moved_lvalue(e.val); + this->moved_lvalue(sp, e.val); ), (BinOp, switch(e.op) @@ -166,32 +167,32 @@ void MirBuilder::push_stmt_assign(::MIR::LValue dst, ::MIR::RValue val) // Takes an implicit borrow... and only works on copy, so why is this block here? break; default: - this->moved_lvalue(e.val_l); - this->moved_lvalue(e.val_r); + this->moved_lvalue(sp, e.val_l); + this->moved_lvalue(sp, e.val_r); break; } ), (UniOp, - this->moved_lvalue(e.val); + this->moved_lvalue(sp, e.val); ), (DstMeta, // Doesn't move ), (MakeDst, // Doesn't move ptr_val - this->moved_lvalue(e.meta_val); + this->moved_lvalue(sp, e.meta_val); ), (Tuple, for(const auto& val : e.vals) - this->moved_lvalue(val); + this->moved_lvalue(sp, val); ), (Array, for(const auto& val : e.vals) - this->moved_lvalue(val); + this->moved_lvalue(sp, val); ), (Struct, for(const auto& val : e.vals) - this->moved_lvalue(val); + this->moved_lvalue(sp, val); ) ) @@ -246,10 +247,12 @@ void MirBuilder::push_stmt_assign(::MIR::LValue dst, ::MIR::RValue val) } void MirBuilder::push_stmt_drop(::MIR::LValue val) { - ASSERT_BUG(Span(), m_block_active, "Pushing statement with no active block"); - ASSERT_BUG(Span(), val.tag() != ::MIR::LValue::TAGDEAD, ""); + static Span sp_drop; + const auto& sp = sp_drop; + ASSERT_BUG(sp, m_block_active, "Pushing statement with no active block"); + ASSERT_BUG(sp, val.tag() != ::MIR::LValue::TAGDEAD, ""); - if( lvalue_is_copy(val) ) { + if( lvalue_is_copy(sp, val) ) { // Don't emit a drop for Copy values return ; } @@ -701,11 +704,11 @@ void MirBuilder::with_val_type(const ::MIR::LValue& val, ::std::function<void(co ) } -bool MirBuilder::lvalue_is_copy(const ::MIR::LValue& val) +bool MirBuilder::lvalue_is_copy(const Span& sp, const ::MIR::LValue& val) { int rv = 0; with_val_type(val, [&](const auto& ty){ - rv = (m_resolve.type_is_copy(ty) ? 2 : 1); + rv = (m_resolve.type_is_copy(sp, ty) ? 2 : 1); }); assert(rv != 0); return rv == 2; @@ -861,57 +864,57 @@ void MirBuilder::drop_scope_values(const ScopeDef& sd) ) } -void MirBuilder::moved_lvalue(const ::MIR::LValue& lv) +void MirBuilder::moved_lvalue(const Span& sp, const ::MIR::LValue& lv) { TRACE_FUNCTION_F(lv); TU_MATCHA( (lv), (e), (Variable, - if( !lvalue_is_copy(lv) ) { + if( !lvalue_is_copy(sp, lv) ) { set_variable_state(e, VarState::Moved); } ), (Temporary, - //if( !lvalue_is_copy(lv) ) { + if( !lvalue_is_copy(sp, lv) ) { set_temp_state(e.idx, VarState::Moved); - //} + } ), (Argument, - //TODO(Span(), "Mark argument as moved"); + //TODO(sp, "Mark argument as moved"); ), (Static, - //TODO(Span(), "Static - Assert that type is Copy"); + //TODO(sp, "Static - Assert that type is Copy"); ), (Return, - BUG(Span(), "Read of return value"); + BUG(sp, "Read of return value"); ), (Field, - if( lvalue_is_copy(lv) ) { + if( lvalue_is_copy(sp, lv) ) { } else { // TODO: Partial moves. - moved_lvalue(*e.val); + moved_lvalue(sp, *e.val); } ), (Deref, - if( lvalue_is_copy(lv) ) { + if( lvalue_is_copy(sp, lv) ) { } else { - BUG(Span(), "Move out of deref with non-Copy values - &move? - " << lv); - moved_lvalue(*e.val); + BUG(sp, "Move out of deref with non-Copy values - &move? - " << lv); + moved_lvalue(sp, *e.val); } ), (Index, - if( lvalue_is_copy(lv) ) { + if( lvalue_is_copy(sp, lv) ) { } else { - BUG(Span(), "Move out of index with non-Copy values - Partial move?"); - moved_lvalue(*e.val); + BUG(sp, "Move out of index with non-Copy values - Partial move?"); + moved_lvalue(sp, *e.val); } - moved_lvalue(*e.idx); + moved_lvalue(sp, *e.idx); ), (Downcast, // TODO: What if the inner is Copy? What if the inner is a hidden pointer? - moved_lvalue(*e.val); + moved_lvalue(sp, *e.val); ) ) } |