summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-03-31 20:10:15 +0800
committerJohn Hodge <tpg@mutabah.net>2015-03-31 20:10:15 +0800
commitc5b773f72a8ef077d8d189912014f64431825df5 (patch)
tree0324cb9b4f717204ae6a335795667b27edc54942 /src
parent752202c3857b00d0aa53117573d4a931f79ed65d (diff)
downloadmrust-c5b773f72a8ef077d8d189912014f64431825df5.tar.gz
Replace arguments in paths, and fix edge case in resolve where types were not resolved if added as defaults
Diffstat (limited to 'src')
-rw-r--r--src/ast/path.cpp24
-rw-r--r--src/ast/path.hpp3
-rw-r--r--src/convert/resolve.cpp14
-rw-r--r--src/convert/typecheck_params.cpp10
-rw-r--r--src/types.cpp6
5 files changed, 45 insertions, 12 deletions
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<TypeRef(const char*)> 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<TypeRef(const char*)> 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<const LocalItem&> 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<TypeRef(const char*)> 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 )