From 7bee527fa774c397390618380bdab8bf4dec9cb0 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 5 Apr 2015 13:17:36 +0800 Subject: Replace 'Self' at resolve-time, with special case for bounds --- src/ast/ast.cpp | 3 +-- src/convert/ast_iterate.cpp | 4 +++- src/convert/resolve.cpp | 30 ++++++++++++++++++++++++++---- src/types.cpp | 4 +++- 4 files changed, 33 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 9aa02fe1..63e33ba6 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -66,11 +66,10 @@ bool ImplDef::matches(::std::vector& out_types, const Path& trait, cons int trait_match = m_trait.equal_no_generic(trait); if( trait_match < 0 ) return false; - DEBUG("Trait " << trait << " matches " << trait_match); int type_match = m_type.equal_no_generic(type); if( type_match < 0 ) return false; - DEBUG("Type " << type << " matches " << type_match); + DEBUG("Match Tr:" < Involves checking that parameters are valid diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index 46ca4458..a2fed087 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -337,9 +337,11 @@ void CASTIterator::handle_enum(AST::Path path, AST::Enum& enm) void CASTIterator::handle_trait(AST::Path path, AST::Trait& trait) { start_scope(); + local_type("Self", TypeRef(TypeRef::TagArg(), "Self")); handle_params( trait.params() ); - local_type("Self", TypeRef(path)); + //local_type("Self", TypeRef(path)); + //local_type("Self", TypeRef(TypeRef::TagArg(), "Self")); for( auto& fcn : trait.functions() ) handle_function( path + fcn.name, fcn.data ); diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 029d368a..65887082 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -51,6 +51,8 @@ class CPathResolver: public: CPathResolver(const AST::Crate& crate); + void handle_params(AST::TypeParams& params) override; + virtual void handle_path(AST::Path& path, CASTIterator::PathMode mode) override; virtual void handle_type(TypeRef& type) override; virtual void handle_expr(AST::ExprNode& node) override; @@ -341,6 +343,26 @@ bool lookup_path_in_module(const AST::Crate& crate, const AST::Module& module, c } #endif } +void CPathResolver::handle_params(AST::TypeParams& params) +{ + DEBUG("params"); + for( auto& param : params.ty_params() ) + { + handle_type(param.get_default()); + local_type( param.name(), TypeRef(TypeRef::TagArg(), param.name(), params) ); + } + DEBUG("Bounds"); + for( auto& bound : params.bounds() ) + { + handle_type(bound.test()); + local_type("Self", bound.test()); + if( !bound.is_trait() ) + DEBUG("namecheck lifetime bounds?"); + else + handle_path(bound.bound(), CASTIterator::MODE_TYPE); + m_locals.pop_back(); + } +} void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) { TRACE_FUNCTION_F("path = " << path << ", m_module_path = " << m_module_path); @@ -487,14 +509,14 @@ void CPathResolver::handle_type(TypeRef& type) const auto& name = type.path()[0].name(); auto opt_local = lookup_local(LocalItem::TYPE, name); - if( name == "Self" ) + /*if( name == "Self" ) { // TODO: Handle "Self" correctly // - Needs to be tagged with the soure params, but since Self is special... // - Shouldn't matter, as Self should be resolved out before it needs that tagging type = TypeRef(TypeRef::TagArg(), "Self"); } - else if( opt_local.is_some() ) + else*/ if( opt_local.is_some() ) { type = opt_local.unwrap().tr; } @@ -507,11 +529,11 @@ void CPathResolver::handle_type(TypeRef& type) { const auto& name = type.type_param(); auto opt_local = lookup_local(LocalItem::TYPE, name); - if( name == "Self" ) + /*if( name == "Self" ) { // Good as it is } - else if( opt_local.is_some() ) + else*/ if( opt_local.is_some() ) { type = opt_local.unwrap().tr; } diff --git a/src/types.cpp b/src/types.cpp index 1925e579..5c15323b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -295,7 +295,7 @@ bool TypeRef::is_concrete() const int TypeRef::equal_no_generic(const TypeRef& x) const { - DEBUG(*this << ", " << x); + //DEBUG(*this << ", " << x); if( m_class == TypeRef::GENERIC ) //|| x.m_class == TypeRef::GENERIC ) return 1; if( m_class != x.m_class ) return -1; @@ -316,6 +316,8 @@ int TypeRef::equal_no_generic(const TypeRef& x) const return m_path.equal_no_generic( x.m_path ); case TypeRef::REFERENCE: case TypeRef::POINTER: + if( m_is_inner_mutable != x.m_is_inner_mutable ) + return -1; return m_inner_types[0].equal_no_generic( x.m_inner_types[0] ); case TypeRef::ARRAY: if( m_size_expr.get() || x.m_size_expr.get() ) -- cgit v1.2.3