diff options
Diffstat (limited to 'src/hir_expand/ufcs_everything.cpp')
-rw-r--r-- | src/hir_expand/ufcs_everything.cpp | 154 |
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); ) |