diff options
author | John Hodge <tpg@ucc.asn.au> | 2019-02-09 22:32:40 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2019-02-09 22:32:40 +0800 |
commit | 054faa303107d5940463465d729cc0d1e2ec8473 (patch) | |
tree | 8d2c6948c3487ec4619ef51d1927ad0dc23adf60 | |
parent | f907e918d75bff4d0c5030fb5c626194c5f2dc89 (diff) | |
download | mrust-054faa303107d5940463465d729cc0d1e2ec8473.tar.gz |
Typecheck - Various fixes for librustc
-rw-r--r-- | src/hir/pattern.hpp | 4 | ||||
-rw-r--r-- | src/hir/type.cpp | 30 | ||||
-rw-r--r-- | src/hir_conv/resolve_ufcs.cpp | 5 | ||||
-rw-r--r-- | src/hir_expand/annotate_value_usage.cpp | 6 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 103 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 3 |
6 files changed, 108 insertions, 43 deletions
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.node<<"]"; - /* os << "("; for(const auto& t : e.m_arg_types) os << t << ", "; os << ") -> " << *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<T> + 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<T> 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); ) ) } |