diff options
Diffstat (limited to 'gcc/rust/resolve/rust-ast-resolve-path.cc')
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-path.cc | 89 |
1 files changed, 58 insertions, 31 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc index 3c69b65..9bd836a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-path.cc +++ b/gcc/rust/resolve/rust-ast-resolve-path.cc @@ -59,6 +59,18 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) bool is_first_segment = i == 0; resolved_node_id = UNKNOWN_NODEID; + bool in_middle_of_path = i > 0; + if (in_middle_of_path && segment.is_lower_self_seg ()) + { + // error[E0433]: failed to resolve: `self` in paths can only be used + // in start position + rust_error_at (segment.get_locus (), + "failed to resolve: %<%s%> in paths can only be used " + "in start position", + segment.as_string ().c_str ()); + return; + } + NodeId crate_scope_id = resolver->peek_crate_module_scope (); if (segment.is_crate_path_seg ()) { @@ -118,7 +130,43 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) // // can only use old resolution when previous segment is unkown - if (previous_resolved_node_id == module_scope_id) + if (is_first_segment) + { + // name scope first + NodeId resolved_node = UNKNOWN_NODEID; + const CanonicalPath path + = CanonicalPath::new_seg (segment.get_node_id (), + ident_seg.as_string ()); + if (resolver->get_name_scope ().lookup (path, &resolved_node)) + { + resolver->insert_resolved_name (segment.get_node_id (), + resolved_node); + resolved_node_id = resolved_node; + } + // check the type scope + else if (resolver->get_type_scope ().lookup (path, &resolved_node)) + { + resolver->insert_resolved_type (segment.get_node_id (), + resolved_node); + resolved_node_id = resolved_node; + } + else if (segment.is_lower_self_seg ()) + { + module_scope_id = crate_scope_id; + previous_resolved_node_id = module_scope_id; + resolver->insert_resolved_name (segment.get_node_id (), + module_scope_id); + continue; + } + else + { + // no error handling here since we might be able to resolve via + // the module hierarchy and handle errors at the end + } + } + + if (resolved_node_id == UNKNOWN_NODEID + && previous_resolved_node_id == module_scope_id) { Optional<CanonicalPath &> resolved_child = mappings->lookup_module_child (module_scope_id, @@ -150,36 +198,8 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) } } - if (resolved_node_id == UNKNOWN_NODEID && is_first_segment) - { - // name scope first - NodeId resolved_node = UNKNOWN_NODEID; - const CanonicalPath path - = CanonicalPath::new_seg (segment.get_node_id (), - ident_seg.as_string ()); - if (resolver->get_name_scope ().lookup (path, &resolved_node)) - { - resolver->insert_resolved_name (segment.get_node_id (), - resolved_node); - } - // check the type scope - else if (resolver->get_type_scope ().lookup (path, &resolved_node)) - { - resolver->insert_resolved_type (segment.get_node_id (), - resolved_node); - } - else - { - rust_error_at (segment.get_locus (), - "Cannot find path %<%s%> in this scope", - segment.as_string ().c_str ()); - return; - } - - resolved_node_id = resolved_node; - } - - if (resolved_node_id != UNKNOWN_NODEID) + bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID; + if (did_resolve_segment) { if (mappings->node_is_module (resolved_node_id)) { @@ -187,6 +207,13 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) } previous_resolved_node_id = resolved_node_id; } + else if (is_first_segment) + { + rust_error_at (segment.get_locus (), + "Cannot find path %<%s%> in this scope", + segment.as_string ().c_str ()); + return; + } } resolved_node = resolved_node_id; |