diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-02-03 13:42:13 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-02-03 13:42:13 +0800 |
commit | 4960edb7d948e43efc58a28ecd05fa9237c8d240 (patch) | |
tree | 3d193eb4b55c680f64fe332f6040bf2122f128ed | |
parent | aab9f94620c7d78377ffbd3fdbcb845657c86503 (diff) | |
download | mrust-4960edb7d948e43efc58a28ecd05fa9237c8d240.tar.gz |
HIR Expr - Have _StructLiteral take a HIR::Path (to allow associated types to be used)
-rw-r--r-- | src/hir/expr.cpp | 2 | ||||
-rw-r--r-- | src/hir/expr.hpp | 4 | ||||
-rw-r--r-- | src/hir/from_ast.cpp | 12 | ||||
-rw-r--r-- | src/hir/from_ast_expr.cpp | 2 | ||||
-rw-r--r-- | src/hir_conv/bind.cpp | 2 | ||||
-rw-r--r-- | src/hir_conv/expand_type.cpp | 5 | ||||
-rw-r--r-- | src/hir_expand/annotate_value_usage.cpp | 6 | ||||
-rw-r--r-- | src/hir_typeck/expr_check.cpp | 6 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 15 | ||||
-rw-r--r-- | src/mir/from_hir.cpp | 35 |
10 files changed, 56 insertions, 33 deletions
diff --git a/src/hir/expr.cpp b/src/hir/expr.cpp index 6b7c2e1a..589e2811 100644 --- a/src/hir/expr.cpp +++ b/src/hir/expr.cpp @@ -158,7 +158,7 @@ DEF_VISIT(ExprNode_PathValue, node, ) DEF_VISIT(ExprNode_Variable, , ) DEF_VISIT(ExprNode_StructLiteral, node, - visit_generic_path(::HIR::Visitor::PathContext::VALUE, node.m_path); + visit_path(::HIR::Visitor::PathContext::VALUE, node.m_path); if( node.m_base_value ) visit_node_ptr(node.m_base_value); for(auto& val : node.m_values) diff --git a/src/hir/expr.hpp b/src/hir/expr.hpp index 15c0a489..140ba817 100644 --- a/src/hir/expr.hpp +++ b/src/hir/expr.hpp @@ -694,7 +694,7 @@ struct ExprNode_StructLiteral: { typedef ::std::vector< ::std::pair< ::std::string, ExprNodeP > > t_values; - ::HIR::GenericPath m_path; + ::HIR::Path m_path; bool m_is_struct; ::HIR::ExprNodeP m_base_value; t_values m_values; @@ -702,7 +702,7 @@ struct ExprNode_StructLiteral: /// Monomorphised types of each field. ::std::vector< ::HIR::TypeRef> m_value_types; - ExprNode_StructLiteral(Span sp, ::HIR::GenericPath path, bool is_struct, ::HIR::ExprNodeP base_value, t_values values): + ExprNode_StructLiteral(Span sp, ::HIR::Path path, bool is_struct, ::HIR::ExprNodeP base_value, t_values values): ExprNode( mv$(sp) ), m_path( mv$(path) ), m_is_struct( is_struct ), diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 899d0b0c..768593c4 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -628,7 +628,17 @@ const ::AST::Crate* g_ast_crate_ptr; return ::HIR::Path( LowerHIR_GenericPath(sp, path) ); ), (UFCS, - if( e.nodes.size() != 1 ) + if( e.nodes.size() == 0 ) + { + if( !e.trait ) + TODO(sp, "Handle UFCS inherent and no nodes - " << path); + if( e.trait->is_valid() ) + TODO(sp, "Handle UFCS w/ trait and no nodes - " << path); + auto type = LowerHIR_Type(*e.type); + ASSERT_BUG(sp, type.m_data.is_Path(), "No nodes and non-Path type - " << path); + return mv$(type.m_data.as_Path().path); + } + if( e.nodes.size() > 1 ) TODO(sp, "Handle UFCS with multiple nodes - " << path); // - No associated type bounds allowed in UFCS paths auto params = LowerHIR_PathParams(sp, e.nodes.front().args(), false); diff --git a/src/hir/from_ast_expr.cpp b/src/hir/from_ast_expr.cpp index 55c742ad..23797382 100644 --- a/src/hir/from_ast_expr.cpp +++ b/src/hir/from_ast_expr.cpp @@ -528,7 +528,7 @@ struct LowerHIR_ExprNode_Visitor: values.push_back( ::std::make_pair(val.name, LowerHIR_ExprNode_Inner(*val.value)) ); // TODO: What if `v.m_path` is an associated type (that's known to be a struct) m_rv.reset( new ::HIR::ExprNode_StructLiteral( v.span(), - LowerHIR_GenericPath(v.span(), v.m_path), + LowerHIR_Path(v.span(), v.m_path), ! v.m_path.m_bindings.type.is_EnumVar(), LowerHIR_ExprNode_Inner_Opt(v.m_base_value.get()), mv$(values) diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index c979b2e6..9b5043f4 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -645,7 +645,7 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { - upper_visitor.visit_generic_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); + upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); ::HIR::ExprVisitorDef::visit(node); } void visit(::HIR::ExprNode_ArraySized& node) override diff --git a/src/hir_conv/expand_type.cpp b/src/hir_conv/expand_type.cpp index dcdf79bd..6b06a748 100644 --- a/src/hir_conv/expand_type.cpp +++ b/src/hir_conv/expand_type.cpp @@ -255,9 +255,10 @@ public: { if( node.m_is_struct ) { - auto new_path = upper_visitor.expand_alias_gp(node.span(), node.m_path); - if( new_path.m_path.m_components.size() != 0 ) + auto new_type = ConvertHIR_ExpandAliases_GetExpansion(upper_visitor.m_crate, node.m_path, /*in_expr=*/true); + if( new_type != ::HIR::TypeRef() ) { + auto new_path = mv$(new_type.m_data.as_Path().path); DEBUG("Replacing " << node.m_path << " with " << new_path); node.m_path = mv$(new_path); } diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 491ab4c7..1754bdac 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -356,13 +356,15 @@ namespace { void visit(::HIR::ExprNode_StructLiteral& node) override { const auto& sp = node.span(); + ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "Struct literal with non-Generic path - " << node.m_path); + auto& ty_path = node.m_path.m_data.as_Generic(); if( node.m_base_value ) { bool is_moved = false; const auto& tpb = node.m_base_value->m_res_type.m_data.as_Path().binding; const ::HIR::Struct* str; if( tpb.is_Enum() ) { const auto& enm = *tpb.as_Enum(); - auto idx = enm.find_variant(node.m_path.m_path.m_components.back()); + auto idx = enm.find_variant(ty_path.m_path.m_components.back()); ASSERT_BUG(sp, idx != SIZE_MAX, ""); const auto& var_ty = enm.m_data.as_Data()[idx].type; str = var_ty.m_data.as_Path().binding.as_Struct(); @@ -379,7 +381,7 @@ namespace { provided_mask[idx] = true; } - const auto monomorph_cb = monomorphise_type_get_cb(node.span(), nullptr, &node.m_path.m_params, nullptr); + const auto monomorph_cb = monomorphise_type_get_cb(node.span(), nullptr, &ty_path.m_params, nullptr); for( unsigned int i = 0; i < fields.size(); i ++ ) { if( ! provided_mask[i] ) { const auto& ty_o = fields[i].second.ent; diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index cd57c471..adb3c426 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -496,6 +496,8 @@ namespace { if( node.m_base_value) { check_types_equal( node.m_base_value->span(), node.m_res_type, node.m_base_value->m_res_type ); } + ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "_StructLiteral with non-Generic path - " << node.m_path); + auto& ty_path = node.m_path.m_data.as_Generic(); // - Create ivars in path, and set result type const auto& ty = node.m_res_type; @@ -506,7 +508,7 @@ namespace { (Unbound, ), (Opaque, ), (Enum, - const auto& var_name = node.m_path.m_path.m_components.back(); + const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; auto idx = enm.find_variant(var_name); ASSERT_BUG(sp, idx != SIZE_MAX, ""); @@ -536,7 +538,7 @@ namespace { const ::HIR::t_struct_fields& fields = *fields_ptr; #if 1 - const auto& ty_params = node.m_path.m_params.m_types; + const auto& ty_params = ty_path.m_params.m_types; auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 8b0eedb3..4a53bd4d 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1193,7 +1193,10 @@ namespace { { const auto& sp = node.span(); TRACE_FUNCTION_F(&node << " " << node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); - this->add_ivars_generic_path(node.span(), node.m_path); + ASSERT_BUG(sp, node.m_path.m_data.is_Generic(), "Struct literal with non-Generic path - " << node.m_path); + auto& ty_path = node.m_path.m_data.as_Generic(); + + this->add_ivars_generic_path(node.span(), ty_path); for( auto& val : node.m_values ) { this->context.add_ivars( val.second->m_res_type ); } @@ -1202,7 +1205,7 @@ namespace { } // - Create ivars in path, and set result type - const auto ty = this->get_structenum_ty(node.span(), node.m_is_struct, node.m_path); + const auto ty = this->get_structenum_ty(node.span(), node.m_is_struct, ty_path); this->context.equate_types(node.span(), node.m_res_type, ty); if( node.m_base_value ) { this->context.equate_types(node.span(), node.m_base_value->m_res_type, ty); @@ -1214,7 +1217,7 @@ namespace { (Unbound, ), (Opaque, ), (Enum, - const auto& var_name = node.m_path.m_path.m_components.back(); + const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; auto idx = enm.find_variant(var_name); ASSERT_BUG(sp, idx != SIZE_MAX, ""); @@ -1257,7 +1260,7 @@ namespace { ASSERT_BUG(node.span(), fields_ptr, ""); const ::HIR::t_struct_fields& fields = *fields_ptr; - const auto& ty_params = node.m_path.m_params.m_types; + const auto& ty_params = ty_path.m_params.m_types; auto monomorph_cb = [&](const auto& gt)->const ::HIR::TypeRef& { const auto& ge = gt.m_data.as_Generic(); if( ge.binding == 0xFFFF ) { @@ -1281,7 +1284,7 @@ namespace { { const auto& name = val.first; auto it = ::std::find_if(fields.begin(), fields.end(), [&](const auto& v)->bool{ return v.first == name; }); - ASSERT_BUG(node.span(), it != fields.end(), "Field '" << name << "' not found in struct " << node.m_path); + ASSERT_BUG(node.span(), it != fields.end(), "Field '" << name << "' not found in struct " << ty_path); const auto& des_ty_r = it->second.ent; auto& des_ty_cache = node.m_value_types[it - fields.begin()]; const auto* des_ty = &des_ty_r; @@ -3164,7 +3167,7 @@ namespace { this->check_type_resolved_genericpath(node.span(), node.m_path); } void visit(::HIR::ExprNode_StructLiteral& node) override { - this->check_type_resolved_pp(node.span(), node.m_path.m_params, ::HIR::TypeRef()); + this->check_type_resolved_path(node.span(), node.m_path); for(auto& ty : node.m_value_types) { if( ty != ::HIR::TypeRef() ) { this->check_type_resolved_top(node.span(), ty); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index ee4cf474..9ce40a74 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -2365,13 +2365,18 @@ namespace { { TRACE_FUNCTION_F("_StructLiteral"); - TU_MATCH(::HIR::TypeRef::TypePathBinding, (node.m_res_type.m_data.as_Path().binding), (e), - (Unbound, ), - (Opaque, ), - (Enum, - auto enum_path = node.m_path.clone(); + ASSERT_BUG(node.span(), node.m_path.m_data.is_Generic(), "_StructLiteral with non-Generic path - " << node.m_path); + const auto& ty_path = node.m_path.m_data.as_Generic(); + + TU_MATCH_HDRA( (node.m_res_type.m_data.as_Path().binding), {) + TU_ARMA(Unbound, _e) { + } + TU_ARMA(Opaque, _e) { + } + TU_ARMA(Enum, e) { + auto enum_path = ty_path.clone(); enum_path.m_path.m_components.pop_back(); - const auto& var_name = node.m_path.m_path.m_components.back(); + const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; size_t idx = enm.find_variant(var_name); @@ -2381,7 +2386,7 @@ namespace { const auto& str = *var_ty.m_data.as_Path().binding.as_Struct(); // Take advantage of the identical generics to cheaply clone/monomorph the path. - ::HIR::GenericPath struct_path = node.m_path.clone(); + ::HIR::GenericPath struct_path = ty_path.clone(); struct_path.m_path = var_ty.m_data.as_Path().path.m_data.as_Generic().m_path; this->visit_sl_inner(node, str, struct_path); @@ -2396,22 +2401,22 @@ namespace { static_cast<unsigned>(idx), mv$(v) }) ); - ), - (Union, + } + TU_ARMA(Union, e) { BUG(node.span(), "_StructLiteral Union isn't valid?"); - ), - (Struct, + } + TU_ARMA(Struct, e) { if(e->m_data.is_Unit()) { m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({ - node.m_path.clone(), + ty_path.clone(), {} }) ); return ; } - this->visit_sl_inner(node, *e, node.m_path); - ) - ) + this->visit_sl_inner(node, *e, ty_path); + } + } } void visit(::HIR::ExprNode_UnionLiteral& node) override { |