summaryrefslogtreecommitdiff
path: root/src/hir_expand/ufcs_everything.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/hir_expand/ufcs_everything.cpp')
-rw-r--r--src/hir_expand/ufcs_everything.cpp154
1 files changed, 77 insertions, 77 deletions
diff --git a/src/hir_expand/ufcs_everything.cpp b/src/hir_expand/ufcs_everything.cpp
index daba3e6a..0562c418 100644
--- a/src/hir_expand/ufcs_everything.cpp
+++ b/src/hir_expand/ufcs_everything.cpp
@@ -18,14 +18,14 @@ namespace {
#define NEWNODE(TY, CLASS, ...) mk_exprnodep(new HIR::ExprNode_##CLASS(__VA_ARGS__), TY)
namespace {
-
+
class ExprVisitor_Mutate:
public ::HIR::ExprVisitorDef
{
const ::HIR::Crate& m_crate;
::HIR::ExprNodeP m_replacement;
::HIR::SimplePath m_lang_Box;
-
+
public:
ExprVisitor_Mutate(const ::HIR::Crate& crate):
m_crate(crate)
@@ -47,7 +47,7 @@ namespace {
root->m_usage = usage;
}
}
-
+
void visit_node_ptr(::HIR::ExprNodeP& node) override {
const auto& node_ref = *node;
const char* node_ty = typeid(node_ref).name();
@@ -62,7 +62,7 @@ namespace {
node->m_usage = usage;
}
}
-
+
// ----------
// _CallValue
// ----------
@@ -70,15 +70,15 @@ namespace {
void visit(::HIR::ExprNode_CallValue& node) override
{
const auto& sp = node.span();
-
+
::HIR::ExprVisitorDef::visit(node);
const auto& ty_val = node.m_value->m_res_type;
-
+
// Calling a `fn` type should be kept as a _CallValue
if( ty_val.m_data.is_Function() ) {
return ;
}
-
+
// 1. Construct tuple type containing argument types for `Args`
::HIR::TypeRef arg_tup_type;
{
@@ -90,7 +90,7 @@ namespace {
// - Make the trait arguments.
::HIR::PathParams trait_args;
trait_args.m_types.push_back( arg_tup_type.clone() );
-
+
// - If the called value is a local closure, figure out how it's being used.
// TODO: You can call via &-ptrs, but that currently isn't handled in typeck
TU_IFLET(::HIR::TypeRef::Data, node.m_value->m_res_type.m_data, Closure, e,
@@ -114,7 +114,7 @@ namespace {
}
}
)
-
+
// Use marking in node to determine trait to use
::HIR::TypeRef self_arg_type;
::HIR::Path method_path(::HIR::SimplePath{});
@@ -147,32 +147,32 @@ namespace {
"call_once"
);
break;
-
+
//case ::HIR::ExprNode_CallValue::TraitUsed::Unknown:
default:
BUG(node.span(), "Encountered CallValue with TraitUsed::Unknown, ty=" << node.m_value->m_res_type);
}
assert(self_arg_type != ::HIR::TypeRef());
-
-
+
+
// Construct argument list for the output
::std::vector< ::HIR::ExprNodeP> args;
args.reserve( 2 );
args.push_back( mv$(node.m_value) );
args.push_back(NEWNODE( arg_tup_type.clone(), Tuple, sp, mv$(node.m_args) ));
-
+
m_replacement = NEWNODE(mv$(node.m_res_type), CallPath, sp,
mv$(method_path),
mv$(args)
);
-
+
// Populate the cache for later passes
auto& arg_types = dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement).m_cache.m_arg_types;
arg_types.push_back( mv$(self_arg_type) );
arg_types.push_back( mv$(arg_tup_type) );
arg_types.push_back( m_replacement->m_res_type.clone() );
}
-
+
// ----------
// _CallMethod
// ----------
@@ -180,15 +180,15 @@ namespace {
void visit(::HIR::ExprNode_CallMethod& node) override
{
const auto& sp = node.span();
-
+
::HIR::ExprVisitorDef::visit(node);
-
+
::std::vector< ::HIR::ExprNodeP> args;
args.reserve( 1 + node.m_args.size() );
args.push_back( mv$(node.m_value) );
for(auto& arg : node.m_args)
args.push_back( mv$(arg) );
-
+
// Replace using known function path
m_replacement = NEWNODE(mv$(node.m_res_type), CallPath, sp,
mv$(node.m_method_path),
@@ -197,8 +197,8 @@ namespace {
// Populate the cache for later passes
dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement).m_cache = mv$(node.m_cache);
}
-
-
+
+
static bool is_op_valid_shift(const ::HIR::TypeRef& ty_l, const ::HIR::TypeRef& ty_r)
{
// Integer with any other integer is valid, others go to overload resolution
@@ -226,7 +226,7 @@ namespace {
}
break;
}
-
+
}
return false;
}
@@ -267,7 +267,7 @@ namespace {
}
return false;
}
-
+
// -------
// _Assign
// -------
@@ -276,10 +276,10 @@ namespace {
{
const auto& sp = node.span();
::HIR::ExprVisitorDef::visit(node);
-
+
const auto& ty_slot = node.m_slot->m_res_type;
const auto& ty_val = node.m_value->m_res_type;
-
+
const char* langitem = nullptr;
const char* opname = nullptr;
#define _(opname) case ::HIR::ExprNode_Assign::Op::opname
@@ -295,7 +295,7 @@ namespace {
return ;
}
break;
-
+
_(And): {langitem = "bitand_assign"; opname = "bitand_assign"; } if(0)
_(Or ): {langitem = "bitor_assign" ; opname = "bitor_assign" ; } if(0)
_(Xor): {langitem = "bitxor_assign"; opname = "bitxor_assign"; } if(0)
@@ -320,12 +320,12 @@ namespace {
#undef _
assert( langitem );
assert( opname );
-
+
// Needs replacement, continue
::HIR::PathParams trait_params;
trait_params.m_types.push_back( ty_val.clone() );
::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), mv$(trait_params) };
-
+
auto slot_type_refmut = ::HIR::TypeRef::new_borrow(::HIR::BorrowType::Unique, ty_slot.clone());
::std::vector< ::HIR::ExprNodeP> args;
args.push_back(NEWNODE( slot_type_refmut.clone(), Borrow, sp, ::HIR::BorrowType::Unique, mv$(node.m_slot) ));
@@ -334,22 +334,22 @@ namespace {
::HIR::Path(ty_slot.clone(), mv$(trait), opname),
mv$(args)
);
-
+
// Populate the cache for later passes
auto& arg_types = dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement).m_cache.m_arg_types;
arg_types.push_back( mv$(slot_type_refmut) );
arg_types.push_back( ty_val.clone() );
arg_types.push_back( ::HIR::TypeRef::new_unit() );
}
-
+
void visit(::HIR::ExprNode_BinOp& node) override
{
const auto& sp = node.span();
::HIR::ExprVisitorDef::visit(node);
-
+
const auto& ty_l = node.m_left->m_res_type;
const auto& ty_r = node.m_right->m_res_type;
-
+
const char* langitem = nullptr;
const char* method = nullptr;
switch(node.m_op)
@@ -383,19 +383,19 @@ namespace {
::HIR::PathParams trait_params;
trait_params.m_types.push_back( ty_r.clone() );
::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), mv$(trait_params) };
-
+
auto ty_l_ref = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ty_l.clone() );
auto ty_r_ref = ::HIR::TypeRef::new_borrow( ::HIR::BorrowType::Shared, ty_r.clone() );
-
+
::std::vector< ::HIR::ExprNodeP> args;
args.push_back(NEWNODE(ty_l_ref.clone(), Borrow, node.m_left ->span(), ::HIR::BorrowType::Shared, mv$(node.m_left ) ));
args.push_back(NEWNODE(ty_r_ref.clone(), Borrow, node.m_right->span(), ::HIR::BorrowType::Shared, mv$(node.m_right) ));
-
+
m_replacement = NEWNODE(mv$(node.m_res_type), CallPath, sp,
::HIR::Path(ty_l.clone(), mv$(trait), method),
mv$(args)
);
-
+
// Populate the cache for later passes
auto& arg_types = dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement).m_cache.m_arg_types;
arg_types.push_back( mv$(ty_l_ref) );
@@ -403,7 +403,7 @@ namespace {
arg_types.push_back( ::HIR::TypeRef( ::HIR::CoreType::Bool ) );
return ;
} break;
-
+
case ::HIR::ExprNode_BinOp::Op::Xor: langitem = method = "bitxor"; if(0)
case ::HIR::ExprNode_BinOp::Op::Or : langitem = method = "bitor" ; if(0)
case ::HIR::ExprNode_BinOp::Op::And: langitem = method = "bitand"; if(0)
@@ -412,14 +412,14 @@ namespace {
return ;
}
break;
-
+
case ::HIR::ExprNode_BinOp::Op::Shr: langitem = method = "shr"; if(0)
case ::HIR::ExprNode_BinOp::Op::Shl: langitem = method = "shr";
if( is_op_valid_shift(ty_l, ty_r) ) {
return ;
}
break;
-
+
case ::HIR::ExprNode_BinOp::Op::Add: langitem = method = "add"; if(0)
case ::HIR::ExprNode_BinOp::Op::Sub: langitem = method = "sub"; if(0)
case ::HIR::ExprNode_BinOp::Op::Mul: langitem = method = "mul"; if(0)
@@ -429,7 +429,7 @@ namespace {
return ;
}
break;
-
+
case ::HIR::ExprNode_BinOp::Op::BoolAnd:
case ::HIR::ExprNode_BinOp::Op::BoolOr:
ASSERT_BUG(sp, ty_l == ::HIR::TypeRef(::HIR::CoreType::Bool), "&& operator requires bool");
@@ -438,35 +438,35 @@ namespace {
}
assert(langitem);
assert(method);
-
+
// Needs replacement, continue
::HIR::PathParams trait_params;
trait_params.m_types.push_back( ty_r.clone() );
::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), mv$(trait_params) };
-
+
::std::vector< ::HIR::ExprNodeP> args;
args.push_back( mv$(node.m_left) );
args.push_back( mv$(node.m_right) );
-
+
m_replacement = NEWNODE(mv$(node.m_res_type), CallPath, sp,
::HIR::Path(ty_l.clone(), mv$(trait), method),
mv$(args)
);
-
+
// Populate the cache for later passes
auto& arg_types = dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement).m_cache.m_arg_types;
arg_types.push_back( ty_l.clone() );
arg_types.push_back( ty_r.clone() );
arg_types.push_back( m_replacement->m_res_type.clone() );
}
-
+
void visit(::HIR::ExprNode_UniOp& node) override
{
const auto& sp = node.span();
::HIR::ExprVisitorDef::visit(node);
-
+
const auto& ty_val = node.m_value->m_res_type;
-
+
const char* langitem = nullptr;
const char* method = nullptr;
switch(node.m_op)
@@ -518,33 +518,33 @@ namespace {
}
assert(langitem);
assert(method);
-
+
// Needs replacement, continue
::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), {} };
-
+
::std::vector< ::HIR::ExprNodeP> args;
args.push_back( mv$(node.m_value) );
-
+
m_replacement = NEWNODE(mv$(node.m_res_type), CallPath, sp,
::HIR::Path(ty_val.clone(), mv$(trait), method),
mv$(args)
);
-
+
// Populate the cache for later passes
auto& arg_types = dynamic_cast< ::HIR::ExprNode_CallPath&>(*m_replacement).m_cache.m_arg_types;
arg_types.push_back( ty_val.clone() );
arg_types.push_back( m_replacement->m_res_type.clone() );
}
-
-
+
+
void visit(::HIR::ExprNode_Index& node) override
{
const auto& sp = node.span();
::HIR::ExprVisitorDef::visit(node);
-
+
const auto& ty_idx = node.m_index->m_res_type;
const auto& ty_val = node.m_value->m_res_type;
-
+
TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_val.m_data), (val_te),
(
// Unknown? fall down to the method call
@@ -564,7 +564,7 @@ namespace {
// Any other index type goes to the function call
)
)
-
+
// TODO: Which trait should be used?
const char* langitem = nullptr;
const char* method = nullptr;
@@ -589,16 +589,16 @@ namespace {
// Needs replacement, continue
assert(langitem);
assert(method);
-
+
// - Construct trait path - Index*<IdxTy>
::HIR::PathParams pp;
pp.m_types.push_back( ty_idx.clone() );
::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), mv$(pp) };
-
+
::std::vector< ::HIR::ExprNodeP> args;
args.push_back( NEWNODE( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()), Borrow, sp, bt, mv$(node.m_value) ) );
args.push_back( mv$(node.m_index) );
-
+
m_replacement = NEWNODE( ::HIR::TypeRef::new_borrow(bt, node.m_res_type.clone()), CallPath, sp,
::HIR::Path(ty_val.clone(), mv$(trait), method),
mv$(args)
@@ -610,19 +610,19 @@ namespace {
arg_types.push_back( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()) );
arg_types.push_back( ty_idx.clone() );
arg_types.push_back( m_replacement->m_res_type.clone() );
-
+
// - Dereference the result (which is an &-ptr)
m_replacement = NEWNODE( mv$(node.m_res_type), Deref, sp, mv$(m_replacement) );
}
-
+
void visit(::HIR::ExprNode_Deref& node) override
{
const auto& sp = node.span();
-
+
::HIR::ExprVisitorDef::visit(node);
-
+
const auto& ty_val = node.m_value->m_res_type;
-
+
TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_val.m_data), (e),
(
BUG(sp, "Deref on unexpected type - " << ty_val);
@@ -647,7 +647,7 @@ namespace {
return ;
)
)
-
+
const char* langitem = nullptr;
const char* method = nullptr;
::HIR::BorrowType bt;
@@ -672,13 +672,13 @@ namespace {
// Needs replacement, continue
assert(langitem);
assert(method);
-
+
// - Construct trait path - Index*<IdxTy>
::HIR::GenericPath trait { m_crate.get_lang_item_path(node.span(), langitem), {} };
-
+
::std::vector< ::HIR::ExprNodeP> args;
args.push_back( NEWNODE( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()), Borrow, sp, bt, mv$(node.m_value) ) );
-
+
m_replacement = NEWNODE( ::HIR::TypeRef::new_borrow(bt, node.m_res_type.clone()), CallPath, sp,
::HIR::Path(ty_val.clone(), mv$(trait), method),
mv$(args)
@@ -689,23 +689,23 @@ namespace {
auto& arg_types = call_node.m_cache.m_arg_types;
arg_types.push_back( ::HIR::TypeRef::new_borrow(bt, ty_val.clone()) );
arg_types.push_back( m_replacement->m_res_type.clone() );
-
+
// - Dereference the result (which is an &-ptr)
m_replacement = NEWNODE( mv$(node.m_res_type), Deref, sp, mv$(m_replacement) );
}
-
-
-
+
+
+
void visit(::HIR::ExprNode_Unsize& node) override
{
::HIR::ExprVisitorDef::visit(node);
-
+
// HACK: The autoderef code has to run before usage information is avaliable, so emits "invalid" _Unsize nodes
// - Fix that.
if( node.m_value->m_res_type.m_data.is_Array() )
{
const Span& sp = node.span();
-
+
::HIR::BorrowType bt = ::HIR::BorrowType::Shared;
switch( node.m_usage )
{
@@ -722,7 +722,7 @@ namespace {
TODO(sp, "Support moving in _Unsize");
break;
}
-
+
auto ty_src = ::HIR::TypeRef::new_borrow(bt, node.m_value->m_res_type.clone());
auto ty_dst = ::HIR::TypeRef::new_borrow(bt, node.m_res_type.clone());
auto ty_dst2 = ty_dst.clone();
@@ -744,12 +744,12 @@ namespace {
m_crate(crate)
{
}
-
+
// NOTE: This is left here to ensure that any expressions that aren't handled by higher code cause a failure
void visit_expr(::HIR::ExprPtr& exp) override {
BUG(Span(), "visit_expr hit in OuterVisitor");
}
-
+
void visit_type(::HIR::TypeRef& ty) override
{
TU_IFLET(::HIR::TypeRef::Data, ty.m_data, Array, e,
@@ -799,7 +799,7 @@ namespace {
{
TU_IFLET(::HIR::Enum::Variant, var.second, Value, e,
DEBUG("Enum value " << p << " - " << var.first);
-
+
ExprVisitor_Mutate ev(m_crate);
ev.visit_node_ptr(e.expr);
)