From 76757341622b747074be74cc75aa5f4f51665f15 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 3 Nov 2018 22:08:03 +0800 Subject: HIR Typecheck - Fixing holes from 1.29 compiler_builtins --- src/hir/type.cpp | 60 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'src/hir/type.cpp') diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 6f826111..434d471b 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -58,8 +58,8 @@ namespace HIR { void ::HIR::TypeRef::fmt(::std::ostream& os) const { - TU_MATCH(::HIR::TypeRef::Data, (m_data), (e), - (Infer, + TU_MATCH_HDR( (m_data), { ) + TU_ARM(m_data, Infer, e) { os << "_"; if( e.index != ~0u || e.ty_class != ::HIR::InferClass::None ) { os << "/*"; @@ -73,14 +73,14 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const } os << "*/"; } - ), - (Diverge, + } + TU_ARM(m_data, Diverge, e) { os << "!"; - ), - (Primitive, + } + TU_ARM(m_data, Primitive, e) { os << e; - ), - (Path, + } + TU_ARM(m_data, Path, e) { os << e.path; TU_MATCH(::HIR::TypeRef::TypePathBinding, (e.binding), (be), (Unbound, os << "/*?*/";), @@ -89,8 +89,8 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const (Union, os << "/*U*/";), (Enum, os << "/*E*/";) ) - ), - (Generic, + } + TU_ARM(m_data, Generic, e) { os << e.name << "/*"; if( e.binding == 0xFFFF ) os << ""; @@ -103,8 +103,8 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const else os << e.binding; os << "*/"; - ), - (TraitObject, + } + TU_ARM(m_data, TraitObject, e) { os << "dyn ("; if( e.m_trait.m_path != ::HIR::GenericPath() ) { @@ -115,8 +115,8 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const if( e.m_lifetime != LifetimeRef::new_static() ) os << "+" << e.m_lifetime; os << ")"; - ), - (ErasedType, + } + TU_ARM(m_data, ErasedType, e) { os << "impl "; for(const auto& tr : e.m_traits) { if( &tr != &e.m_traits[0] ) @@ -126,25 +126,25 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const if( e.m_lifetime != LifetimeRef::new_static() ) os << "+ '" << e.m_lifetime; os << "/*" << e.m_origin << "#" << e.m_index << "*/"; - ), - (Array, + } + TU_ARM(m_data, Array, e) { os << "[" << *e.inner << "; "; if( e.size_val != ~0u ) os << e.size_val; else os << "/*sz*/"; os << "]"; - ), - (Slice, + } + TU_ARM(m_data, Slice, e) { os << "[" << *e.inner << "]"; - ), - (Tuple, + } + TU_ARM(m_data, Tuple, e) { os << "("; for(const auto& t : e) os << t << ", "; os << ")"; - ), - (Borrow, + } + TU_ARM(m_data, Borrow, e) { switch(e.type) { case ::HIR::BorrowType::Shared: os << "&"; break; @@ -152,8 +152,8 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const case ::HIR::BorrowType::Owned: os << "&move "; break; } os << *e.inner; - ), - (Pointer, + } + TU_ARM(m_data, Pointer, e) { switch(e.type) { case ::HIR::BorrowType::Shared: os << "*const "; break; @@ -161,8 +161,8 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const case ::HIR::BorrowType::Owned: os << "*move "; break; } os << *e.inner; - ), - (Function, + } + TU_ARM(m_data, Function, e) { if( e.is_unsafe ) { os << "unsafe "; } @@ -173,8 +173,8 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const for(const auto& t : e.m_arg_types) os << t << ", "; os << ") -> " << *e.m_rettype; - ), - (Closure, + } + TU_ARM(m_data, Closure, e) { os << "closure["< " << *e.m_rettype; */ - ) - ) + } + } } bool ::HIR::TypeRef::operator==(const ::HIR::TypeRef& x) const -- cgit v1.2.3 From 2a2b29e747d5cf06f930c1b6c671628f1d9e5cb6 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 9 Dec 2018 08:23:12 +0800 Subject: HIR Types - Comment out an overly-verbose log message --- src/hir/type.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/hir/type.cpp') diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 434d471b..2c24e3e1 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -889,7 +889,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x } ::HIR::Compare HIR::TypeRef::compare_with_placeholders(const Span& sp, const ::HIR::TypeRef& x, t_cb_resolve_type resolve_placeholder) const { - TRACE_FUNCTION_F(*this << " ?= " << x); + //TRACE_FUNCTION_F(*this << " ?= " << x); const auto& left = (m_data.is_Infer() || m_data.is_Generic() ? resolve_placeholder(*this) : *this); //const auto& left = *this; const auto& right = (x.m_data.is_Infer() ? resolve_placeholder(x) : (x.m_data.is_Generic() ? resolve_placeholder(x) : x)); -- cgit v1.2.3 From 42b9c8704fe4aab25e8f9d0cca15a74b025eee43 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 3 Feb 2019 17:48:32 +0800 Subject: HIR - Minimally-tested support for `extern { type }` --- src/hir/from_ast.cpp | 10 ++++++++ src/hir/hir.hpp | 8 +++++++ src/hir/serialise.cpp | 9 ++++++++ src/hir/type.cpp | 2 ++ src/hir/type.hpp | 2 ++ src/hir/visitor.cpp | 3 +++ src/hir_conv/bind.cpp | 4 ++++ src/hir_conv/constant_evaluation.cpp | 2 ++ src/hir_conv/markings.cpp | 1 + src/hir_typeck/expr_check.cpp | 9 ++++++++ src/hir_typeck/expr_cs.cpp | 18 +++++++++++++++ src/hir_typeck/helpers.cpp | 13 +++++++++++ src/hir_typeck/outer.cpp | 4 ++++ src/hir_typeck/static.cpp | 15 ++++++++++++ src/mir/from_hir.cpp | 3 +++ src/mir/from_hir_match.cpp | 15 ++++++++++++ src/resolve/absolute.cpp | 44 +++++++++++++++++------------------- src/resolve/index.cpp | 13 ++++++++++- src/resolve/use.cpp | 3 +++ src/trans/auto_impls.cpp | 6 ++--- src/trans/codegen.cpp | 3 +++ src/trans/codegen_c.cpp | 11 +++++++++ src/trans/enumerate.cpp | 16 ++++++------- 23 files changed, 178 insertions(+), 36 deletions(-) (limited to 'src/hir/type.cpp') diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 768593c4..fb8096f7 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -1187,6 +1187,7 @@ namespace { ::std::vector< ::HIR::TraitPath> trait_bounds; ::std::string lifetime_bound; auto gps = LowerHIR_GenericParams(i.params(), &is_sized); + for(auto& b : gps.m_bounds) { TU_MATCH(::HIR::GenericBound, (b), (be), @@ -1463,6 +1464,15 @@ void _add_mod_val_item(::HIR::Module& mod, ::std::string name, bool is_pub, ::H _add_mod_ns_item( mod, item.name, item.is_pub, ::HIR::TypeItem::make_Import({ ::HIR::SimplePath(e.name, {}), false, 0} ) ); ), (Type, + if( e.type().m_data.is_Any() ) + { + if( !e.params().lft_params().empty() || !e.params().ty_params().empty() || !e.params().bounds().empty() ) + { + ERROR(item.data.span, E0000, "Generics on extern type"); + } + _add_mod_ns_item(mod, item.name, item.is_pub, ::HIR::ExternType {}); + break; + } _add_mod_ns_item( mod, item.name, item.is_pub, ::HIR::TypeItem::make_TypeAlias( LowerHIR_TypeAlias(e) ) ); ), (Struct, diff --git a/src/hir/hir.hpp b/src/hir/hir.hpp index fc4a19e8..48787583 100644 --- a/src/hir/hir.hpp +++ b/src/hir/hir.hpp @@ -215,6 +215,13 @@ struct StructMarkings unsigned int coerce_param = ~0u; }; +class ExternType +{ +public: + // TODO: do extern types need any associated data? + TraitMarkings m_markings; +}; + class Enum { public: @@ -367,6 +374,7 @@ TAGGED_UNION(TypeItem, Import, (Import, struct { ::HIR::SimplePath path; bool is_variant; unsigned int idx; }), (Module, Module), (TypeAlias, TypeAlias), // NOTE: These don't introduce new values + (ExternType, ExternType), (Enum, Enum), (Struct, Struct), (Union, Union), diff --git a/src/hir/serialise.cpp b/src/hir/serialise.cpp index c91cf93f..e5fe8ed5 100644 --- a/src/hir/serialise.cpp +++ b/src/hir/serialise.cpp @@ -834,6 +834,10 @@ (Union, m_out.write_tag(6); serialise(e); + ), + (ExternType, + m_out.write_tag(7); + serialise(e); ) ) } @@ -1020,6 +1024,11 @@ serialise(item.m_markings); } + void serialise(const ::HIR::ExternType& item) + { + TRACE_FUNCTION_F("ExternType"); + serialise(item.m_markings); + } void serialise(const ::HIR::Trait& item) { TRACE_FUNCTION_F("_trait:"); diff --git a/src/hir/type.cpp b/src/hir/type.cpp index 2c24e3e1..981ed0b3 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -85,6 +85,7 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const TU_MATCH(::HIR::TypeRef::TypePathBinding, (e.binding), (be), (Unbound, os << "/*?*/";), (Opaque, os << "/*O*/";), + (ExternType, os << "/*X*/";), (Struct, os << "/*S*/";), (Union, os << "/*U*/";), (Enum, os << "/*E*/";) @@ -782,6 +783,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x TU_MATCH(::HIR::TypeRef::TypePathBinding, (*this), (e), (Unbound, return ::HIR::TypeRef::TypePathBinding::make_Unbound({}); ), (Opaque , return ::HIR::TypeRef::TypePathBinding::make_Opaque({}); ), + (ExternType, return ::HIR::TypeRef::TypePathBinding(e); ), (Struct, return ::HIR::TypeRef::TypePathBinding(e); ), (Union , return ::HIR::TypeRef::TypePathBinding(e); ), (Enum , return ::HIR::TypeRef::TypePathBinding(e); ) diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 480b32c4..0c98773f 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -19,6 +19,7 @@ namespace HIR { +class ExternType; class Struct; class Union; class Enum; @@ -152,6 +153,7 @@ public: TAGGED_UNION_EX(TypePathBinding, (), Unbound, ( (Unbound, struct {}), // Not yet bound, either during lowering OR during resolution (when associated and still being resolved) (Opaque, struct {}), // Opaque, i.e. An associated type of a generic (or Self in a trait) + (ExternType, const ::HIR::ExternType*), (Struct, const ::HIR::Struct*), (Union, const ::HIR::Union*), (Enum, const ::HIR::Enum*) diff --git a/src/hir/visitor.cpp b/src/hir/visitor.cpp index 5c9c0dfa..f23bae88 100644 --- a/src/hir/visitor.cpp +++ b/src/hir/visitor.cpp @@ -47,6 +47,9 @@ void ::HIR::Visitor::visit_module(::HIR::ItemPath p, ::HIR::Module& mod) DEBUG("type " << name); this->visit_type_alias(p + name, e); ), + (ExternType, + DEBUG("extern type " << name); + ), (Enum, DEBUG("enum " << name); this->visit_enum(p + name, e); diff --git a/src/hir_conv/bind.cpp b/src/hir_conv/bind.cpp index 9b5043f4..b616a64f 100644 --- a/src/hir_conv/bind.cpp +++ b/src/hir_conv/bind.cpp @@ -456,6 +456,10 @@ namespace { (TypeAlias, BUG(sp, "TypeAlias encountered after `Resolve Type Aliases` - " << ty); ), + (ExternType, + e.binding = ::HIR::TypeRef::TypePathBinding::make_ExternType(&e3); + DEBUG("- " << ty); + ), (Struct, fix_param_count(sp, pe, e3.m_params, pe.m_params); e.binding = ::HIR::TypeRef::TypePathBinding::make_Struct(&e3); diff --git a/src/hir_conv/constant_evaluation.cpp b/src/hir_conv/constant_evaluation.cpp index 43a64bbb..3d1bf4a5 100644 --- a/src/hir_conv/constant_evaluation.cpp +++ b/src/hir_conv/constant_evaluation.cpp @@ -169,6 +169,8 @@ namespace { ), (Enum, ), + (ExternType, + ), (TypeAlias, ) ) diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp index df7fbd36..d43db2b5 100644 --- a/src/hir_conv/markings.cpp +++ b/src/hir_conv/markings.cpp @@ -333,6 +333,7 @@ public: TU_MATCHA( (te.binding), (tpb), (Unbound, ), (Opaque, ), + (ExternType, markings_ptr = &tpb->m_markings; ), (Struct, markings_ptr = &tpb->m_markings; ), (Union , markings_ptr = &tpb->m_markings; ), (Enum , markings_ptr = &tpb->m_markings; ) diff --git a/src/hir_typeck/expr_check.cpp b/src/hir_typeck/expr_check.cpp index adb3c426..7d5a9c6f 100644 --- a/src/hir_typeck/expr_check.cpp +++ b/src/hir_typeck/expr_check.cpp @@ -462,6 +462,9 @@ namespace { (Union, BUG(sp, "Union in TupleVariant"); ), + (ExternType, + BUG(sp, "ExternType in TupleVariant"); + ), (Struct, ASSERT_BUG(sp, e->m_data.is_Tuple(), "Pointed struct in TupleVariant (" << node.m_path << ") isn't a Tuple"); fields_ptr = &e->m_data.as_Tuple(); @@ -522,6 +525,9 @@ namespace { (Union, TODO(sp, "Union in StructLiteral"); ), + (ExternType, + BUG(sp, "ExternType in StructLiteral"); + ), (Struct, if( e->m_data.is_Unit() ) { @@ -611,6 +617,9 @@ namespace { (Union, BUG(sp, "Union with _UnitVariant"); ), + (ExternType, + BUG(sp, "ExternType with _UnitVariant"); + ), (Struct, assert( e->m_data.is_Unit() ); ) diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 4a53bd4d..291dcd84 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -1144,6 +1144,9 @@ namespace { ), (Union, BUG(sp, "TupleVariant pointing to a union"); + ), + (ExternType, + BUG(sp, "TupleVariant pointing to a extern type"); ) ) assert(fields_ptr); @@ -1216,6 +1219,7 @@ namespace { TU_MATCH(::HIR::TypeRef::TypePathBinding, (ty.m_data.as_Path().binding), (e), (Unbound, ), (Opaque, ), + (ExternType, ), // Error? (Enum, const auto& var_name = ty_path.m_path.m_components.back(); const auto& enm = *e; @@ -4900,6 +4904,10 @@ void Context::require_sized(const Span& sp, const ::HIR::TypeRef& ty_) // Already checked by type_is_sized params_def = nullptr; ), + (ExternType, + static ::HIR::GenericParams empty_params; + params_def = &empty_params; + ), (Enum, params_def = &pb->m_params; ), @@ -5551,6 +5559,13 @@ namespace { (Opaque, // Handled above in bounded ), + (ExternType, + // Must be equal + if( sbe == dbe ) + { + return CoerceResult::Equality; + } + ), (Enum, // Must be equal if( sbe == dbe ) @@ -6474,6 +6489,9 @@ namespace { // TODO: Check bounds? return false; ), + (ExternType, + return false; + ), (Struct, if(pbe_a != pbe_b) return false; if( !pbe_a->m_struct_markings.can_unsize ) diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 1af269ad..5c0696e3 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -2477,6 +2477,9 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, ), (Opaque, ), + (ExternType, + markings = &tpb->m_markings; + ), (Struct, markings = &tpb->m_markings; ), @@ -2710,6 +2713,9 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, ), (Union, TODO(sp, "Check auto trait destructure on union " << type); + ), + (ExternType, + TODO(sp, "Check auto trait destructure on extern type " << type); ) ) DEBUG("- Nothing failed, calling callback"); @@ -3141,6 +3147,10 @@ bool TraitResolution::trait_contains_type(const Span& sp, const ::HIR::GenericPa (Opaque, // TODO: Check bounds ), + (ExternType, + // Is it sized? No. + return ::HIR::Compare::Unequal; + ), (Enum, // HAS to be Sized ), @@ -4323,6 +4333,9 @@ bool TraitResolution::find_field(const Span& sp, const ::HIR::TypeRef& ty, const (Enum, // No fields on enums either ), + (ExternType, + // No fields on extern types + ), (Union, const auto& unm = *be; const auto& params = e.path.m_data.as_Generic().m_params; diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index 63e92d8b..6a8e8b35 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -52,6 +52,10 @@ namespace { (TypeAlias, BUG(sp, "Type path pointed to type alias - " << path); ), + (ExternType, + static ::HIR::GenericParams empty_params; + return empty_params; + ), (Module, BUG(sp, "Type path pointed to module - " << path); ), diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 457bd44e..ce7faf6c 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -851,6 +851,9 @@ bool StaticTraitResolve::find_impl__check_crate( ), (Union, TODO(sp, "Check auto trait destructure on union " << type); + ), + (ExternType, + TODO(sp, "Check auto trait destructure on extern type " << type); ) ) DEBUG("- Nothing failed, calling callback"); @@ -1629,6 +1632,10 @@ bool StaticTraitResolve::type_is_sized(const Span& sp, const ::HIR::TypeRef& ty) return false; } ), + (ExternType, + // Extern types aren't Sized + return false; + ), (Enum, ), (Union, @@ -1732,6 +1739,10 @@ bool StaticTraitResolve::type_is_impossible(const Span& sp, const ::HIR::TypeRef (Union, // TODO: Check all variants? Or just one? TODO(sp, "type_is_impossible for union " << ty); + ), + (ExternType, + // Extern types are possible, just not usable + return false; ) ) return true; @@ -2032,6 +2043,10 @@ bool StaticTraitResolve::type_needs_drop_glue(const Span& sp, const ::HIR::TypeR (Union, // Unions don't have drop glue unless they impl Drop return false; + ), + (ExternType, + // Extern types don't have drop glue + return false; ) ) ), diff --git a/src/mir/from_hir.cpp b/src/mir/from_hir.cpp index 9ce40a74..fb214dda 100644 --- a/src/mir/from_hir.cpp +++ b/src/mir/from_hir.cpp @@ -2405,6 +2405,9 @@ namespace { TU_ARMA(Union, e) { BUG(node.span(), "_StructLiteral Union isn't valid?"); } + TU_ARMA(ExternType, e) { + BUG(node.span(), "_StructLiteral ExternType isn't valid?"); + } TU_ARMA(Struct, e) { if(e->m_data.is_Unit()) { m_builder.set_result( node.span(), ::MIR::RValue::make_Struct({ diff --git a/src/mir/from_hir_match.cpp b/src/mir/from_hir_match.cpp index 264c74c5..6fb77a3b 100644 --- a/src/mir/from_hir_match.cpp +++ b/src/mir/from_hir_match.cpp @@ -802,6 +802,9 @@ void PatternRulesetBuilder::append_from_lit(const Span& sp, const ::HIR::Literal ) ) ), + (ExternType, + TODO(sp, "Match extern type"); + ), (Union, TODO(sp, "Match union"); ), @@ -1217,6 +1220,9 @@ void PatternRulesetBuilder::append_from(const Span& sp, const ::HIR::Pattern& pa (Union, TODO(sp, "Match over union - " << ty); ), + (ExternType, + TODO(sp, "Match over extern type - " << ty); + ), (Enum, auto monomorph = [&](const auto& ty) { auto rv = monomorphise_type(sp, pbe->m_params, e.path.m_data.as_Generic().m_params, ty); @@ -1738,6 +1744,9 @@ namespace { (Opaque, BUG(sp, "Destructuring an opaque type - " << *cur_ty); ), + (ExternType, + BUG(sp, "Destructuring an extern type - " << *cur_ty); + ), (Struct, // TODO: Should this do a call to expand_associated_types? auto monomorph = [&](const auto& ty) { @@ -2173,6 +2182,9 @@ int MIR_LowerHIR_Match_Simple__GeneratePattern(MirBuilder& builder, const Span& (Union, TODO(sp, "Match over Union"); ), + (ExternType, + TODO(sp, "Match over ExternType"); + ), (Enum, auto monomorph = [&](const auto& ty) { auto rv = monomorphise_type(sp, pbe->m_params, te.path.m_data.as_Generic().m_params, ty); @@ -2827,6 +2839,9 @@ void MatchGenGrouped::gen_dispatch(const ::std::vector& rules, s (Union, TODO(sp, "Match over Union"); ), + (ExternType, + TODO(sp, "Match over ExternType - " << ty); + ), (Enum, ) ) diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp index d2609e9e..75a0857f 100644 --- a/src/resolve/absolute.cpp +++ b/src/resolve/absolute.cpp @@ -350,7 +350,7 @@ namespace auto v = mod.m_value_items.find(name); if( v != mod.m_value_items.end() ) { const auto& b = v->second.path.m_bindings.value; - if( const auto* be = b.opt_EnumVar() ) { + if( /*const auto* be =*/ b.opt_EnumVar() ) { DEBUG("- TY: Enum variant " << v->second.path); path = ::AST::Path( v->second.path ); return true; @@ -832,6 +832,9 @@ namespace { (TypeAlias, pb.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), + (ExternType, + pb.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); + ), (Struct, pb.type = ::AST::PathBinding_Type::make_Struct({nullptr, &e}); ), @@ -880,8 +883,8 @@ namespace { if( it == hmod->m_mod_items.end() ) ERROR(sp, E0000, "Couldn't find path component '" << n.name() << "' of " << path); - TU_MATCH(::HIR::TypeItem, (it->second->ent), (e), - (Import, + TU_MATCH_HDRA( (it->second->ent), {) + TU_ARMA(Import, e) { // - Update path then restart auto newpath = AST::Path(e.path.m_crate_name, {}); for(const auto& n : e.path.m_components) @@ -892,11 +895,11 @@ namespace { // TODO: Recursion limit Resolve_Absolute_Path_BindAbsolute(context, sp, mode, path); return ; - ), - (Module, + } + TU_ARMA(Module, e) { hmod = &e; - ), - (Trait, + } + TU_ARMA(Trait, e) { auto trait_path = ::AST::Path( crate.m_name, {} ); for(unsigned int j = start; j <= i; j ++) trait_path.nodes().push_back( path_abs.nodes[j].name() ); @@ -940,23 +943,15 @@ namespace { path = mv$(new_path); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (TypeAlias, - path = split_into_crate(sp, mv$(path), start, crate.m_name); - path = split_into_ufcs_ty(sp, mv$(path), i-start); - return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (Struct, - path = split_into_crate(sp, mv$(path), start, crate.m_name); - path = split_into_ufcs_ty(sp, mv$(path), i-start); - return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (Union, + } + case ::HIR::TypeItem::TAG_ExternType: + case ::HIR::TypeItem::TAG_TypeAlias: + case ::HIR::TypeItem::TAG_Struct: + case ::HIR::TypeItem::TAG_Union: path = split_into_crate(sp, mv$(path), start, crate.m_name); path = split_into_ufcs_ty(sp, mv$(path), i-start); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ), - (Enum, + TU_ARMA(Enum, e) { const auto& last_node = path_abs.nodes.back(); // If this refers to an enum variant, return the full path auto idx = e.find_variant(last_node.name()); @@ -982,8 +977,8 @@ namespace { path = split_into_crate(sp, mv$(path), start, crate.m_name); path = split_into_ufcs_ty(sp, mv$(path), i-start); return Resolve_Absolute_Path_BindUFCS(context, sp, mode, path); - ) - ) + } + } } const auto& name = path_abs.nodes.back().name(); @@ -1007,6 +1002,9 @@ namespace { (Module, path.m_bindings.type = ::AST::PathBinding_Type::make_Module({nullptr, &e}); ), + (ExternType, + path.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); + ), (TypeAlias, path.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr/*, &e*/}); ), diff --git a/src/resolve/index.cpp b/src/resolve/index.cpp index ec1fcd8d..ddeffa0c 100644 --- a/src/resolve/index.cpp +++ b/src/resolve/index.cpp @@ -241,7 +241,15 @@ void Resolve_Index_Module_Base(const AST::Crate& crate, AST::Module& mod) i.is_pub, i_data.name, mv$(path), e.mac }); } - // TODO: Other imports (e.g. derives, which have different naming structures) + TU_ARMA(ProcMacro, e) { + TODO(sp, "ProcMacro import"); + } + TU_ARMA(ProcMacroAttribute, e) { + TODO(sp, "ProcMacroAttribute import"); + } + TU_ARMA(ProcMacroDerive, e) { + TODO(sp, "ProcMacroDerive import"); + } }} } else @@ -318,6 +326,9 @@ void Resolve_Index_Module_Wildcard__glob_in_hir_mod(const Span& sp, const AST::C p.m_bindings.type = ::AST::PathBinding_Type::make_Enum({nullptr}); ), (TypeAlias, + p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); + ), + (ExternType, p.m_bindings.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); ) ) diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp index 8c9266a2..95e6d2c1 100644 --- a/src/resolve/use.cpp +++ b/src/resolve/use.cpp @@ -645,6 +645,9 @@ namespace { (TypeAlias, rv.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); ), + (ExternType, + rv.type = ::AST::PathBinding_Type::make_TypeAlias({nullptr}); // Lazy. + ), (Enum, rv.type = ::AST::PathBinding_Type::make_Enum({nullptr, &e}); ), diff --git a/src/trans/auto_impls.cpp b/src/trans/auto_impls.cpp index 418a338b..877659b2 100644 --- a/src/trans/auto_impls.cpp +++ b/src/trans/auto_impls.cpp @@ -74,7 +74,7 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) // For each field of the tuple, create a clone (either using Copy if posible, or calling Clone::clone) for(const auto& subty : te) { - auto fld_lvalue = ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({ 0 })) })), values.size() }); + auto fld_lvalue = ::MIR::LValue::make_Field({ box$(::MIR::LValue::make_Deref({ box$(::MIR::LValue::make_Argument({ 0 })) })), static_cast(values.size()) }); if( state.resolve.type_is_copy(sp, subty) ) { values.push_back( ::std::move(fld_lvalue) ); @@ -94,8 +94,8 @@ void Trans_AutoImpl_Clone(State& state, ::HIR::TypeRef ty) ::MIR::RValue::make_Borrow({ 0, ::HIR::BorrowType::Shared, mv$(fld_lvalue) }) })); bb.terminator = ::MIR::Terminator::make_Call({ - mir_fcn.blocks.size() + 2, // return block (after the panic block below) - mir_fcn.blocks.size() + 1, // panic block (next block) + static_cast(mir_fcn.blocks.size() + 2), // return block (after the panic block below) + static_cast(mir_fcn.blocks.size() + 1), // panic block (next block) res_lv.clone(), ::MIR::CallTarget( ::HIR::Path(subty.clone(), lang_Clone, "clone") ), ::make_vec1<::MIR::Param>( ::std::move(borrow_lv) ) diff --git a/src/trans/codegen.cpp b/src/trans/codegen.cpp index 9e93caba..b2b614a9 100644 --- a/src/trans/codegen.cpp +++ b/src/trans/codegen.cpp @@ -43,6 +43,9 @@ void Trans_Codegen(const ::std::string& outfile, const TransOptions& opt, const TU_MATCHA( (te.binding), (tpb), (Unbound, throw ""; ), (Opaque, throw ""; ), + (ExternType, + //codegen->emit_extern_type(sp, te.path.m_data.as_Generic(), *tpb); + ), (Struct, codegen->emit_struct(sp, te.path.m_data.as_Generic(), *tpb); ), diff --git a/src/trans/codegen_c.cpp b/src/trans/codegen_c.cpp index 2c40c991..979da88d 100644 --- a/src/trans/codegen_c.cpp +++ b/src/trans/codegen_c.cpp @@ -1013,6 +1013,9 @@ namespace { (Struct, m_of << "struct s_" << Trans_Mangle(te.path) << ";\n"; ), + (ExternType, + m_of << "struct x_" << Trans_Mangle(te.path) << ";\n"; + ), (Union, m_of << "union u_" << Trans_Mangle(te.path) << ";\n"; ), @@ -1837,6 +1840,7 @@ namespace { TU_MATCHA((te.binding), (pbe), (Unbound, MIR_BUG(*m_mir_res, "Unbound type path " << ty); ), (Opaque, MIR_BUG(*m_mir_res, "Opaque type path " << ty); ), + (ExternType, MIR_BUG(*m_mir_res, "Extern type literal " << ty); ), (Struct, TU_MATCHA( (pbe->m_data), (se), (Unit, @@ -5351,6 +5355,9 @@ namespace { TU_MATCHA((te.binding), (pbe), (Unbound, MIR_BUG(*m_mir_res, "Unbound type path " << ty); ), (Opaque, MIR_BUG(*m_mir_res, "Opaque type path " << ty); ), + (ExternType, + MIR_BUG(*m_mir_res, "Extern type literal"); + ), (Struct, TU_MATCHA( (pbe->m_data), (se), (Unit, @@ -5835,6 +5842,10 @@ namespace { (Enum, m_of << "struct e_" << Trans_Mangle(te.path); ), + (ExternType, + m_of << "struct x_" << Trans_Mangle(te.path); + //return ; + ), (Unbound, MIR_BUG(*m_mir_res, "Unbound type path in trans - " << ty); ), diff --git a/src/trans/enumerate.cpp b/src/trans/enumerate.cpp index 6aeb3485..c326d125 100644 --- a/src/trans/enumerate.cpp +++ b/src/trans/enumerate.cpp @@ -570,6 +570,9 @@ namespace { (Opaque, BUG(Span(), "Opaque type hit in enumeration - " << ty); ), + (ExternType, + // No innards to visit + ), (Struct, visit_struct(te.path.m_data.as_Generic(), *tpb); ), @@ -1064,15 +1067,10 @@ void Trans_Enumerate_Types(EnumState& state) TU_MATCHA( (te.binding), (tpb), (Unbound, ), (Opaque, ), - (Struct, - markings_ptr = &tpb->m_markings; - ), - (Union, - markings_ptr = &tpb->m_markings; - ), - (Enum, - markings_ptr = &tpb->m_markings; - ) + (ExternType, markings_ptr = &tpb->m_markings; ), + (Struct, markings_ptr = &tpb->m_markings; ), + (Union, markings_ptr = &tpb->m_markings; ), + (Enum, markings_ptr = &tpb->m_markings; ) ) ASSERT_BUG(Span(), markings_ptr, "Path binding not set correctly - " << ty); -- 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/type.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 7dca0b4a6ff1158edf1ab17772e96bab488c1b32 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 20 Apr 2019 11:50:34 +0800 Subject: HIR Typecheck - Bulk commit of typecheck fixes, less magic --- src/hir/type.cpp | 14 ++ src/hir/type.hpp | 3 + src/hir_typeck/expr_cs.cpp | 441 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 441 insertions(+), 17 deletions(-) (limited to 'src/hir/type.cpp') diff --git a/src/hir/type.cpp b/src/hir/type.cpp index ff4742e6..ccd5cd21 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -789,6 +789,20 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x assert(!"Fell off end of clone_binding"); throw ""; } +bool HIR::TypeRef::TypePathBinding::operator==(const HIR::TypeRef::TypePathBinding& x) const +{ + if( this->tag() != x.tag() ) + return false; + TU_MATCH(::HIR::TypeRef::TypePathBinding, (*this, x), (te, xe), + (Unbound, return true;), + (Opaque, return true;), + (ExternType, return te == xe;), + (Struct, return te == xe;), + (Union , return te == xe;), + (Enum , return te == xe;) + ) + throw ""; +} ::HIR::TypeRef HIR::TypeRef::clone() const diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 0c98773f..2fc1179d 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -159,6 +159,9 @@ public: (Enum, const ::HIR::Enum*) ), (), (), ( TypePathBinding clone() const; + + bool operator==(const TypePathBinding& x) const; + bool operator!=(const TypePathBinding& x) const { return !(*this == x); } ) ); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index f012386e..641dddc5 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -3064,7 +3064,7 @@ namespace { void no_revisit(::HIR::ExprNode& node) { BUG(node.span(), "Node revisit unexpected - " << typeid(node).name()); } - }; + }; // class ExprVisitor_Revisit // ----------------------------------------------------------------------- // Post-inferrence visitor @@ -3379,7 +3379,133 @@ namespace { // All good } } - }; + }; // class ExprVisitor_Apply + + class ExprVisitor_Print: + public ::HIR::ExprVisitor + { + const Context& context; + ::std::ostream& m_os; + public: + ExprVisitor_Print(const Context& context, ::std::ostream& os): + context(context), + m_os(os) + {} + + void visit(::HIR::ExprNode_Block& node) override { + m_os << "_Block {" << context.m_ivars.fmt_type(node.m_nodes.back()->m_res_type) << "}"; + } + void visit(::HIR::ExprNode_Asm& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Return& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Let& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Loop& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_LoopControl& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Match& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_If& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Assign& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_BinOp& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_UniOp& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Borrow& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Cast& node) override { + m_os << "_Cast {" << context.m_ivars.fmt_type(node.m_value->m_res_type) << "}"; + } + void visit(::HIR::ExprNode_Unsize& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Index& node) override { + m_os << "_Index {" << fmt_res_ty(*node.m_value) << "}[{" << fmt_res_ty(*node.m_index) << "}]"; + } + void visit(::HIR::ExprNode_Deref& node) override { + m_os << "_Deref {" << fmt_res_ty(*node.m_value) << "}"; + } + void visit(::HIR::ExprNode_Emplace& node) override { + m_os << "_Emplace(" << fmt_res_ty(*node.m_value) << " in " << fmt_res_ty(*node.m_place) << ")"; + } + + void visit(::HIR::ExprNode_TupleVariant& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_CallPath& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_CallValue& node) override { + m_os << "_CallValue {" << fmt_res_ty(*node.m_value) << "}("; + for(const auto& arg : node.m_args) + m_os << "{" << fmt_res_ty(*arg) << "}, "; + m_os << ")"; + } + void visit(::HIR::ExprNode_CallMethod& node) override { + m_os << "_CallMethod {" << fmt_res_ty(*node.m_value) << "}." << node.m_method << "("; + for(const auto& arg : node.m_args) + m_os << "{" << fmt_res_ty(*arg) << "}, "; + m_os << ")"; + } + void visit(::HIR::ExprNode_Field& node) override { + m_os << "_Field {" << fmt_res_ty(*node.m_value) << "}." << node.m_field; + } + + void visit(::HIR::ExprNode_Literal& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_UnitVariant& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_PathValue& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Variable& node) override { + no_revisit(node); + } + + void visit(::HIR::ExprNode_StructLiteral& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_UnionLiteral& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_Tuple& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_ArrayList& node) override { + no_revisit(node); + } + void visit(::HIR::ExprNode_ArraySized& node) override { + no_revisit(node); + } + + void visit(::HIR::ExprNode_Closure& node) override { + no_revisit(node); + } + private: + HMTypeInferrence::FmtType fmt_res_ty(const ::HIR::ExprNode& n) { + return context.m_ivars.fmt_type(n.m_res_type); + } + void no_revisit(::HIR::ExprNode& n) { + throw ""; + } + }; // class ExprVisitor_Print } @@ -3393,13 +3519,14 @@ void Context::dump() const { m_ivars.dump(); DEBUG("--- CS Context - " << link_coerce.size() << " Coercions, " << link_assoc.size() << " associated, " << to_visit.size() << " nodes, " << adv_revisits.size() << " callbacks"); for(const auto& v : link_coerce) { - DEBUG(v); + //DEBUG(v); + DEBUG(this->m_ivars.fmt_type(v.left_ty) << " := " << v.right_node_ptr << " " << &**v.right_node_ptr << " (" << this->m_ivars.fmt_type((*v.right_node_ptr)->m_res_type) << ")"); } for(const auto& v : link_assoc) { DEBUG(v); } for(const auto& v : to_visit) { - DEBUG(&*v << " " << typeid(*v).name() << " -> " << this->m_ivars.fmt_type(v->m_res_type)); + DEBUG(&*v << " " << FMT_CB(os, { ExprVisitor_Print ev(*this, os); v->visit(ev); }) << " -> " << this->m_ivars.fmt_type(v->m_res_type)); } for(const auto& v : adv_revisits) { DEBUG(FMT_CB(ss, v->fmt(ss);)); @@ -5403,6 +5530,18 @@ namespace { // Neither side is an ivar, keep going. } + // If either side is an unbound path, then return Unknown + if( TU_TEST1(src.m_data, Path, .binding.is_Unbound()) ) + { + DEBUG("Source unbound path"); + return CoerceResult::Unknown; + } + if( TU_TEST1(dst.m_data, Path, .binding.is_Unbound()) ) + { + DEBUG("Destination unbound path"); + return CoerceResult::Unknown; + } + // Array unsize (quicker than going into deref search) if(dst.m_data.is_Slice() && src.m_data.is_Array()) { @@ -6652,18 +6791,34 @@ namespace { return false; } + enum class IvarPossFallbackType { + None, // No fallback, only make safe decisions + Assume, // Picks an option, even if there's non source/destination types + IgnoreWeakDisable, // Ignores the weaker disable flags + }; + ::std::ostream& operator<<(::std::ostream& os, IvarPossFallbackType t) { + switch(t) + { + case IvarPossFallbackType::None: os << ""; break; + case IvarPossFallbackType::Assume: os << " weak"; break; + case IvarPossFallbackType::IgnoreWeakDisable: os << " unblock"; break; + } + return os; + } /// Check IVar possibilities, from both coercion/unsizing (which have well-encoded rules) and from trait impls - bool check_ivar_poss(Context& context, unsigned int i, Context::IVarPossible& ivar_ent, bool honour_disable=true) + bool check_ivar_poss(Context& context, unsigned int i, Context::IVarPossible& ivar_ent, IvarPossFallbackType fallback_ty=IvarPossFallbackType::None) { static Span _span; const auto& sp = _span; + const bool honour_disable = (fallback_ty != IvarPossFallbackType::IgnoreWeakDisable); if( ivar_ent.force_disable ) { DEBUG(i << ": forced unknown"); return false; } - if( honour_disable && (ivar_ent.force_no_to || ivar_ent.force_no_from) ) + // TODO: This shouldn't just return, it should instead add a placeholder possibility + if( fallback_ty != IvarPossFallbackType::IgnoreWeakDisable && (ivar_ent.force_no_to || ivar_ent.force_no_from) ) { DEBUG(i << ": coercion blocked"); return false; @@ -6693,7 +6848,7 @@ namespace { return false; } - TRACE_FUNCTION_F(i << (honour_disable ? "" : " fallback") << " - " << ty_l); + TRACE_FUNCTION_F(i << fallback_ty << " - " << ty_l); bool has_no_coerce_posiblities; @@ -6701,6 +6856,7 @@ namespace { // Fill a single list with all possibilities, and pick the most suitable type. // - This list needs to include flags to say if the type can be dereferenced. { + // TODO: Move this to its own function. struct PossibleType { bool is_pointer; // I.e. it's from a coerce bool can_deref; // I.e. from an unsize or coerce, AND it's a "from" @@ -6750,7 +6906,7 @@ namespace { } // If exactly the same type is both a source and destination, equate. - // NOTE: Not correct, especially when there's ivars in the list which could become a destination + // - This is always correct, even if one of the types is an ivar (you can't go A -> B -> A with a coercion) { for(const auto& ent : possible_tys) { @@ -6758,10 +6914,12 @@ namespace { continue ; for(const auto& ent2 : possible_tys) { - if( &ent2 == &ent ) - break; - if( ent.can_deref ) + if( &ent == &ent2 ) { + continue; + } + if( ent2.can_deref ) { continue ; + } if( *ent.ty == *ent2.ty ) { DEBUG("- Source/Destination type"); context.equate_types(sp, ty_l, *ent.ty); @@ -6974,6 +7132,7 @@ namespace { // If there's multiple source types (which means that this ivar has to be a coercion from one of them) // Look for the least permissive of the available destination types and assign to that #if 1 + // NOTE: This only works for coercions (not usizings), so is restricted to all options being pointers if( ::std::all_of(possible_tys.begin(), possible_tys.end(), [](const auto& ent){ return ent.is_pointer; }) //|| ::std::none_of(possible_tys.begin(), possible_tys.end(), [](const auto& ent){ return ent.is_pointer; }) ) @@ -7045,11 +7204,192 @@ namespace { return true; } } -#endif + #endif + + // TODO: Remove any types that are covered by another type + // - E.g. &[T] and &[U] can be considered equal, because [T] can't unsize again + // - Comparison function: Returns one of Incomparible,Less,Same,More - Representing the amount of type information present. + { + struct InfoOrdering + { + enum Ordering { + Incompatible, // The types are incompatible + Less, // The LHS type provides less information (e.g. has more ivars) + Same, // Same number of ivars + More, // The RHS provides more information (less ivars) + }; + static bool is_infer(const ::HIR::TypeRef& ty) { + if( ty.m_data.is_Infer() ) + return true; + if( TU_TEST1(ty.m_data, Path, .binding.is_Unbound()) ) + return true; + return false; + } + static Ordering compare(const ::HIR::TypeRef& ty_l, const ::HIR::TypeRef& ty_r) { + if( is_infer(ty_l) ) { + if( is_infer(ty_r) ) + return Same; + return Less; + } + else { + if( is_infer(ty_r) ) + return More; + } + if( ty_l.m_data.tag() != ty_r.m_data.tag() ) { + return Incompatible; + } + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_l.m_data, ty_r.m_data), (le, re), + ( + return Incompatible; + ), + (Tuple, + if( le.size() != re.size() ) + return Incompatible; + int score = 0; + for(size_t i = 0; i < le.size(); i ++) + { + switch(compare(le[i], re[i])) + { + case Incompatible: + return Incompatible; + case Less: score --; break; + case Same: break; + case More: score ++; break; + } + } + if( score < 0 ) + return Less; + else if( score > 0 ) + return More; + else + return Same; + ) + ) + } + static Ordering compare_top(const Context& context, const ::HIR::TypeRef& ty_l, const ::HIR::TypeRef& ty_r, bool should_deref) { + if( context.m_ivars.types_equal(ty_l, ty_r) ) + return Same; + if( is_infer(ty_l) ) + return Incompatible; + if( is_infer(ty_r) ) + return Incompatible; + if( ty_l.m_data.tag() != ty_r.m_data.tag() ) { + return Incompatible; + } + if( should_deref ) { + if( const auto* le = ty_l.m_data.opt_Borrow() ) { + const auto& re = ty_r.m_data.as_Borrow(); + if( le->type != re.type ) + return Incompatible; + return compare_top(context, context.m_ivars.get_type(*le->inner), context.m_ivars.get_type(*re.inner), false); + } + else if( const auto* le = ty_l.m_data.opt_Pointer() ) { + const auto& re = ty_r.m_data.as_Pointer(); + if( le->type != re.type ) + return Incompatible; + return compare_top(context, context.m_ivars.get_type(*le->inner), context.m_ivars.get_type(*re.inner), false); + } + else if( TU_TEST2(ty_l.m_data, Path, .binding, Struct, ->m_struct_markings.coerce_unsized != ::HIR::StructMarkings::Coerce::None) ) + { + const auto& le = ty_l.m_data.as_Path(); + const auto& re = ty_l.m_data.as_Path(); + if( le.binding != re.binding ) + return Incompatible; + auto param_idx = le.binding.as_Struct()->m_struct_markings.coerce_param; + assert(param_idx != ~0u); + return compare_top(context, + context.m_ivars.get_type(le.path.m_data.as_Generic().m_params.m_types.at(param_idx)), + context.m_ivars.get_type(re.path.m_data.as_Generic().m_params.m_types.at(param_idx)), + false + ); + } + else + { + BUG(Span(), "Can't deref " << ty_l << " / " << ty_r); + } + } + TU_MATCH_DEF( ::HIR::TypeRef::Data, (ty_l.m_data, ty_r.m_data), (le, re), + ( + return Incompatible; + ), + (Slice, + switch(compare(context.m_ivars.get_type(*le.inner), context.m_ivars.get_type(*re.inner))) + { + case Less: return Less; + case More: return More; + case Same: + case Incompatible: + return Same; + } + throw ""; + ) + ) + } + static const ::HIR::TypeRef& get_pointer_inner(const Context& context, const ::HIR::TypeRef& t_raw) { + const auto& t = context.m_ivars.get_type(t_raw); + if( const auto* te = t.m_data.opt_Borrow() ) { + return context.m_ivars.get_type(*te->inner); + } + else if( const auto* te = t.m_data.opt_Pointer() ) { + return context.m_ivars.get_type(*te->inner); + } + else if( TU_TEST2(t.m_data, Path, .binding, Struct, ->m_struct_markings.coerce_unsized != ::HIR::StructMarkings::Coerce::None) ) + { + const auto& te = t.m_data.as_Path(); + auto param_idx = te.binding.as_Struct()->m_struct_markings.coerce_param; + assert(param_idx != ~0u); + const auto& path = te.path.m_data.as_Generic(); + return context.m_ivars.get_type(path.m_params.m_types.at(param_idx)); + } + else { + throw ""; + //return t; + } + } + }; + + // De-duplicate destinations and sources separately + for(auto it = possible_tys.begin(); it != possible_tys.end(); ++it) + { + if( !it->ty ) + continue; + for(auto it2 = it + 1; it2 != possible_tys.end(); ++it2) + { + if( !it2->ty ) + continue; + if(it->can_deref != it2->can_deref) { + continue; + } + if(it->is_pointer != it2->is_pointer) { + continue; + } + + switch(InfoOrdering::compare_top(context, *it->ty, *it2->ty, /*should_deref=*/it->is_pointer)) + { + case InfoOrdering::Incompatible: + break; + case InfoOrdering::Less: + case InfoOrdering::Same: + DEBUG("Remove " << *it << ", keep " << *it2); + it->ty = it2->ty; + it->is_pointer = it2->is_pointer; + it2->ty = nullptr; + break; + case InfoOrdering::More: + DEBUG("Keep " << *it << ", remove " << *it2); + it2->ty = nullptr; + break; + } + } + } + auto new_end = ::std::remove_if(possible_tys.begin(), possible_tys.end(), [](const auto& e){ return e.ty == nullptr; }); + DEBUG("Removing " << (possible_tys.end() - new_end) << " redundant possibilities"); + possible_tys.erase(new_end, possible_tys.end()); + } // TODO: If in fallback mode, pick the most permissive option // - E.g. If the options are &mut T and *const T, use the *const T - if( !honour_disable ) + if( fallback_ty == IvarPossFallbackType::Assume ) { // All are coercions (not unsizings) if( ::std::all_of(possible_tys.begin(), possible_tys.end(), [](const auto& ent){ return ent.is_pointer; }) && n_ivars == 0 ) @@ -7091,9 +7431,9 @@ namespace { } } -#if 1 DEBUG("possible_tys = " << possible_tys); - DEBUG("Adding bounded [" << ivar_ent.bounded << "]"); + DEBUG("- Bounded [" << ivar_ent.bounded << "]"); +#if 1 if( !possible_tys.empty() ) { for(const auto& new_ty : ivar_ent.bounded) @@ -7125,7 +7465,10 @@ namespace { if( !failed_a_bound ) { // TODO: Don't add ivars? - if( new_ty.m_data.is_Infer() ) + if( new_ty == ty_l ) + { + } + else if( new_ty.m_data.is_Infer() ) { n_ivars += 1; } @@ -7322,6 +7665,57 @@ namespace { return true; } + // If there's no ivars, and no instances of &_ or Box<_>, then error/bug here. +#if 0 + if( possible_tys.size() > 0 ) + { + struct H { + static const ::HIR::TypeRef& get_pointer_inner(const Context& context, const ::HIR::TypeRef& t_raw) { + const auto& t = context.m_ivars.get_type(t_raw); + if( const auto* te = t.m_data.opt_Borrow() ) { + return get_pointer_inner(context, *te->inner); + } + else if( const auto* te = t.m_data.opt_Pointer() ) { + return get_pointer_inner(context, *te->inner); + } + else if( TU_TEST2(t.m_data, Path, .binding, Struct, ->m_struct_markings.coerce_unsized != ::HIR::StructMarkings::Coerce::None) ) + { + const auto& te = t.m_data.as_Path(); + auto param_idx = te.binding.as_Struct()->m_struct_markings.coerce_param; + assert(param_idx != ~0u); + const auto& path = te.path.m_data.as_Generic(); + return get_pointer_inner(context, path.m_params.m_types.at(param_idx)); + } + else { + return t; + } + } + }; + bool has_all_info = true; + if( n_ivars > 0 ) + { + has_all_info = false; + } + for(const auto& e : possible_tys) + { + const auto& inner = H::get_pointer_inner(context, *e.ty); + DEBUG(e << ", inner=" << inner); + if( inner.m_data.is_Infer() ) + { + has_all_info = false; + } + if( TU_TEST1(inner.m_data, Path, .binding.is_Unbound()) ) + { + has_all_info = false; + } + } + if( has_all_info ) + { + BUG(sp, "Sufficient information for " << ty_l << " but didn't pick a type - options are [" << possible_tys << "]"); + } + } +#endif + // If only one bound meets the possible set, use it if( ! possible_tys.empty() ) { @@ -7707,6 +8101,19 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: } } #endif + // If nothing has changed, run check_ivar_poss again but allow it to assume is has all the options + if( !context.m_ivars.peek_changed() ) + { + // Check the possible equations + DEBUG("--- IVar possibilities (fallback 1)"); + for(unsigned int i = context.possible_ivar_vals.size(); i --; ) // NOTE: Ordering is a hack for libgit2 + //for(unsigned int i = 0; i < context.possible_ivar_vals.size(); i ++ ) + { + if( check_ivar_poss(context, i, context.possible_ivar_vals[i], IvarPossFallbackType::Assume) ) { + break; + } + } + } // If nothing has changed, run check_ivar_poss again but ignoring the 'disable' flag #if 1 if( !context.m_ivars.peek_changed() ) @@ -7716,7 +8123,7 @@ void Typecheck_Code_CS(const typeck::ModuleState& ms, t_args& args, const ::HIR: for(unsigned int i = context.possible_ivar_vals.size(); i --; ) // NOTE: Ordering is a hack for libgit2 //for(unsigned int i = 0; i < context.possible_ivar_vals.size(); i ++ ) { - if( check_ivar_poss(context, i, context.possible_ivar_vals[i], /*honour_disable=*/false) ) { + if( check_ivar_poss(context, i, context.possible_ivar_vals[i], IvarPossFallbackType::IgnoreWeakDisable) ) { # if 1 break; # else -- cgit v1.2.3 From 2f2f8f04b081f89de411f9b9b2ad40ace3733983 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 4 Jun 2019 07:28:18 +0800 Subject: HIR Markings - Flag for any Copy impl --- src/hir/type.cpp | 13 +++++++++++++ src/hir/type.hpp | 3 +++ src/hir_conv/markings.cpp | 16 +++++++--------- src/hir_typeck/helpers.cpp | 19 +------------------ src/hir_typeck/static.cpp | 7 +++++++ 5 files changed, 31 insertions(+), 27 deletions(-) (limited to 'src/hir/type.cpp') diff --git a/src/hir/type.cpp b/src/hir/type.cpp index ccd5cd21..6e8eaaa9 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -804,6 +804,19 @@ bool HIR::TypeRef::TypePathBinding::operator==(const HIR::TypeRef::TypePathBindi throw ""; } +const ::HIR::TraitMarkings* HIR::TypeRef::TypePathBinding::get_trait_markings() const +{ + const ::HIR::TraitMarkings* markings_ptr = nullptr; + TU_MATCHA( (*this), (tpb), + (Unbound, ), + (Opaque, ), + (ExternType, markings_ptr = &tpb->m_markings; ), + (Struct, markings_ptr = &tpb->m_markings; ), + (Union, markings_ptr = &tpb->m_markings; ), + (Enum, markings_ptr = &tpb->m_markings; ) + ) + return markings_ptr; +} ::HIR::TypeRef HIR::TypeRef::clone() const { diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 38196a55..7a5a0a1c 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -19,6 +19,7 @@ namespace HIR { +class TraitMarkings; class ExternType; class Struct; class Union; @@ -164,6 +165,8 @@ public: ), (), (), ( TypePathBinding clone() const; + const TraitMarkings* get_trait_markings() const; + bool operator==(const TypePathBinding& x) const; bool operator!=(const TypePathBinding& x) const { return !(*this == x); } ) diff --git a/src/hir_conv/markings.cpp b/src/hir_conv/markings.cpp index d43db2b5..01eb0952 100644 --- a/src/hir_conv/markings.cpp +++ b/src/hir_conv/markings.cpp @@ -20,6 +20,7 @@ class Visitor: const ::HIR::Crate& m_crate; const ::HIR::SimplePath& m_lang_Unsize; const ::HIR::SimplePath& m_lang_CoerceUnsized; + const ::HIR::SimplePath& m_lang_Copy; const ::HIR::SimplePath& m_lang_Deref; const ::HIR::SimplePath& m_lang_Drop; const ::HIR::SimplePath& m_lang_PhantomData; @@ -28,6 +29,7 @@ public: m_crate(crate), m_lang_Unsize( crate.get_lang_item_path_opt("unsize") ), m_lang_CoerceUnsized( crate.get_lang_item_path_opt("coerce_unsized") ), + m_lang_Copy( crate.get_lang_item_path_opt("copy") ), m_lang_Deref( crate.get_lang_item_path_opt("deref") ), m_lang_Drop( crate.get_lang_item_path_opt("drop") ), m_lang_PhantomData( crate.get_lang_item_path_opt("phantom_data") ) @@ -329,15 +331,7 @@ public: if( impl.m_type.m_data.is_Path() ) { const auto& te = impl.m_type.m_data.as_Path(); - const ::HIR::TraitMarkings* markings_ptr = nullptr; - TU_MATCHA( (te.binding), (tpb), - (Unbound, ), - (Opaque, ), - (ExternType, markings_ptr = &tpb->m_markings; ), - (Struct, markings_ptr = &tpb->m_markings; ), - (Union , markings_ptr = &tpb->m_markings; ), - (Enum , markings_ptr = &tpb->m_markings; ) - ) + const ::HIR::TraitMarkings* markings_ptr = te.binding.get_trait_markings(); if( markings_ptr ) { ::HIR::TraitMarkings& markings = *const_cast<::HIR::TraitMarkings*>(markings_ptr); @@ -435,6 +429,10 @@ public: DEBUG("Type " << impl.m_type << " can Deref"); markings.has_a_deref = true; } + else if( trait_path == m_lang_Copy ) { + DEBUG("Type " << impl.m_type << " has a Copy impl"); + markings.is_copy = true; + } // TODO: Marker traits (with conditions) else { } diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 629b8bba..326ecfa9 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -2480,24 +2480,7 @@ bool TraitResolution::find_trait_impls_crate(const Span& sp, TU_IFLET( ::HIR::TypeRef::Data, (type.m_data), Path, e, if( e.path.m_data.is_Generic() && e.path.m_data.as_Generic().m_params.m_types.size() == 0 ) { - TU_MATCH( ::HIR::TypeRef::TypePathBinding, (e.binding), (tpb), - (Unbound, - ), - (Opaque, - ), - (ExternType, - markings = &tpb->m_markings; - ), - (Struct, - markings = &tpb->m_markings; - ), - (Union, - markings = &tpb->m_markings; - ), - (Enum, - markings = &tpb->m_markings; - ) - ) + markings = e.binding.get_trait_markings(); } ) diff --git a/src/hir_typeck/static.cpp b/src/hir_typeck/static.cpp index 0c0f1859..e08ea678 100644 --- a/src/hir_typeck/static.cpp +++ b/src/hir_typeck/static.cpp @@ -1469,6 +1469,13 @@ bool StaticTraitResolve::type_is_copy(const Span& sp, const ::HIR::TypeRef& ty) return rv; ), (Path, + const auto* markings = e.binding.get_trait_markings(); + if( markings && ! markings->is_copy ) + { + return false; + } + // TODO: Also have a marking that indicates that the type is unconditionally Copy + { auto it = m_copy_cache.find(ty); if( it != m_copy_cache.end() ) -- cgit v1.2.3