diff options
-rw-r--r-- | src/hir/from_ast.cpp | 2 | ||||
-rw-r--r-- | src/hir/item_path.hpp | 14 | ||||
-rw-r--r-- | src/hir/type.cpp | 4 | ||||
-rw-r--r-- | src/hir/type.hpp | 1 | ||||
-rw-r--r-- | src/hir_typeck/common.cpp | 2 | ||||
-rw-r--r-- | src/hir_typeck/expr_cs.cpp | 8 | ||||
-rw-r--r-- | src/hir_typeck/helpers.cpp | 73 | ||||
-rw-r--r-- | src/hir_typeck/outer.cpp | 52 |
8 files changed, 107 insertions, 49 deletions
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp index 78f6b683..af5e6118 100644 --- a/src/hir/from_ast.cpp +++ b/src/hir/from_ast.cpp @@ -749,7 +749,7 @@ } // Leave `m_origin` until the bind pass return ::HIR::TypeRef( ::HIR::TypeRef::Data::make_ErasedType(::HIR::TypeRef::Data::Data_ErasedType { - ::HIR::Path(::HIR::SimplePath()), + ::HIR::Path(::HIR::SimplePath()), 0, mv$(traits), ::HIR::LifetimeRef() // TODO: Lifetime ref } ) ); diff --git a/src/hir/item_path.hpp b/src/hir/item_path.hpp index 576c7755..9b579b72 100644 --- a/src/hir/item_path.hpp +++ b/src/hir/item_path.hpp @@ -48,6 +48,20 @@ public: return ::HIR::SimplePath(); } } + ::HIR::Path get_full_path() const { + assert(parent); + assert(name); + + if( parent->name ) { + return get_simple_path(); + } + else if( parent->trait ) { + return ::HIR::Path( parent->ty->clone(), ::HIR::GenericPath(parent->trait->clone(), parent->trait_params->clone()), ::std::string(name) ); + } + else { + return ::HIR::Path( parent->ty->clone(), ::std::string(name) ); + } + } const char* get_name() const { return name ? name : ""; } diff --git a/src/hir/type.cpp b/src/hir/type.cpp index e1d701ef..865607bc 100644 --- a/src/hir/type.cpp +++ b/src/hir/type.cpp @@ -119,7 +119,7 @@ void ::HIR::TypeRef::fmt(::std::ostream& os) const } if( e.m_lifetime.name != "" ) os << "+ '" << e.m_lifetime.name; - os << "/*" << e.m_origin << "*/"; + os << "/*" << e.m_origin << "#" << e.m_index << "*/"; ), (Array, os << "[" << *e.inner << "; "; @@ -786,7 +786,7 @@ bool ::HIR::TypeRef::match_test_generics(const Span& sp, const ::HIR::TypeRef& x for(const auto& trait : e.m_traits) traits.push_back( trait.clone() ); return ::HIR::TypeRef( Data::make_ErasedType({ - e.m_origin.clone(), + e.m_origin.clone(), e.m_index, mv$(traits), e.m_lifetime }) ); diff --git a/src/hir/type.hpp b/src/hir/type.hpp index 60ea04bd..653777db 100644 --- a/src/hir/type.hpp +++ b/src/hir/type.hpp @@ -141,6 +141,7 @@ public: }), (ErasedType, struct { ::HIR::Path m_origin; + unsigned int m_index; ::std::vector< ::HIR::TraitPath> m_traits; ::HIR::LifetimeRef m_lifetime; }), diff --git a/src/hir_typeck/common.cpp b/src/hir_typeck/common.cpp index 8c902bd2..79e1095e 100644 --- a/src/hir_typeck/common.cpp +++ b/src/hir_typeck/common.cpp @@ -218,7 +218,7 @@ bool monomorphise_type_needed(const ::HIR::TypeRef& tpl) traits.push_back( monomorphise_traitpath_with(sp, trait, callback, allow_infer) ); rv = ::HIR::TypeRef( ::HIR::TypeRef::Data::Data_ErasedType { - mv$(origin), + mv$(origin), e.m_index, mv$(traits), e.m_lifetime } ); diff --git a/src/hir_typeck/expr_cs.cpp b/src/hir_typeck/expr_cs.cpp index 45de4850..2996a92a 100644 --- a/src/hir_typeck/expr_cs.cpp +++ b/src/hir_typeck/expr_cs.cpp @@ -2918,6 +2918,7 @@ namespace { } ), (ErasedType, + ASSERT_BUG(sp, e.m_origin != ::HIR::SimplePath(), "ErasedType " << ty << " wasn't bound to its origin"); check_type_resolved_path(sp, e.m_origin, top_type); ), (Array, @@ -3144,7 +3145,12 @@ void Context::equate_types(const Span& sp, const ::HIR::TypeRef& li, const ::HIR // NOTE: Lifetime is ignored ), (ErasedType, - TODO(sp, "ErasedType"); + ASSERT_BUG(sp, l_e.m_origin != ::HIR::SimplePath(), "ErasedType " << l_t << " wasn't bound to its origin"); + ASSERT_BUG(sp, r_e.m_origin != ::HIR::SimplePath(), "ErasedType " << r_t << " wasn't bound to its origin"); + // TODO: Ivar equate origin + if( l_e.m_origin != r_e.m_origin ) { + ERROR(sp, E0000, "Type mismatch between " << l_t << " and " << r_t << " - different source"); + } ), (Array, this->equate_types(sp, *l_e.inner, *r_e.inner); diff --git a/src/hir_typeck/helpers.cpp b/src/hir_typeck/helpers.cpp index 48152b11..8eaf031c 100644 --- a/src/hir_typeck/helpers.cpp +++ b/src/hir_typeck/helpers.cpp @@ -340,6 +340,29 @@ void HMTypeInferrence::print_pathparams(::std::ostream& os, const ::HIR::PathPar void HMTypeInferrence::expand_ivars(::HIR::TypeRef& type) { + struct H { + static void expand_ivars_path(/*const*/ HMTypeInferrence& self, ::HIR::Path& path) + { + TU_MATCH(::HIR::Path::Data, (path.m_data), (e2), + (Generic, + self.expand_ivars_params(e2.m_params); + ), + (UfcsKnown, + self.expand_ivars(*e2.type); + self.expand_ivars_params(e2.trait.m_params); + self.expand_ivars_params(e2.params); + ), + (UfcsUnknown, + self.expand_ivars(*e2.type); + self.expand_ivars_params(e2.params); + ), + (UfcsInherent, + self.expand_ivars(*e2.type); + self.expand_ivars_params(e2.params); + ) + ) + } + }; TU_MATCH(::HIR::TypeRef::Data, (type.m_data), (e), (Infer, const auto& t = this->get_type(type); @@ -353,24 +376,7 @@ void HMTypeInferrence::expand_ivars(::HIR::TypeRef& type) ), (Path, // Iterate all arguments - TU_MATCH(::HIR::Path::Data, (e.path.m_data), (e2), - (Generic, - this->expand_ivars_params(e2.m_params); - ), - (UfcsKnown, - this->expand_ivars(*e2.type); - this->expand_ivars_params(e2.trait.m_params); - this->expand_ivars_params(e2.params); - ), - (UfcsUnknown, - this->expand_ivars(*e2.type); - this->expand_ivars_params(e2.params); - ), - (UfcsInherent, - this->expand_ivars(*e2.type); - this->expand_ivars_params(e2.params); - ) - ) + H::expand_ivars_path(*this, e.path); ), (Generic, ), @@ -378,26 +384,15 @@ void HMTypeInferrence::expand_ivars(::HIR::TypeRef& type) this->expand_ivars_params(e.m_trait.m_path.m_params); for(auto& marker : e.m_markers) this->expand_ivars_params(marker.m_params); + // TODO: Associated types ), (ErasedType, - TU_MATCH(::HIR::Path::Data, (e.m_origin.m_data), (e2), - (Generic, - this->expand_ivars_params(e2.m_params); - ), - (UfcsKnown, - this->expand_ivars(*e2.type); - this->expand_ivars_params(e2.trait.m_params); - this->expand_ivars_params(e2.params); - ), - (UfcsUnknown, - this->expand_ivars(*e2.type); - this->expand_ivars_params(e2.params); - ), - (UfcsInherent, - this->expand_ivars(*e2.type); - this->expand_ivars_params(e2.params); - ) - ) + H::expand_ivars_path(*this, e.m_origin); + for(auto& trait : e.m_traits) + { + this->expand_ivars_params(trait.m_path.m_params); + // TODO: Associated types + } ), (Array, this->expand_ivars(*e.inner); @@ -1498,7 +1493,11 @@ bool TraitResolution::has_associated_type(const ::HIR::TypeRef& input) const return H::check_pathparams(r, e2.m_params); ), (UfcsInherent, - TODO(Span(), "Path - UfcsInherent - " << p); + if( r.has_associated_type(*e2.type) ) + return true; + if( H::check_pathparams(r, e2.params) ) + return true; + return false; ), (UfcsKnown, if( r.has_associated_type(*e2.type) ) diff --git a/src/hir_typeck/outer.cpp b/src/hir_typeck/outer.cpp index 2ab0de6e..e16869bc 100644 --- a/src/hir_typeck/outer.cpp +++ b/src/hir_typeck/outer.cpp @@ -80,9 +80,14 @@ namespace { ::HIR::Crate& crate; StaticTraitResolve m_resolve; - const ::HIR::Trait* m_current_trait; - const ::HIR::ItemPath* m_current_trait_path; - + const ::HIR::Trait* m_current_trait = nullptr; + const ::HIR::ItemPath* m_current_trait_path = nullptr; + + + ::HIR::ItemPath* m_fcn_path = nullptr; + ::HIR::Function* m_fcn_ptr = nullptr; + unsigned int m_fcn_erased_count = 0; + ::std::vector< ::HIR::TypeRef* > m_self_types; typedef ::std::vector< ::std::pair< const ::HIR::SimplePath*, const ::HIR::Trait* > > t_trait_imports; @@ -90,8 +95,7 @@ namespace { public: Visitor(::HIR::Crate& crate): crate(crate), - m_resolve(crate), - m_current_trait(nullptr) + m_resolve(crate) { } @@ -271,6 +275,29 @@ namespace { ) ) ) + + // If an ErasedType is encountered, check if it has an origin set. + TU_IFLET(::HIR::TypeRef::Data, ty.m_data, ErasedType, e, + if( e.m_origin == ::HIR::SimplePath() ) + { + // If not, ensure taht we're checking a function return type, and error if not + if( ! m_fcn_path ) + ERROR(sp, E0000, "Use of an erased type outside of a function return - " << ty); + + ::HIR::PathParams params; + for(unsigned int i = 0; i < m_fcn_ptr->m_params.m_types.size(); i ++) + params.m_types.push_back(::HIR::TypeRef(m_fcn_ptr->m_params.m_types[i].m_name, 256+i)); + // Populate with function path + e.m_origin = m_fcn_path->get_full_path(); + TU_MATCHA( (e.m_origin.m_data), (e2), + (Generic, e2.m_params = mv$(params); ), + (UfcsInherent, e2.params = mv$(params); ), + (UfcsKnown, e2.params = mv$(params); ), + (UfcsUnknown, throw ""; ) + ) + e.m_index = m_fcn_erased_count++; + } + ) } void visit_generic_path(::HIR::GenericPath& p, PathContext pc) override @@ -489,7 +516,7 @@ namespace { public: void visit_path(::HIR::Path& p, ::HIR::Visitor::PathContext pc) override { - assert(pc == ::HIR::Visitor::PathContext::TYPE); + //assert(pc == ::HIR::Visitor::PathContext::TYPE); TU_MATCH(::HIR::Path::Data, (p.m_data), (e), (Generic, this->visit_generic_path(e, pc); @@ -497,7 +524,7 @@ namespace { (UfcsKnown, this->visit_type(*e.type); m_self_types.push_back(&*e.type); - this->visit_generic_path(e.trait, ::HIR::Visitor::PathContext::TYPE); + this->visit_generic_path(e.trait, pc); m_self_types.pop_back(); // TODO: Locate impl block and check parameters ), @@ -600,6 +627,17 @@ namespace { m_self_types.pop_back(); } + + void visit_function(::HIR::ItemPath p, ::HIR::Function& item) override { + + m_fcn_path = &p; + m_fcn_ptr = &item; + m_fcn_erased_count = 0; + visit_type(item.m_return); + m_fcn_path = nullptr; + + ::HIR::Visitor::visit_function(p, item); + } }; } |