summaryrefslogtreecommitdiff
path: root/src/convert
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-08-31 14:06:26 +0800
committerJohn Hodge <tpg@mutabah.net>2015-08-31 14:06:26 +0800
commit68607811e4e8d6feba95f55c3e49da9923fc35fd (patch)
tree665891a1fac39c1d9a87617ad1af1ca27b139a60 /src/convert
parent261f2aea278e1185f69b06e65501c1ca718df47c (diff)
downloadmrust-68607811e4e8d6feba95f55c3e49da9923fc35fd.tar.gz
Convert path bindings to TAGGED_UNION, improve resolve logic (leading to error)
Diffstat (limited to 'src/convert')
-rw-r--r--src/convert/ast_iterate.cpp25
-rw-r--r--src/convert/resolve.cpp182
-rw-r--r--src/convert/typecheck_bounds.cpp4
-rw-r--r--src/convert/typecheck_expr.cpp65
-rw-r--r--src/convert/typecheck_params.cpp78
5 files changed, 232 insertions, 122 deletions
diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp
index 72cfd009..10eaf80b 100644
--- a/src/convert/ast_iterate.cpp
+++ b/src/convert/ast_iterate.cpp
@@ -178,25 +178,26 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
const auto& hint_binding = hint_path.binding();
const auto& pat_binding = pat_path.binding();
DEBUG("Pat: " << pat_path << ", Type: " << type_hint.path());
- switch( hint_binding.type() )
- {
- case AST::PathBinding::UNBOUND:
+ TU_MATCH_DEF( AST::PathBinding, (hint_binding), (info),
+ (
+ throw ::std::runtime_error(FMT("Bad type in tuple struct pattern : " << type_hint.path()))
+ ),
+ (Unbound,
throw ::std::runtime_error("Unbound path in pattern");
- case AST::PathBinding::ENUM: {
+ ),
+ (Enum,
// The pattern's path must refer to a variant of the hint path
// - Actual type params are checked by the 'handle_pattern_enum' code
- if( pat_binding.type() != AST::PathBinding::ENUM_VAR )
+ if( !pat_binding.is_EnumVar() )
throw ::std::runtime_error(FMT("Paths in pattern are invalid"));
- if( pat_binding.bound_enumvar().enum_ != &hint_binding.bound_enum() )
+ if( pat_binding.as_EnumVar().enum_ != info.enum_ )
throw ::std::runtime_error(FMT("Paths in pattern are invalid"));
- const auto& enm = *pat_binding.bound_enumvar().enum_;
- auto idx = pat_binding.bound_enumvar().idx;
+ const auto& enm = *pat_binding.as_EnumVar().enum_;
+ auto idx = pat_binding.as_EnumVar().idx;
auto& var = enm.variants().at(idx);
handle_pattern_enum(pat_path[-2].args(), hint_path[-1].args(), enm.params(), var, v.sub_patterns);
- break; }
- default:
- throw ::std::runtime_error(FMT("Bad type in tuple struct pattern : " << type_hint.path()));
- }
+ )
+ )
}
break; }
}
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index 901a3acb..821d4810 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -89,9 +89,11 @@ public:
::rust::option<const LocalItem&> lookup_local(LocalItem::Type type, const ::std::string& name) const;
- bool find_local_item(AST::Path& path, bool allow_variables);
- bool find_mod_item(AST::Path& path);
- bool find_super_mod_item(AST::Path& path);
+ bool find_local_item(AST::Path& path, const ::std::string& name, bool allow_variables);
+ //bool find_local_item(AST::Path& path, bool allow_variables);
+ bool find_mod_item(AST::Path& path, const ::std::string& name);
+ bool find_self_mod_item(AST::Path& path, const ::std::string& name);
+ bool find_super_mod_item(AST::Path& path, const ::std::string& name);
bool find_type_param(const ::std::string& name);
// TODO: Handle a block and obtain the local module (if any)
@@ -319,11 +321,11 @@ void CPathResolver::end_scope()
// > Search local use definitions (function-level)
// - TODO: Local use statements (scoped)
// > Search module-level definitions
-bool lookup_path_in_module(const AST::Crate& crate, const AST::Module& module, const AST::Path& mod_path, AST::Path& path)
+bool lookup_path_in_module(const AST::Crate& crate, const AST::Module& module, const AST::Path& mod_path, AST::Path& path, const ::std::string& name, bool is_leaf)
{
TRACE_FUNCTION_F("mod_path="<<mod_path);
// - Allow leaf nodes if path is a single node, don't skip private wildcard imports
- auto item = module.find_item(path[0].name(), (path.size() == 1), false);
+ auto item = module.find_item(name, is_leaf, false);
switch(item.type())
{
case AST::Module::ItemRef::ITEM_none:
@@ -358,6 +360,9 @@ bool lookup_path_in_module(const AST::Crate& crate, const AST::Module& module, c
return true;
}
}
+bool lookup_path_in_module(const AST::Crate& crate, const AST::Module& module, const AST::Path& mod_path, AST::Path& path) {
+ return lookup_path_in_module(crate, module, mod_path, path, path[0].name(), path.size() == 1);
+}
/// Perform path resolution within a generic definition block
void CPathResolver::handle_params(AST::TypeParams& params)
@@ -445,7 +450,7 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
INDENT();
// Already absolute, our job is done
// - However, if the path isn't bound, bind it
- if( !path.binding().is_bound() ) {
+ if( path.binding().is_Unbound() ) {
path.resolve(m_crate);
}
else {
@@ -460,11 +465,38 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
// > Variable: (wait, how is this known already?)
// - 'self'
case AST::Path::Class::Local:
- //if(
- // 1. Check for local items
- // 2. Type parameters (ONLY when in expression mode)
- // 3. Module items
- //throw ::std::runtime_error("TODO: Local in CPathResolver::handle_path_int");
+ if( !path.binding().is_Unbound() )
+ {
+ DEBUG("- Path " << path << " already bound");
+ }
+ else
+ {
+ const auto& info = path.m_class.as_Local();
+ // 1. Check for local items
+ if( this->find_local_item(path, info.name, (mode == CASTIterator::MODE_EXPR)) ) {
+ path.resolve(m_crate);
+ break ;
+ }
+ else {
+ // No match, fall through
+ }
+ // 2. Type parameters (ONLY when in type mode)
+ if( mode == CASTIterator::MODE_TYPE ) {
+ throw ::std::runtime_error("TODO: Local in CPathResolver::handle_path_int type param");
+ }
+ // 3. Module items
+ if( this->find_mod_item(path, info.name) ) {
+ path.resolve(m_crate);
+ break;
+ }
+ else {
+ }
+
+ DEBUG("no matches found for path = " << path);
+ if( mode != MODE_BIND )
+ throw ParseError::Generic("CPathResolver::handle_path - Name resolution failed (Local)");
+ return ;
+ }
break;
case AST::Path::Class::Relative:
@@ -472,8 +504,8 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
// > Return values: name or path
{
bool allow_variables = (mode == CASTIterator::MODE_EXPR && path.is_trivial());
- if( this->find_local_item(path, allow_variables) ) {
- //path.resolve(m_crate);
+ if( this->find_local_item(path, path[0].name(), allow_variables) ) {
+ path.resolve(m_crate);
break ;
}
else {
@@ -495,13 +527,14 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
auto newpath = AST::Path(AST::Path::TagUfcs(), TypeRef(TypeRef::TagArg(), path[0].name()), TypeRef());
newpath.add_tailing(path);
path = mv$(newpath);
+ handle_path_ufcs(path, mode);
}
else {
// Mark as local
- // - TODO: Also need to annotate
// - TODO: Not being trivial is an error, not a bug
assert( path.is_trivial() );
path = AST::Path(AST::Path::TagLocal(), path[0].name());
+ // - TODO: Need to bind this to the source parameter block
}
break;
}
@@ -509,7 +542,8 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
// 3. current module
{
- if( this->find_mod_item(path) ) {
+ if( this->find_mod_item(path, path[0].name()) ) {
+ path.resolve(m_crate);
break;
}
else {
@@ -524,7 +558,7 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
// Module relative
case AST::Path::Class::Self:{
- if( this->find_mod_item(path) ) {
+ if( this->find_self_mod_item(path, path[0].name()) ) {
break;
}
else {
@@ -535,7 +569,7 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
break; }
// Parent module relative
case AST::Path::Class::Super:{
- if( this->find_super_mod_item(path) ) {
+ if( this->find_super_mod_item(path, path[0].name()) ) {
break;
}
else {
@@ -547,25 +581,76 @@ void CPathResolver::handle_path_int(AST::Path& path, CASTIterator::PathMode mode
}
// TODO: Are there any reasons not to be bound at this point?
- //assert( path.binding().is_bound() );
+ //assert( !path.binding().is_Unbound() );
}
void CPathResolver::handle_path_ufcs(AST::Path& path, CASTIterator::PathMode mode)
{
+ assert(path.m_class.is_UFCS());
auto& info = path.m_class.as_UFCS();
+ TRACE_FUNCTION_F("info={< " << *info.type << " as " << *info.trait << ">::" << info.nodes << "}");
+ const ::std::string& item_name = info.nodes[0].name();
// 1. Handle sub-types
handle_type(*info.type);
handle_type(*info.trait);
// 2. Handle wildcard traits (locate in inherent impl, or from an in-scope trait)
if( info.trait->is_wildcard() )
{
- DEBUG("Searching for impls when trait is _");
+ DEBUG("Searching for impls when trait is _ (trait = " << *info.trait << ")");
// Search applicable type parameters for known implementations
// 1. Inherent
AST::Impl* impl_ptr;
::std::vector<TypeRef> params;
- if( m_crate.find_impl(AST::Path(), *info.type, &impl_ptr, &params) )
+ if( info.type->is_type_param() && info.type->type_param() == "Self" )
+ {
+ throw ParseError::Todo("CPathResolver::handle_path_ufcs - Handle '<Self as _>::...'");
+ }
+ else if( info.type->is_type_param() )
+ {
+ DEBUG("Checking applicable generic bounds");
+ const auto& tp = *info.type->type_params_ptr();
+ assert(&tp != nullptr);
+ bool success = false;
+
+ // Enumerate bounds
+ for( const auto& bound : tp.bounds() )
+ {
+ DEBUG("bound = " << bound);
+ if( bound.is_trait() && bound.test() == *info.type )
+ {
+ const auto& t = *bound.bound().binding().as_Trait().trait_;
+ {
+ const auto& fcns = t.functions();
+ auto it = ::std::find_if( fcns.begin(), fcns.end(), [&](const AST::Item<AST::Function>& a) { return a.name == item_name; } );
+ if( it != fcns.end() ) {
+ // Found it.
+ if( info.nodes.size() != 1 )
+ throw ParseError::Generic("CPathResolver::handle_path_ufcs - Multiple arguments");
+ *info.trait = bound.bound();
+ success = true;
+ break;
+ }
+ }
+ {
+ const auto& types = t.types();
+ auto it = ::std::find_if( types.begin(), types.end(), [&](const AST::Item<AST::TypeAlias>& a) { return a.name == item_name; } );
+ if( it != types.end() ) {
+ // Found it.
+ *info.trait = bound.bound();
+ success = true;
+ break;
+ }
+ }
+ }
+ }
+
+ if( !success )
+ throw ParseError::Todo("CPathResolver::handle_path_ufcs - UFCS, find trait for generic");
+ // - re-handle, to ensure that the bound is resolved
+ handle_type(*info.trait);
+ }
+ else if( m_crate.find_impl(AST::Path(), *info.type, &impl_ptr, &params) )
{
DEBUG("Found matching inherent impl");
// - Mark as being from the inherent, and move along
@@ -573,16 +658,18 @@ void CPathResolver::handle_path_ufcs(AST::Path& path, CASTIterator::PathMode mod
*info.trait = TypeRef(TypeRef::TagInvalid());
}
else
- {
- // Iterate all traits in scope, and find one that is impled for this type
- throw ParseError::Todo("CPathResolver::handle_path - UFCS, find trait");
+ {
+ // Iterate all traits in scope, and find one that is implemented for this type
+ // - TODO: Iterate traits to find match for <Type as _>
+ throw ParseError::Todo("CPathResolver::handle_path_ufcs - UFCS, find trait");
}
}
// 3. Call resolve to attempt binding
path.resolve(m_crate);
}
-bool CPathResolver::find_local_item(AST::Path& path, bool allow_variables) {
+bool CPathResolver::find_local_item(AST::Path& path, const ::std::string& name, bool allow_variables)
+{
TRACE_FUNCTION_F("path="<<path<<", allow_variables="<<allow_variables);
// Search current scopes for a name
// - This should search both the expression stack
@@ -594,8 +681,9 @@ bool CPathResolver::find_local_item(AST::Path& path, bool allow_variables) {
{
for( auto it2 = s.locals.rbegin(); it2 != s.locals.rend(); ++it2 )
{
- if( *it2 == path[0].name() ) {
- path = AST::Path(AST::Path::TagLocal(), path[0].name());
+ if( *it2 == name ) {
+ path = AST::Path(AST::Path::TagLocal(), name);
+ path.bind_variable(0);
return true;
}
}
@@ -603,19 +691,29 @@ bool CPathResolver::find_local_item(AST::Path& path, bool allow_variables) {
if( s.module != nullptr )
{
DEBUG("- Looking in sub-module '" << s.module_path << "'");
- if( lookup_path_in_module(m_crate, *s.module, s.module_path, path) )
+ if( lookup_path_in_module(m_crate, *s.module, s.module_path, path, name, path.is_trivial()) )
return true;
}
}
return false;
}
-bool CPathResolver::find_mod_item(AST::Path& path) {
+bool CPathResolver::find_mod_item(AST::Path& path, const ::std::string& name) {
+ const AST::Module* mod = m_module;
+ do {
+ if( lookup_path_in_module(m_crate, *mod, m_module_path, path, name, path.size()==1) )
+ return true;
+ if( mod->name() == "" )
+ throw ParseError::Todo("Handle anon modules when resoling unqualified relative paths");
+ } while( mod->name() == "" );
+ return false;
+}
+bool CPathResolver::find_self_mod_item(AST::Path& path, const ::std::string& name) {
if( m_module->name() == "" )
throw ParseError::Todo("Correct handling of 'self' in anon modules");
- return lookup_path_in_module(m_crate, *m_module, m_module_path, path);
+ return lookup_path_in_module(m_crate, *m_module, m_module_path, path, name, path.size()==1);
}
-bool CPathResolver::find_super_mod_item(AST::Path& path) {
+bool CPathResolver::find_super_mod_item(AST::Path& path, const ::std::string& name) {
if( m_module->name() == "" )
throw ParseError::Todo("Correct handling of 'super' in anon modules");
@@ -628,7 +726,7 @@ bool CPathResolver::find_super_mod_item(AST::Path& path) {
// 2. Resolve that path
super_path.resolve(m_crate);
// 3. Call lookup_path_in_module
- return lookup_path_in_module(m_crate, super_path.binding().bound_module(), super_path, path);
+ return lookup_path_in_module(m_crate, *super_path.binding().as_Module().module_, super_path, path, name, path.size()==1);
}
bool CPathResolver::find_type_param(const ::std::string& name) {
for( auto it = m_locals.end(); it -- != m_locals.begin(); )
@@ -810,24 +908,22 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod
// If wildcard, make sure it's sane
if( imp.name == "" )
{
- switch(imp.data.binding().type())
- {
- case AST::PathBinding::UNBOUND:
- throw ParseError::BugCheck("path unbound after calling .resolve()");
- case AST::PathBinding::MODULE:
- break;
- case AST::PathBinding::ENUM:
- break;
-
- default:
+ TU_MATCH_DEF(AST::PathBinding, (imp.data.binding()), (info),
+ (
throw ParseError::Generic("Wildcard imports are only allowed on modules and enums");
- }
+ ),
+ (Unbound,
+ throw ParseError::BugCheck("path unbound after calling .resolve()");
+ ),
+ (Module, (void)0;),
+ (Enum, (void)0;)
+ )
}
}
for( auto& new_imp : new_imports )
{
- if( not new_imp.binding().is_bound() ) {
+ if( new_imp.binding().is_Unbound() ) {
new_imp.resolve(crate, false);
}
mod.add_alias(false, new_imp, new_imp[new_imp.size()-1].name());
diff --git a/src/convert/typecheck_bounds.cpp b/src/convert/typecheck_bounds.cpp
index 4112bf27..1216e959 100644
--- a/src/convert/typecheck_bounds.cpp
+++ b/src/convert/typecheck_bounds.cpp
@@ -25,9 +25,9 @@ void CGenericBoundChecker::handle_params(AST::TypeParams& params)
if( bound.is_trait() )
{
auto& trait = bound.bound();
- assert(trait.binding().is_bound());
+ assert( !trait.binding().is_Unbound() );
DEBUG("trait = " << trait);
- if( trait.binding().type() != AST::PathBinding::TRAIT )
+ if( trait.binding().is_Trait() )
{
//throw CompileError::BoundNotTrait( bound.lex_scope(), bound.param(), trait );
throw ::std::runtime_error(FMT("TODO - Bound " << trait << " not a trait : " << trait.binding()));
diff --git a/src/convert/typecheck_expr.cpp b/src/convert/typecheck_expr.cpp
index 8a4bc84f..e2bd1857 100644
--- a/src/convert/typecheck_expr.cpp
+++ b/src/convert/typecheck_expr.cpp
@@ -300,14 +300,16 @@ void CTC_NodeVisitor::visit(AST::ExprNode_NamedValue& node)
if( p.is_absolute() )
{
// grab bound item
- switch(p.binding().type())
- {
- case AST::PathBinding::STATIC:
- node.get_res_type() = p.binding().bound_static().type();
- break;
- case AST::PathBinding::ENUM_VAR: {
- const AST::Enum& enm = *p.binding().bound_enumvar().enum_;
- auto idx = p.binding().bound_enumvar().idx;
+ TU_MATCH_DEF(AST::PathBinding, (p.binding()), (info),
+ (
+ throw ::std::runtime_error( FMT("Unknown binding type on named value : "<<p) );
+ ),
+ (Static,
+ node.get_res_type() = info.static_->type();
+ ),
+ (EnumVar,
+ const AST::Enum& enm = *info.enum_;
+ auto idx = info.idx;
// Enum variant:
// - Check that this variant takes no arguments
if( enm.variants()[idx].m_sub_types.size() > 0 )
@@ -322,10 +324,8 @@ void CTC_NodeVisitor::visit(AST::ExprNode_NamedValue& node)
while(pn.args().size() < num_params)
pn.args().push_back( TypeRef() );
node.get_res_type() = TypeRef(tp);
- break; }
- default:
- throw ::std::runtime_error( FMT("Unknown binding type on named value : "<<p) );
- }
+ )
+ )
}
else
{
@@ -415,16 +415,16 @@ void CTC_NodeVisitor::visit(AST::ExprNode_Field& node)
// TODO Move this logic to types.cpp?
const AST::Path& p = tr->path();
- switch( p.binding().type() )
- {
- case AST::PathBinding::STRUCT: {
+ TU_MATCH_DEF( AST::PathBinding, (p.binding()), (info),
+ (
+ throw ::std::runtime_error("TODO: Get field from non-structure");
+ ),
+ (Struct,
const AST::PathNode& lastnode = p.nodes().back();
- AST::Struct& s = const_cast<AST::Struct&>( p.binding().bound_struct() );
+ AST::Struct& s = const_cast<AST::Struct&>( *info.struct_ );
node.get_res_type().merge_with( s.get_field_type(node.m_name.c_str(), lastnode.args()) );
- break; }
- default:
- throw ::std::runtime_error("TODO: Get field from non-structure");
- }
+ )
+ )
DEBUG("deref_count = " << deref_count);
for( unsigned i = 0; i < deref_count; i ++ )
{
@@ -575,9 +575,12 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallPath& node)
argtypes.push_back( arg->get_res_type() );
}
- if(node.m_path.binding().type() == AST::PathBinding::FUNCTION)
- {
- const AST::Function& fcn = node.m_path.binding().bound_func();
+ TU_MATCH_DEF( AST::PathBinding, (node.m_path.binding()), (info),
+ (
+ throw ::std::runtime_error("CallPath on non-function");
+ ),
+ (Function,
+ const AST::Function& fcn = *info.func_;
if( fcn.params().ty_params().size() > 0 )
{
@@ -586,11 +589,10 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallPath& node)
DEBUG("ExprNode_CallPath - rt = " << fcn.rettype());
node.get_res_type().merge_with( fcn.rettype() );
- }
- else if(node.m_path.binding().type() == AST::PathBinding::ENUM_VAR)
- {
- const AST::Enum& enm = *node.m_path.binding().bound_enumvar().enum_;
- const unsigned int idx = node.m_path.binding().bound_enumvar().idx;
+ ),
+ (EnumVar,
+ const AST::Enum& enm = *info.enum_;
+ const unsigned int idx = info.idx;
auto& path_node_enum = node.m_path[node.m_path.size()-2];
m_tc.check_enum_variant(path_node_enum.args(), argtypes, enm.params(), enm.variants().at(idx));
@@ -601,11 +603,8 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallPath& node)
DEBUG("ExprNode_CallPath - enum t = " << ty);
node.get_res_type().merge_with(ty);
- }
- else
- {
- throw ::std::runtime_error("CallPath on non-function");
- }
+ )
+ )
}
void Typecheck_Expr(AST::Crate& crate)
diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp
index f3fe5047..e8cbbc05 100644
--- a/src/convert/typecheck_params.cpp
+++ b/src/convert/typecheck_params.cpp
@@ -235,43 +235,57 @@ void CGenericParamChecker::handle_path(AST::Path& path, CASTIterator::PathMode p
{
TRACE_FUNCTION_F("path = " << path);
AST::PathNode& last_node = path[path.size()-1];
- const AST::TypeParams* params = nullptr;
- switch(path.binding().type())
- {
- case AST::PathBinding::UNBOUND:
- throw CompileError::BugCheck( FMT("CGenericParamChecker::handle_path - Unbound path : " << path) );
- case AST::PathBinding::MODULE:
- DEBUG("WTF - Module path, isn't this invalid at this stage?");
- break;
- case AST::PathBinding::TRAIT:
- params = &path.binding().bound_trait().params();
- if(0)
- case AST::PathBinding::STRUCT:
- params = &path.binding().bound_struct().params();
- if(0)
- case AST::PathBinding::ENUM:
- params = &path.binding().bound_enum().params();
-
- {
+ auto comm = [&](const AST::TypeParams& params) {
auto lt = find_type_by_name("Self");
TypeRef self_type; // =TypeRef(TypeRef::TagPath(), path)
if( lt )
self_type = lt->fixed_type;
- check_generic_params(*params, last_node.args(), self_type, (m_within_expr > 0));
- }
- break;
- case AST::PathBinding::ALIAS:
- params = &path.binding().bound_alias().params();
- if(0)
- case AST::PathBinding::FUNCTION:
- params = &path.binding().bound_func().params();
-
- check_generic_params(*params, last_node.args(), TypeRef(TypeRef::TagInvalid()), (m_within_expr > 0));
- break;
- default:
- throw ::std::runtime_error("Unknown path type in CGenericParamChecker::handle_path");
- }
+ check_generic_params(params, last_node.args(), self_type, (m_within_expr > 0));
+ };
+
+ TU_MATCH( AST::PathBinding, (path.binding()), (info),
+ (Unbound,
+ throw CompileError::BugCheck( FMT("CGenericParamChecker::handle_path - Unbound path : " << path) );
+ ),
+ (Module,
+ DEBUG("WTF - Module path, isn't this invalid at this stage?");
+ ),
+ (Trait,
+ comm( info.trait_->params() );
+ ),
+ (Struct,
+ comm( info.struct_->params() );
+ ),
+ (Enum,
+ comm( info.enum_->params() );
+ ),
+ (TypeAlias,
+ comm( info.alias_->params() );
+ ),
+ (Function,
+ check_generic_params(info.func_->params(), last_node.args(), TypeRef(TypeRef::TagInvalid()), (m_within_expr > 0));
+ ),
+
+ (EnumVar,
+ throw ::std::runtime_error("TODO: handle_path EnumVar");
+ ),
+ (Static,
+ throw ::std::runtime_error("TODO: handle_path Static");
+ ),
+ (StructMethod,
+ throw ::std::runtime_error("TODO: handle_path StructMethod");
+ ),
+ (TraitMethod,
+ throw ::std::runtime_error("TODO: handle_path TraitMethod");
+ ),
+ (TypeParameter,
+ throw ::std::runtime_error("TODO: handle_path TypeParameter");
+ ),
+ (Variable,
+ throw ::std::runtime_error("TODO: handle_path Variable");
+ )
+ )
}
void CGenericParamChecker::handle_expr(AST::ExprNode& root)