From 777bdf9a8bfcd6a5b1b4c38c6a57f582fc9d5d18 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 3 Jan 2019 23:11:35 +0800 Subject: HIR Expand - Handle match ergonomics in AVU --- src/hir_expand/annotate_value_usage.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/hir_expand/annotate_value_usage.cpp') diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 693c7745..f5acbbc5 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -452,12 +452,20 @@ namespace { throw ""; } - ::HIR::ValueUsage get_usage_for_pattern(const Span& sp, const ::HIR::Pattern& pat, const ::HIR::TypeRef& ty) const + ::HIR::ValueUsage get_usage_for_pattern(const Span& sp, const ::HIR::Pattern& pat, const ::HIR::TypeRef& outer_ty) const { if( pat.m_binding.is_valid() ) { - return get_usage_for_pattern_binding(sp, pat.m_binding, ty); + return get_usage_for_pattern_binding(sp, pat.m_binding, outer_ty); } + // Implicit derefs + const ::HIR::TypeRef* typ = &outer_ty; + for(size_t i = 0; i < pat.m_implicit_deref_count; i ++) + { + typ = &*typ->m_data.as_Borrow().inner; + } + const ::HIR::TypeRef& ty = *typ; + TU_MATCHA( (pat.m_data), (pe), (Any, return ::HIR::ValueUsage::Borrow; -- cgit v1.2.3 From feaa7573c2d959d1cf893e8bd772cb22bccf5d62 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Jan 2019 19:34:28 +0800 Subject: HIR Misc - Local asserts with patterns --- src/hir_expand/annotate_value_usage.cpp | 4 ++-- src/mir/from_hir.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/hir_expand/annotate_value_usage.cpp') diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index f5acbbc5..491ab4c7 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -560,10 +560,10 @@ namespace { ), (EnumStruct, const auto& enm = *pe.binding_ptr; - ASSERT_BUG(sp, enm.m_data.is_Data(), ""); + ASSERT_BUG(sp, enm.m_data.is_Data(), "EnumStruct pattern on non-data enum"); const auto& var = enm.m_data.as_Data().at(pe.binding_idx); const auto& str = *var.type.m_data.as_Path().binding.as_Struct(); - ASSERT_BUG(sp, str.m_data.is_Named(), ""); + ASSERT_BUG(sp, str.m_data.is_Named(), "EnumStruct pattern on non-struct variant - " << pe.path); const auto& flds = str.m_data.as_Named(); auto monomorph_cb = monomorphise_type_get_cb(sp, nullptr, &pe.path.m_params, nullptr); diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index e13b9db1..ee4cf474 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -251,6 +251,7 @@ namespace { } TU_ARMA(Struct, e) { const auto& str = *e.binding; + ASSERT_BUG(sp, str.m_data.is_Named(), "Struct pattern on non-Named struct - " << e.path); const auto& fields = str.m_data.as_Named(); for(const auto& fld_pat : e.sub_patterns) { @@ -304,6 +305,7 @@ namespace { ASSERT_BUG(sp, enm.m_data.is_Data(), "Expected struct variant - " << pat); const auto& var = enm.m_data.as_Data()[e.binding_idx];; const auto& str = *var.type.m_data.as_Path().binding.as_Struct(); + ASSERT_BUG(sp, str.m_data.is_Named(), "Struct pattern on non-Named struct - " << e.path); const auto& fields = str.m_data.as_Named(); auto lval_var = ::MIR::LValue::make_Downcast({ box$(mv$(lval)), e.binding_idx }); for(const auto& fld_pat : e.sub_patterns) -- cgit v1.2.3 From 4960edb7d948e43efc58a28ecd05fa9237c8d240 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 3 Feb 2019 13:42:13 +0800 Subject: HIR Expr - Have _StructLiteral take a HIR::Path (to allow associated types to be used) --- src/hir/expr.cpp | 2 +- src/hir/expr.hpp | 4 ++-- src/hir/from_ast.cpp | 12 ++++++++++- src/hir/from_ast_expr.cpp | 2 +- src/hir_conv/bind.cpp | 2 +- src/hir_conv/expand_type.cpp | 5 +++-- src/hir_expand/annotate_value_usage.cpp | 6 ++++-- src/hir_typeck/expr_check.cpp | 6 ++++-- src/hir_typeck/expr_cs.cpp | 15 ++++++++------ src/mir/from_hir.cpp | 35 +++++++++++++++++++-------------- 10 files changed, 56 insertions(+), 33 deletions(-) (limited to 'src/hir_expand/annotate_value_usage.cpp') 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(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 { -- cgit v1.2.3 From 054faa303107d5940463465d729cc0d1e2ec8473 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 9 Feb 2019 22:32:40 +0800 Subject: Typecheck - Various fixes for librustc --- src/hir/pattern.hpp | 4 ++ src/hir/type.cpp | 30 +++++----- src/hir_conv/resolve_ufcs.cpp | 5 ++ src/hir_expand/annotate_value_usage.cpp | 6 ++ src/hir_typeck/expr_cs.cpp | 103 +++++++++++++++++++++++--------- src/hir_typeck/helpers.cpp | 3 +- 6 files changed, 108 insertions(+), 43 deletions(-) (limited to 'src/hir_expand/annotate_value_usage.cpp') diff --git a/src/hir/pattern.hpp b/src/hir/pattern.hpp index b17ebcb4..cd6c7422 100644 --- a/src/hir/pattern.hpp +++ b/src/hir/pattern.hpp @@ -102,6 +102,10 @@ struct Pattern const Struct* binding; ::std::vector< ::std::pair< ::std::string, Pattern> > sub_patterns; bool is_exhaustive; + + bool is_wildcard() const { + return sub_patterns.empty() && !is_exhaustive; + } } ), // Refutable (Value, struct { Value val; } ), diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 981ed0b3..ff4742e6 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -177,12 +177,10 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const } TU_ARM(m_data, Closure, e) { os << "closure["< " << *e.m_rettype; - */ } } } @@ -901,6 +899,22 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x return Compare::Equal; } + // Unbound paths and placeholder generics + if( left.m_data.tag() != right.m_data.tag() ) { + if( left.m_data.is_Path() && left.m_data.as_Path().binding.is_Unbound() ) { + return Compare::Fuzzy; + } + if( right.m_data.is_Path() && right.m_data.as_Path().binding.is_Unbound() ) { + return Compare::Fuzzy; + } + if( left.m_data.is_Generic() && (left.m_data.as_Generic().binding >> 8) == 2 ) { + return Compare::Fuzzy; + } + if( right.m_data.is_Generic() && (right.m_data.as_Generic().binding >> 8) == 2 ) { + return Compare::Fuzzy; + } + } + // If left is infer TU_IFLET(::HIR::TypeRef::Data, left.m_data, Infer, e, switch(e.ty_class) @@ -1025,18 +1039,6 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x // - See `(Generic,` below if( left.m_data.tag() != right.m_data.tag() ) { - if( left.m_data.is_Path() && left.m_data.as_Path().binding.is_Unbound() ) { - return Compare::Fuzzy; - } - if( right.m_data.is_Path() && right.m_data.as_Path().binding.is_Unbound() ) { - return Compare::Fuzzy; - } - if( left.m_data.is_Generic() && (left.m_data.as_Generic().binding >> 8) == 2 ) { - return Compare::Fuzzy; - } - if( right.m_data.is_Generic() && (right.m_data.as_Generic().binding >> 8) == 2 ) { - return Compare::Fuzzy; - } return Compare::Unequal; } TU_MATCH(::HIR::TypeRef::Data, (left.m_data, right.m_data), (le, re), diff --git a/src/hir_conv/resolve_ufcs.cpp b/src/hir_conv/resolve_ufcs.cpp index 19ec84ba..90b3868d 100644 --- a/src/hir_conv/resolve_ufcs.cpp +++ b/src/hir_conv/resolve_ufcs.cpp @@ -187,6 +187,11 @@ namespace { upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::VALUE); ::HIR::ExprVisitorDef::visit(node); } + void visit(::HIR::ExprNode_StructLiteral& node) override + { + upper_visitor.visit_path(node.m_path, ::HIR::Visitor::PathContext::TYPE); + ::HIR::ExprVisitorDef::visit(node); + } void visit(::HIR::ExprNode_Match& node) override { diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 1754bdac..e763586c 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -520,6 +520,12 @@ namespace { ), (Struct, const auto& str = *pe.binding; + if( pe.is_wildcard() ) + return ::HIR::ValueUsage::Borrow; + if( pe.sub_patterns.empty() && (TU_TEST1(str.m_data, Tuple, .empty()) || str.m_data.is_Unit()) ) { + return ::HIR::ValueUsage::Borrow; + } + ASSERT_BUG(sp, str.m_data.is_Named(), "Struct pattern on non-brace struct"); const auto& flds = str.m_data.as_Named(); auto monomorph_cb = monomorphise_type_get_cb(sp, nullptr, &pe.path.m_params, nullptr); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 794f3a9c..70b9c26c 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1196,10 +1196,9 @@ namespace { { const auto& sp = node.span(); TRACE_FUNCTION_F(&node << " " << node.m_path << "{...} [" << (node.m_is_struct ? "struct" : "enum") << "]"); - 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); + this->add_ivars_path(node.span(), node.m_path); + for( auto& val : node.m_values ) { this->context.add_ivars( val.second->m_res_type ); } @@ -1207,6 +1206,15 @@ namespace { this->context.add_ivars( node.m_base_value->m_res_type ); } + // TODO: The path can be a Ufcs (any type) + if( !node.m_path.m_data.is_Generic() ) + { + auto t = this->context.m_resolve.expand_associated_types(sp, ::HIR::TypeRef::new_path( mv$(node.m_path), {} )); + node.m_path = mv$(t.m_data.as_Path().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(); + // - Create ivars in path, and set result type 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); @@ -3997,8 +4005,21 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T rv = true; } TU_ARM(pattern.m_data, Box, pe) { - // TODO: inner pattern - TODO(sp, "Match ergonomics - box pattern"); + // Box + if( TU_TEST2(ty.m_data, Path, .path.m_data, Generic, .m_path == context.m_lang_Box) ) + { + const auto& path = ty.m_data.as_Path().path.m_data.as_Generic(); + const auto& inner = path.m_params.m_types.at(0); + rv = this->revisit_inner(context, *pe.sub, inner, binding_mode); + } + else + { + TODO(sp, "Match ergonomics - box pattern - Non Box type: " << ty); + //auto inner = this->m_ivars.new_ivar_tr(); + //this->handle_pattern_direct_inner(sp, *e.sub, inner); + //::HIR::GenericPath path { m_lang_Box, ::HIR::PathParams(mv$(inner)) }; + //this->equate_types( sp, type, ::HIR::TypeRef::new_path(mv$(path), ::HIR::TypeRef::TypePathBinding(&m_crate.get_struct_by_path(sp, m_lang_Box))) ); + } } TU_ARM(pattern.m_data, Ref, pe) { BUG(sp, "Match ergonomics - & pattern"); @@ -4082,25 +4103,34 @@ void Context::handle_pattern(const Span& sp, ::HIR::Pattern& pat, const ::HIR::T assert(e.binding); const auto& str = *e.binding; - // - assert check from earlier pass - ASSERT_BUG(sp, str.m_data.is_Named(), "Struct pattern on non-Named struct"); - const auto& sd = str.m_data.as_Named(); - const auto& params = e.path.m_params; - - rv = true; - for( auto& field_pat : e.sub_patterns ) + //if( ! e.is_wildcard() ) + if( e.sub_patterns.empty() ) { - unsigned int f_idx = ::std::find_if( sd.begin(), sd.end(), [&](const auto& x){ return x.first == field_pat.first; } ) - sd.begin(); - if( f_idx == sd.size() ) { - ERROR(sp, E0000, "Struct " << e.path << " doesn't have a field " << field_pat.first); - } - const ::HIR::TypeRef& field_type = sd[f_idx].second.ent; - if( monomorphise_type_needed(field_type) ) { - auto field_type_mono = monomorphise_type(sp, str.m_params, params, field_type); - rv &= this->revisit_inner(context, field_pat.second, field_type_mono, binding_mode); - } - else { - rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode); + // TODO: Check the field count? + rv = true; + } + else + { + // - assert check from earlier pass + ASSERT_BUG(sp, str.m_data.is_Named(), "Struct pattern on non-Named struct"); + const auto& sd = str.m_data.as_Named(); + const auto& params = e.path.m_params; + + rv = true; + for( auto& field_pat : e.sub_patterns ) + { + unsigned int f_idx = ::std::find_if( sd.begin(), sd.end(), [&](const auto& x){ return x.first == field_pat.first; } ) - sd.begin(); + if( f_idx == sd.size() ) { + ERROR(sp, E0000, "Struct " << e.path << " doesn't have a field " << field_pat.first); + } + const ::HIR::TypeRef& field_type = sd[f_idx].second.ent; + if( monomorphise_type_needed(field_type) ) { + auto field_type_mono = monomorphise_type(sp, str.m_params, params, field_type); + rv &= this->revisit_inner(context, field_pat.second, field_type_mono, binding_mode); + } + else { + rv &= this->revisit_inner(context, field_pat.second, field_type, binding_mode); + } } } } @@ -4684,7 +4714,7 @@ void Context::handle_pattern_direct_inner(const Span& sp, ::HIR::Pattern& pat, c this->add_ivars_params( e.path.m_params ); this->equate_types( sp, type, ::HIR::TypeRef::new_path(e.path.clone(), ::HIR::TypeRef::TypePathBinding(e.binding)) ); - if( e.sub_patterns.empty() ) + if( e.is_wildcard() ) return ; assert(e.binding); @@ -5140,6 +5170,7 @@ namespace { { DEBUG("- Moving into block"); assert( p->m_value_node ); + // Block result and the inner node's result must be the same type ASSERT_BUG( p->span(), context.m_ivars.types_equal(p->m_res_type, p->m_value_node->m_res_type), "Block and result mismatch - " << context.m_ivars.fmt_type(p->m_res_type) << " != " << context.m_ivars.fmt_type(p->m_value_node->m_res_type)); // - Override the the result type to the desired result @@ -5253,7 +5284,7 @@ namespace { return CoerceResult::Equality; } context.possible_equate_type_unsize_to(sep->index, dst); - DEBUG("Src ivar"); + DEBUG("Src is ivar (" << src << "), return Unknown"); return CoerceResult::Unknown; } else @@ -5926,10 +5957,20 @@ namespace { context.m_ivars.mark_change(); // Continue on with coercion (now that node_ptr is updated) - switch( check_unsize_tys(context, sp, *dep->inner, *se.inner, node_ptr_ptr) ) + switch( check_unsize_tys(context, sp, *dep->inner, *se.inner, &node_ptr) ) { case CoerceResult::Unknown: - return CoerceResult::Unknown; + // Add new coercion at the new inner point + if( &node_ptr != node_ptr_ptr ) + { + DEBUG("Unknown check_unsize_tys after autoderef - " << dst << " := " << node_ptr->m_res_type); + context.equate_types_coerce(sp, dst, node_ptr); + return CoerceResult::Custom; + } + else + { + return CoerceResult::Unknown; + } case CoerceResult::Custom: return CoerceResult::Custom; case CoerceResult::Equality: @@ -6824,9 +6865,17 @@ namespace { const auto& re_inner = r.m_data.is_Borrow() ? r.m_data.as_Borrow().inner : r.m_data.as_Pointer().inner; if( le.type < re_borrow_type ) { + if( !context.m_ivars.types_equal(*le.inner, *re_inner) ) { + return DedupKeep::Both; + } + DEBUG("- Remove " << r); return DedupKeep::Left; } else if( le.type > re_borrow_type ) { + if( !context.m_ivars.types_equal(*le.inner, *re_inner) ) { + return DedupKeep::Both; + } + DEBUG("- Remove " << l); return DedupKeep::Right; } else { diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index dd6409c0..15c61bc7 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -3359,8 +3359,7 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa return ::HIR::Compare::Equal; ), (Array, - // TODO: Clone here? - return type_is_copy(sp, *e.inner); + return type_is_clone(sp, *e.inner); ) ) } -- cgit v1.2.3 From ed4d41c9762303bd06ff270593b358e8077cd534 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 1 Mar 2019 18:35:05 +0800 Subject: HIR Annotate Usage - Handle `break` --- src/hir_expand/annotate_value_usage.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/hir_expand/annotate_value_usage.cpp') diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index e763586c..5a7dfbd8 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -122,6 +122,10 @@ namespace { void visit(::HIR::ExprNode_LoopControl& node) override { // NOTE: Leaf + if( node.m_value ) + { + this->visit_node_ptr(node.m_value); + } } void visit(::HIR::ExprNode_Match& node) override { -- cgit v1.2.3 From 6490e4cdd72c03ed526a8754b48f592b453f5f25 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 15 Jun 2019 11:29:39 +0800 Subject: HIR Annotate - Handle method receivers correctly --- src/hir_expand/annotate_value_usage.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/hir_expand/annotate_value_usage.cpp') diff --git a/src/hir_expand/annotate_value_usage.cpp b/src/hir_expand/annotate_value_usage.cpp index 5a7dfbd8..5ce270bc 100644 --- a/src/hir_expand/annotate_value_usage.cpp +++ b/src/hir_expand/annotate_value_usage.cpp @@ -337,9 +337,32 @@ namespace { } void visit(::HIR::ExprNode_CallMethod& node) override { + { + assert(node.m_cache.m_fcn); + ::HIR::ValueUsage vu = ::HIR::ValueUsage::Borrow; + switch(node.m_cache.m_fcn->m_receiver) + { + case ::HIR::Function::Receiver::Free: + BUG(node.span(), "_CallMethod resolved to free function"); + case ::HIR::Function::Receiver::Value: + case ::HIR::Function::Receiver::Box: + case ::HIR::Function::Receiver::Custom: + case ::HIR::Function::Receiver::BorrowOwned: + vu = ::HIR::ValueUsage::Move; + break; + case ::HIR::Function::Receiver::BorrowUnique: + vu = ::HIR::ValueUsage::Mutate; + break; + case ::HIR::Function::Receiver::BorrowShared: + vu = ::HIR::ValueUsage::Borrow; + break; + //case ::HIR::Function::Receiver::PointerMut: + //case ::HIR::Function::Receiver::PointerConst: + } + auto _ = push_usage( vu ); + this->visit_node_ptr(node.m_value); + } auto _ = push_usage( ::HIR::ValueUsage::Move ); - - this->visit_node_ptr(node.m_value); for( auto& val : node.m_args ) this->visit_node_ptr(val); } -- cgit v1.2.3