diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-path.cc | 86 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.cc | 84 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-1231.rs | 36 |
3 files changed, 124 insertions, 82 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc index c3631fd..9bd836a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-path.cc +++ b/gcc/rust/resolve/rust-ast-resolve-path.cc @@ -130,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, @@ -162,45 +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 - { - 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; - } - - 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)) { @@ -208,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; diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc index 7d7eac1..d444e37 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.cc +++ b/gcc/rust/resolve/rust-ast-resolve-type.cc @@ -155,8 +155,39 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) break; } - if (previous_resolved_node_id == module_scope_id - && path.get_segments ().size () > 1) + 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_type_scope ().lookup (path, &resolved_node)) + { + resolver->insert_resolved_type (segment->get_node_id (), + resolved_node); + resolved_node_id = resolved_node; + } + else if (resolver->get_name_scope ().lookup (path, &resolved_node)) + { + resolver->insert_resolved_name (segment->get_node_id (), + resolved_node); + resolved_node_id = resolved_node; + } + else if (segment->is_lower_self_seg ()) + { + // what is the current crate scope node id? + 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; + } + } + + if (resolved_node_id == UNKNOWN_NODEID + && previous_resolved_node_id == module_scope_id) { Optional<CanonicalPath &> resolved_child = mappings->lookup_module_child (module_scope_id, @@ -188,46 +219,8 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) } } - 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_type_scope ().lookup (path, &resolved_node)) - { - resolver->insert_resolved_type (segment->get_node_id (), - resolved_node); - } - else if (resolver->get_name_scope ().lookup (path, &resolved_node)) - { - resolver->insert_resolved_name (segment->get_node_id (), - resolved_node); - } - else - { - if (segment->is_lower_self_seg ()) - { - // what is the current crate scope node id? - 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; - } - - rust_error_at (segment->get_locus (), - "failed to resolve TypePath: %s in this scope", - segment->as_string ().c_str ()); - return false; - } - - 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)) { @@ -235,6 +228,13 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) } previous_resolved_node_id = resolved_node_id; } + else if (is_first_segment) + { + rust_error_at (segment->get_locus (), + "failed to resolve TypePath: %s in this scope", + segment->as_string ().c_str ()); + return false; + } } if (resolved_node_id != UNKNOWN_NODEID) diff --git a/gcc/testsuite/rust/execute/torture/issue-1231.rs b/gcc/testsuite/rust/execute/torture/issue-1231.rs new file mode 100644 index 0000000..970e86f --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-1231.rs @@ -0,0 +1,36 @@ +// { dg-additional-options "-w" } +// { dg-output "outer\ninner\n" } +extern "C" { + fn printf(s: *const i8, ...); +} + +fn machin() { + unsafe { + let a = "outer\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, 123); + } +} + +fn bidule() { + fn machin() { + unsafe { + let a = "inner\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, 123); + } + } + + self::machin(); + machin(); +} + +fn main() -> i32 { + bidule(); + + 0 +} |