From c5b773f72a8ef077d8d189912014f64431825df5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 31 Mar 2015 20:10:15 +0800 Subject: Replace arguments in paths, and fix edge case in resolve where types were not resolved if added as defaults --- src/ast/path.cpp | 24 ++++++++++++++++++++++++ src/ast/path.hpp | 3 +++ src/convert/resolve.cpp | 14 +++++++++++--- src/convert/typecheck_params.cpp | 10 ++++++---- src/types.cpp | 6 +----- 5 files changed, 45 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/ast/path.cpp b/src/ast/path.cpp index 85559e0e..222ce918 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -326,6 +326,8 @@ void Path::check_param_counts(const TypeParams& params, bool expect_params, Path unsigned int i = node.args().size(); const auto& p = params.ty_params()[i]; DEBUG("Extra #" << i << ", p = " << p); + // XXX: Currently, the default is just inserted (_ where not specified) + // - Erroring failed on transmute, and other omitted for inferrence instnaces if( true || p.get_default() != TypeRef() ) node.args().push_back( p.get_default() ); else @@ -385,6 +387,28 @@ void Path::bind_static(const Static& ent) m_binding = PathBinding(&ent); } +void Path::resolve_args(::std::function fcn) +{ + TRACE_FUNCTION_F(*this); + for(auto& n : nodes()) + { + for(auto& p : n.args()) + p.resolve_args(fcn); + } + + switch(m_class) + { + case Path::RELATIVE: + case Path::ABSOLUTE: + break; + case Path::LOCAL: + break; + case Path::UFCS: + m_ufcs[0].resolve_args(fcn); + m_ufcs[1].resolve_args(fcn); + break; + } +} Path& Path::operator+=(const Path& other) { diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 7f45d360..1bf2ba7d 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -252,6 +252,9 @@ public: /// expect_params enables checking of param counts (clear for handling 'use') void resolve(const Crate& crate, bool expect_params=true); + /// Resolve generic arguments within the path + void resolve_args(::std::function fcn); + bool is_trivial() const { return m_class == RELATIVE && m_nodes.size() == 1 && m_nodes[0].args().size() == 0; } diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index f9795c1d..3e690f61 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -70,6 +70,8 @@ public: ::rust::option lookup_local(LocalItem::Type type, const ::std::string& name) const; // TODO: Handle a block and obtain the local module (if any) +private: + void handle_path_int(AST::Path& path, CASTIterator::PathMode mode); }; // Path resolution checking @@ -342,8 +344,11 @@ bool lookup_path_in_module(const AST::Crate& crate, const AST::Module& module, c void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) { TRACE_FUNCTION_F("path = " << path << ", m_module_path = " << m_module_path); - + + handle_path_int(path, mode); + // Handle generic components of the path + // - Done AFTER resoltion, as binding might introduce defaults (which may not have been resolved) for( auto& ent : path.nodes() ) { for( auto& arg : ent.args() ) @@ -351,7 +356,9 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) handle_type(arg); } } - +} +void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode) +{ // Convert to absolute if( path.is_absolute() ) { @@ -474,7 +481,7 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) void CPathResolver::handle_type(TypeRef& type) { TRACE_FUNCTION_F("type = " << type); - if( type.is_path() && type.path().is_relative() && type.path().size() == 1 ) + if( type.is_path() && type.path().is_trivial() ) { const auto& name = type.path()[0].name(); @@ -494,6 +501,7 @@ void CPathResolver::handle_type(TypeRef& type) } } CASTIterator::handle_type(type); + DEBUG("res = " << type); } void CPathResolver::handle_expr(AST::ExprNode& node) { diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp index 279978e8..c4d231ff 100644 --- a/src/convert/typecheck_params.cpp +++ b/src/convert/typecheck_params.cpp @@ -204,17 +204,19 @@ void CGenericParamChecker::check_generic_params(const AST::TypeParams& info, ::s { if( bound.is_trait() ) { - auto bound_type = bound.test(); - bound_type.resolve_args([&](const char *a){ + auto ra_fcn = [&](const char *a){ if( strcmp(a, "Self") == 0 ) { if( self_type == TypeRef() ) throw CompileError::Generic("Unexpected use of 'Self' in bounds"); return self_type; } return types.at(info.find_name(a)); - }); + }; + auto bound_type = bound.test(); + bound_type.resolve_args(ra_fcn); - const auto& trait = bound.bound(); + auto trait = bound.bound(); + trait.resolve_args(ra_fcn); // TODO: Also resolve args in the trait // Check if 'type' impls 'trait' diff --git a/src/types.cpp b/src/types.cpp index c8af093c..e9460886 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -172,11 +172,7 @@ void TypeRef::resolve_args(::std::function fcn) *this = fcn(m_path[0].name().c_str()); break; case TypeRef::PATH: - for(auto& n : m_path.nodes()) - { - for(auto& p : n.args()) - p.resolve_args(fcn); - } + m_path.resolve_args(fcn); break; case TypeRef::MULTIDST: for(auto& t : m_inner_types ) -- cgit v1.2.3