diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-item.h | 1 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-base.cc | 18 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.cc | 41 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-path.cc | 97 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/pub_restricted_1.rs | 14 |
5 files changed, 109 insertions, 62 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 5d1e0d6..9dc61a8 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -701,6 +701,7 @@ public: std::string as_string () const; const SimplePath &get_path () const { return in_path; } + SimplePath &get_path () { return in_path; } protected: // Clone function implementation - not currently virtual but may be if diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc index d1b3885..2a86618 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc @@ -17,15 +17,27 @@ // <http://www.gnu.org/licenses/>. #include "rust-ast-resolve-base.h" +#include "rust-ast-resolve-expr.h" +#include "rust-ast-resolve-path.h" +#include "rust-item.h" namespace Rust { namespace Resolver { bool -resolve_visibility (const AST::Visibility &vis) +ResolverBase::resolve_visibility (const AST::Visibility &vis) { - gcc_unreachable (); - return false; + if (vis.has_path ()) + { + auto path = vis.get_path (); + ResolvePath::go (&path, parent); + + // Do we need to lookup something here? + // Is it just about resolving the names correctly so we can look them up + // later? + } + + return true; } // Default visitors implementations diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index 9546698..2c383c9 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -238,6 +238,8 @@ ResolveItem::visit (AST::Module &module) mappings->insert_canonical_path (mappings->get_current_crate (), module.get_node_id (), cpath); + resolve_visibility (module.get_visibility ()); + NodeId scope_node_id = module.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -267,6 +269,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl) mappings->insert_canonical_path (mappings->get_current_crate (), struct_decl.get_node_id (), cpath); + resolve_visibility (struct_decl.get_visibility ()); + NodeId scope_node_id = struct_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -286,6 +290,8 @@ ResolveItem::visit (AST::TupleStruct &struct_decl) if (field.get_field_type ()->is_marked_for_strip ()) continue; + resolve_visibility (field.get_visibility ()); + ResolveType::go (field.get_field_type ().get (), struct_decl.get_node_id ()); } @@ -303,6 +309,8 @@ ResolveItem::visit (AST::Enum &enum_decl) mappings->insert_canonical_path (mappings->get_current_crate (), enum_decl.get_node_id (), cpath); + resolve_visibility (enum_decl.get_visibility ()); + NodeId scope_node_id = enum_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -328,6 +336,9 @@ ResolveItem::visit (AST::Enum &enum_decl) void ResolveItem::visit (AST::EnumItem &item) { + // Since at this point we cannot have visibilities on enum items anymore, we + // can skip handling them + auto decl = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); auto path = prefix.append (decl); @@ -396,6 +407,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl) mappings->insert_canonical_path (mappings->get_current_crate (), struct_decl.get_node_id (), cpath); + resolve_visibility (struct_decl.get_visibility ()); + NodeId scope_node_id = struct_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -415,6 +428,8 @@ ResolveItem::visit (AST::StructStruct &struct_decl) if (field.get_field_type ()->is_marked_for_strip ()) continue; + resolve_visibility (field.get_visibility ()); + ResolveType::go (field.get_field_type ().get (), struct_decl.get_node_id ()); } @@ -432,6 +447,8 @@ ResolveItem::visit (AST::Union &union_decl) mappings->insert_canonical_path (mappings->get_current_crate (), union_decl.get_node_id (), cpath); + resolve_visibility (union_decl.get_visibility ()); + NodeId scope_node_id = union_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -485,6 +502,8 @@ ResolveItem::visit (AST::ConstantItem &constant) mappings->insert_canonical_path (mappings->get_current_crate (), constant.get_node_id (), cpath); + resolve_visibility (constant.get_visibility ()); + ResolveType::go (constant.get_type ().get (), constant.get_node_id ()); ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (), path, cpath); @@ -505,6 +524,8 @@ ResolveItem::visit (AST::Function &function) mappings->insert_canonical_path (mappings->get_current_crate (), function.get_node_id (), cpath); + resolve_visibility (function.get_visibility ()); + NodeId scope_node_id = function.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -559,6 +580,8 @@ ResolveItem::visit (AST::InherentImpl &impl_block) resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + resolve_visibility (impl_block.get_visibility ()); + if (impl_block.has_generics ()) { for (auto &generic : impl_block.get_generic_params ()) @@ -640,6 +663,9 @@ ResolveItem::visit (AST::Method &method) method.get_node_id (), cpath); NodeId scope_node_id = method.get_node_id (); + + resolve_visibility (method.get_visibility ()); + resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); resolver->get_label_scope ().push (scope_node_id); @@ -711,6 +737,9 @@ void ResolveItem::visit (AST::TraitImpl &impl_block) { NodeId scope_node_id = impl_block.get_node_id (); + + resolve_visibility (impl_block.get_visibility ()); + resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); @@ -812,6 +841,9 @@ void ResolveItem::visit (AST::Trait &trait) { NodeId scope_node_id = trait.get_node_id (); + + resolve_visibility (trait.get_visibility ()); + resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); @@ -862,6 +894,8 @@ ResolveItem::visit (AST::Trait &trait) void ResolveItem::visit (AST::ExternBlock &extern_block) { + resolve_visibility (extern_block.get_visibility ()); + for (auto &item : extern_block.get_extern_items ()) { resolve_extern_item (item.get ()); @@ -895,6 +929,8 @@ ResolveImplItems::visit (AST::TypeAlias &alias) { ResolveItem::visit (alias); + resolve_visibility (alias.get_visibility ()); + // FIXME this stops the erronious unused decls which will be fixed later on resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (), alias.get_node_id ()); @@ -911,6 +947,9 @@ void ResolveExternItem::visit (AST::ExternalFunctionItem &function) { NodeId scope_node_id = function.get_node_id (); + + resolve_visibility (function.get_visibility ()); + resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); resolver->get_label_scope ().push (scope_node_id); @@ -945,6 +984,8 @@ ResolveExternItem::visit (AST::ExternalFunctionItem &function) void ResolveExternItem::visit (AST::ExternalStaticItem &item) { + resolve_visibility (item.get_visibility ()); + ResolveType::go (item.get_type ().get (), item.get_node_id ()); } diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc index 3e4bb33..c7597a2 100644 --- a/gcc/rust/resolve/rust-ast-resolve-path.cc +++ b/gcc/rust/resolve/rust-ast-resolve-path.cc @@ -279,90 +279,69 @@ ResolvePath::resolve_segments (CanonicalPath prefix, size_t offs, } } -void -ResolvePath::resolve_path (AST::SimplePath *expr) +static bool +lookup_and_insert_segment (Resolver *resolver, CanonicalPath path, + NodeId segment_id, NodeId *to_resolve, bool &is_type) { - // resolve root segment first then apply segments in turn - auto &segs = expr->get_segments (); - auto &root_segment = segs.at (0); - auto &root_ident_seg = root_segment.get_segment_name (); - - /** - * TODO: We need to handle functions and types later on for `use` statements. - * So we will also need to check the type scope - * - * bool segment_is_type = false; - * bool segment_is_func = false; - */ - CanonicalPath root_seg_path - = CanonicalPath::new_seg (root_segment.get_node_id (), root_ident_seg); - - // name scope first - if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node)) + if (resolver->get_name_scope ().lookup (path, to_resolve)) { - resolver->insert_resolved_name (root_segment.get_node_id (), - resolved_node); - resolver->insert_new_definition (root_segment.get_node_id (), - Definition{expr->get_node_id (), - parent}); + resolver->insert_resolved_name (segment_id, *to_resolve); } - else + else if (resolver->get_type_scope ().lookup (path, to_resolve)) { - rust_error_at (expr->get_locus (), - "Cannot find path %<%s%> in this scope", - root_segment.as_string ().c_str ()); - return; + is_type = true; + resolver->insert_resolved_type (segment_id, *to_resolve); } - - bool is_single_segment = segs.size () == 1; - if (is_single_segment) + else { - // if (segment_is_type) - // resolver->insert_resolved_type (expr->get_node_id (), resolved_node); - - resolver->insert_resolved_name (expr->get_node_id (), resolved_node); - resolver->insert_new_definition (expr->get_node_id (), - Definition{expr->get_node_id (), - parent}); - return; + return false; } - resolve_simple_path_segments (root_seg_path, 1, expr->get_segments (), - expr->get_node_id (), expr->get_locus ()); + return true; } void -ResolvePath::resolve_simple_path_segments ( - CanonicalPath prefix, size_t offs, - const std::vector<AST::SimplePathSegment> &segs, NodeId expr_node_id, - Location expr_locus) +ResolvePath::resolve_path (AST::SimplePath *simple_path) { - /** - * TODO: We also need to handle types and functions here - */ + // resolve root segment first then apply segments in turn + auto expr_node_id = simple_path->get_node_id (); + auto is_type = false; - CanonicalPath path = prefix; - for (const auto &seg : segs) + auto path = CanonicalPath::create_empty (); + for (const auto &seg : simple_path->get_segments ()) { auto s = ResolveSimplePathSegmentToCanonicalPath::resolve (seg); path = path.append (s); + // Reset state resolved_node = UNKNOWN_NODEID; + is_type = false; - if (resolver->get_name_scope ().lookup (path, &resolved_node)) + if (!lookup_and_insert_segment (resolver, path, seg.get_node_id (), + &resolved_node, is_type)) { - resolver->insert_resolved_name (seg.get_node_id (), resolved_node); - resolver->insert_new_definition (seg.get_node_id (), - Definition{expr_node_id, parent}); + rust_error_at (seg.get_locus (), + "cannot find simple path segment %qs", + seg.as_string ().c_str ()); + return; } } - if (resolved_node != UNKNOWN_NODEID) + if (resolved_node == UNKNOWN_NODEID) { - resolver->insert_resolved_name (expr_node_id, resolved_node); - resolver->insert_new_definition (expr_node_id, - Definition{expr_node_id, parent}); + rust_error_at (simple_path->get_locus (), + "could not resolve simple path %qs", + simple_path->as_string ().c_str ()); + return; } + + if (is_type) + resolver->insert_resolved_type (expr_node_id, resolved_node); + else + resolver->insert_resolved_name (expr_node_id, resolved_node); + + resolver->insert_new_definition (expr_node_id, + Definition{expr_node_id, parent}); } } // namespace Resolver diff --git a/gcc/testsuite/rust/compile/pub_restricted_1.rs b/gcc/testsuite/rust/compile/pub_restricted_1.rs new file mode 100644 index 0000000..01fb65e --- /dev/null +++ b/gcc/testsuite/rust/compile/pub_restricted_1.rs @@ -0,0 +1,14 @@ +pub mod foo { + pub mod bar { + pub fn baz() {} + } +} + +// this is invalid Rust: We just want to make sure the paths get resolved properly +pub(in foo::bar::baz) struct A0; + +pub(in foo::fah::baz) struct A1; // { dg-error "cannot find simple path segment .fah." } +pub(in fro::bulator::saindoux) struct A2; // { dg-error "cannot find simple path segment .fro." } +pub(in foo::bar::saindoux) struct A3; // { dg-error "cannot find simple path segment .saindoux." } + +fn main() {} |