diff options
author | John Hodge <tpg@mutabah.net> | 2015-04-05 23:05:49 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-04-05 23:05:49 +0800 |
commit | b438b28eb173aba78027b50fcf1091b150711114 (patch) | |
tree | c2194deaa2ba13a7315181ba195971fe41cc28b4 /src/convert/resolve.cpp | |
parent | cae16a7a72a75f08e01b63ef31a56e75125556b6 (diff) | |
download | mrust-b438b28eb173aba78027b50fcf1091b150711114.tar.gz |
Suport for #[lang], start work on resolving UFCS paths
Diffstat (limited to 'src/convert/resolve.cpp')
-rw-r--r-- | src/convert/resolve.cpp | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 35187b5f..53f20f94 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -384,8 +384,9 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode) void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode)
{
// Convert to absolute
- if( path.is_absolute() )
+ switch( path.type() )
{
+ case AST::Path::ABSOLUTE:
DEBUG("Absolute - binding");
INDENT();
// Already absolute, our job is done
@@ -397,9 +398,8 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode DEBUG("- Path " << path << " already bound");
}
UNINDENT();
- }
- else if( path.is_relative() )
- {
+ break;
+ case AST::Path::RELATIVE: {
assert(path.size() > 0);
DEBUG("Relative, local");
@@ -425,11 +425,13 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode throw ParseError::Todo("TODO: MODE_EXPR, but not a single identifer, what do?");
DEBUG("Local variable " << path[0].name());
path = AST::Path(AST::Path::TagLocal(), path[0].name());
+ return ;
}
- else
+ if( is_trivial_path )
+ throw ParseError::Generic("Type used in expression context?");
+ // Type parameter
+ case MODE_TYPE:
{
- if( is_trivial_path )
- throw ParseError::Generic("Type used in expression context?");
// Convert to a UFCS path
DEBUG("Local type");
// - "<Type as _>::nodes"
@@ -441,12 +443,6 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode DEBUG("path = " << path);
}
return ;
- // Type parameter
- case MODE_TYPE:
- DEBUG("Local type " << path);
- // - Switch the path to be a "LOCAL"
- path.set_local();
- return ;
// Binding is valid
case MODE_BIND:
//break ;
@@ -501,6 +497,17 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode assert( path.is_relative() );
if( mode != MODE_BIND )
throw ParseError::Generic("CPathResolver::handle_path - Name resolution failed");
+ break; }
+ case AST::Path::LOCAL:
+ // Don't touch locals, they're already known
+ break;
+ case AST::Path::UFCS:
+ // 1. Handle sub-types
+ handle_type(path.ufcs().at(0));
+ handle_type(path.ufcs().at(1));
+ // 2. Call resolve to attempt binding
+ path.resolve(m_crate);
+ break;
}
}
void CPathResolver::handle_type(TypeRef& type)
@@ -511,16 +518,15 @@ 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( opt_local.is_some() )
{
- // 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");
+ type = opt_local.unwrap().tr;
}
- else*/ if( opt_local.is_some() )
+ else if( name == "Self" )
{
- type = opt_local.unwrap().tr;
+ // If the name was "Self", but Self isn't already defined... then we need to make it an arg?
+ throw CompileError::Generic( FMT("CPathResolver::handle_type - Unexpected 'Self'") );
+ type = TypeRef(TypeRef::TagArg(), "Self");
}
else
{
|