summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2016-08-23 17:32:29 +0800
committerJohn Hodge <tpg@mutabah.net>2016-08-23 17:32:29 +0800
commitc2aedab7b60ca3e6c293b7d022897aee0661db21 (patch)
treec8de400dc1a7d30726d7e7f56c63ac82416a3775 /src
parent6cf05070d793f95e051046f0a301f6e006bebb50 (diff)
downloadmrust-c2aedab7b60ca3e6c293b7d022897aee0661db21.tar.gz
HIR Typecheck - Require span for type_is_copy
Diffstat (limited to 'src')
-rw-r--r--src/hir/hir.cpp17
-rw-r--r--src/hir/hir.hpp2
-rw-r--r--src/hir_expand/annotate_value_usage.cpp11
-rw-r--r--src/hir_expand/closures.cpp13
-rw-r--r--src/hir_typeck/static.cpp209
-rw-r--r--src/hir_typeck/static.hpp9
-rw-r--r--src/mir/from_hir.cpp4
-rw-r--r--src/mir/from_hir.hpp4
-rw-r--r--src/mir/mir_builder.cpp77
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);
)
)
}