From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by sourceware.org (Postfix) with ESMTPS id 22FD53858D39 for ; Wed, 21 Feb 2024 13:16:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 22FD53858D39 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embecosm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 22FD53858D39 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::52f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708521389; cv=none; b=iXWhQae+ZyPlJGocTVvjR7DCXH9ejk+R3/E7YbdviocCvyPkf8Z6n5Ja5zBIwd8JHCTMyNU+K86Mce8B+45Q3k4LiIuC2qShKzlyQZs/8kn4mpePjAoZYtO6VtiTIUVMijc8OZe37feOtEDH3OYVtzbKaeF6E2tLSF+uvOACVCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708521389; c=relaxed/simple; bh=kYSjXbTmS7GMmuwT7s3ApkjKhQRlg7OtUJJHeZeBh/U=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=hGW9uNII4F+nYZcMoMGu3P3Tn9K9Ozjc8AJddxfDw98mZ/8IGxewOzdfkYV/leD2l1/iZX2DCd4sQVCgTITcqHIOg7Nt5NgEuykzRc+g6GyIDAfjrKuQuU2bDBTtY+TyG1f17CFZiqQE/3IF8TwXTodCEKCiXV9G+BdHrkGt6rg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ed1-x52f.google.com with SMTP id 4fb4d7f45d1cf-564fe0273e4so635743a12.2 for ; Wed, 21 Feb 2024 05:16:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1708521385; x=1709126185; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=2N06jfvF8idQFcaS8roajx/5UmjVIQpLmbcr6ZU5wX8=; b=Tm7z1zOMIeC7g37XR7U9IvFAvI3evL09J9IpMDioNtRJHTHC/Od1W6XHDz2vmKkMwb GxAf5l1MAse+ENr8nynVVFxNqQqA3tuW/p+vJnK1oCQF4pRTWzk+E2SPIffI+tlBWhbY HMStHWYdOzEeutt/eISiiJSzLdAClgTPdvDPenosjTk5iKPDZirSzkUlN0LXuE3ljXaR 8SNoAryamGv1gVmNkQjoFkW/3H33zSWop8wLTll1BudWD1sPeoJ2ZqiijakUAQW4C8ac GgJ8SKN+d9Mi6tvSPI5UeNC0IUtirHK7+pXqyizJKR51gNHHd/m5zP108ECXZEyfp0Nj OHxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708521385; x=1709126185; h=content-transfer-encoding:mime-version:reply-to:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=2N06jfvF8idQFcaS8roajx/5UmjVIQpLmbcr6ZU5wX8=; b=l7cvcc+gyym+ulCWNmHHYdD0kVLTPiD6jmTe77EjfjhoYqVkpQBK4RX+UBmavq2V5r CF+sXx+zV9F7amkDVjjCVAmqQwLJf7cn3QKddW8H2RAW4pgrB0NeYOWLg10hR7Ua75ic OVt50vjLdSNYQ/XFv6ENEget6IDV9UB15lhbpHT6HbOBTuvGYAQ35py1LAH3yq2s67BG jsRQVxgIDZkhIGwJmyJOy1UtDixrPDUfC2fwWqdNEh4zE7PXoFyCZtI73mowcuubG1m2 5ob2/pv2fpepipCIjLfj/sDZlFFKbtXpwhAKgb5moMoxAdg10B9Wk8GWHuvh3S2zkU14 R8JA== X-Gm-Message-State: AOJu0YxwaOP0ofHv+ot+wcTWvPBl6faMpjig+CfDJjTPppALK8ZizL1G MDKrM9rAonwoOI+2oUXSaweJssJFbBG7QfXEp7/T6GFkjsUnbCGLXnu4CjvuJhl1gQ8YvHEoonY = X-Google-Smtp-Source: AGHT+IGTKBv7kU8vpomqGDE8FGgSRS8i9r1LM3Kzwx3VjASuf1UYfK7kWjkFKolbr+PcpVGGUr3x2Q== X-Received: by 2002:a17:906:3499:b0:a3e:d7fe:4c4d with SMTP id g25-20020a170906349900b00a3ed7fe4c4dmr4822008ejb.57.1708521384804; Wed, 21 Feb 2024 05:16:24 -0800 (PST) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id m12-20020a170906160c00b00a3d0a094574sm4927074ejd.66.2024.02.21.05.16.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Feb 2024 05:16:23 -0800 (PST) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Owen Avery Subject: [COMMITTED 3/9] gccrs: Fix rebinding imports Date: Wed, 21 Feb 2024 14:15:21 +0100 Message-ID: <20240221131636.3336103-6-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20240221131636.3336103-2-arthur.cohen@embecosm.com> References: <20240221131636.3336103-2-arthur.cohen@embecosm.com> Reply-To: arthur.cohen@embecosm.com MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: From: Owen Avery gcc/rust/ChangeLog: * resolve/rust-ast-resolve-item.cc (flatten_glob): Use Import class. (flatten_rebind): Likewise. (flatten_list): Likewise. (flatten): Likewise. (flatten_use_dec_to_paths): Likewise. (flatten_use_dec_to_imports): Likewise. (ResolveItem::visit): Likewise. (Import::add_prefix): New. (rust_flatten_nested_glob): Adjust test. (rust_flatten_glob): Likewise. (rust_flatten_rebind_none): Likewise. (rust_flatten_rebind): Likewise. (rust_flatten_rebind_nested): Likewise. (rust_flatten_list): Likewise. * resolve/rust-ast-resolve-item.h (class Import): New. gcc/testsuite/ChangeLog: * rust/compile/use_2.rs: New test. Signed-off-by: Owen Avery --- gcc/rust/resolve/rust-ast-resolve-item.cc | 179 +++++++++++----------- gcc/rust/resolve/rust-ast-resolve-item.h | 23 +++ gcc/testsuite/rust/compile/use_2.rs | 7 + 3 files changed, 116 insertions(+), 93 deletions(-) create mode 100644 gcc/testsuite/rust/compile/use_2.rs diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index e69b945407c..743657bc421 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -824,33 +824,30 @@ ResolveItem::resolve_extern_item (AST::ExternalItem *item) } static void -flatten_glob (const AST::UseTreeGlob &glob, - std::vector &paths); +flatten_glob (const AST::UseTreeGlob &glob, std::vector &imports); static void -flatten_rebind (const AST::UseTreeRebind &glob, - std::vector &paths); +flatten_rebind (const AST::UseTreeRebind &glob, std::vector &imports); static void -flatten_list (const AST::UseTreeList &glob, - std::vector &paths); +flatten_list (const AST::UseTreeList &glob, std::vector &imports); static void -flatten (const AST::UseTree *tree, std::vector &paths) +flatten (const AST::UseTree *tree, std::vector &imports) { switch (tree->get_kind ()) { case AST::UseTree::Glob: { auto glob = static_cast (tree); - flatten_glob (*glob, paths); + flatten_glob (*glob, imports); break; } case AST::UseTree::Rebind: { auto rebind = static_cast (tree); - flatten_rebind (*rebind, paths); + flatten_rebind (*rebind, imports); break; } case AST::UseTree::List: { auto list = static_cast (tree); - flatten_list (*list, paths); + flatten_list (*list, imports); break; } break; @@ -858,36 +855,28 @@ flatten (const AST::UseTree *tree, std::vector &paths) } static void -flatten_glob (const AST::UseTreeGlob &glob, std::vector &paths) +flatten_glob (const AST::UseTreeGlob &glob, std::vector &imports) { if (glob.has_path ()) - paths.emplace_back (glob.get_path ()); + imports.emplace_back (glob.get_path (), true, std::string ()); } static void -flatten_rebind (const AST::UseTreeRebind &rebind, - std::vector &paths) +flatten_rebind (const AST::UseTreeRebind &rebind, std::vector &imports) { auto path = rebind.get_path (); - if (rebind.has_path ()) - paths.emplace_back (path); - // FIXME: Do we want to emplace the rebind here as well? + std::string label; if (rebind.has_identifier ()) - { - auto rebind_path = path; - auto new_seg = rebind.get_identifier (); - - // Add the identifier as a new path - rebind_path.get_segments ().back () - = AST::SimplePathSegment (new_seg.as_string (), UNDEF_LOCATION); + label = rebind.get_identifier ().as_string (); + else + label = path.get_final_segment ().as_string (); - paths.emplace_back (rebind_path); - } + imports.emplace_back (path, false, label); } static void -flatten_list (const AST::UseTreeList &list, std::vector &paths) +flatten_list (const AST::UseTreeList &list, std::vector &imports) { auto prefix = AST::SimplePath::create_empty (); if (list.has_path ()) @@ -895,21 +884,25 @@ flatten_list (const AST::UseTreeList &list, std::vector &paths) for (const auto &tree : list.get_trees ()) { - auto sub_paths = std::vector (); - flatten (tree.get (), sub_paths); + // append imports to the main list, then modify them in-place + auto start_idx = imports.size (); + flatten (tree.get (), imports); - for (auto &sub_path : sub_paths) - { - auto new_path = prefix; - std::copy (sub_path.get_segments ().begin (), - sub_path.get_segments ().end (), - std::back_inserter (new_path.get_segments ())); - - paths.emplace_back (new_path); - } + for (auto import = imports.begin () + start_idx; import != imports.end (); + import++) + import->add_prefix (prefix); } } +void +Import::add_prefix (AST::SimplePath prefix) +{ + AST::SimplePath old_path (std::move (path)); + path = std::move (prefix); + std::move (old_path.get_segments ().begin (), old_path.get_segments ().end (), + std::back_inserter (path.get_segments ())); +} + /** * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve. * @@ -930,21 +923,21 @@ flatten_list (const AST::UseTreeList &list, std::vector &paths) * Finally in the third case, we want to create two SimplePaths to resolve: * [some::path::one, some::path::two] */ -static std::vector -flatten_use_dec_to_paths (const AST::UseDeclaration &use_item) +static std::vector +flatten_use_dec_to_imports (const AST::UseDeclaration &use_item) { - auto paths = std::vector (); + auto imports = std::vector (); const auto &tree = use_item.get_tree (); - flatten (tree.get (), paths); + flatten (tree.get (), imports); - return paths; + return imports; } void ResolveItem::visit (AST::UseDeclaration &use_item) { - std::vector to_resolve = flatten_use_dec_to_paths (use_item); + std::vector to_resolve = flatten_use_dec_to_imports (use_item); // FIXME: I think this does not actually resolve glob use-decls and is going // the wrong way about it. RFC #1560 specifies the following: @@ -956,18 +949,20 @@ ResolveItem::visit (AST::UseDeclaration &use_item) // Which is the opposite of what we're doing if I understand correctly? NodeId current_module = resolver->peek_current_module_scope (); - for (auto &path : to_resolve) + for (auto &import : to_resolve) { + auto &path = import.get_path (); + rust_debug ("resolving use-decl path: [%s]", path.as_string ().c_str ()); NodeId resolved_node_id = ResolvePath::go (&path); bool ok = resolved_node_id != UNKNOWN_NODEID; if (!ok) continue; - const AST::SimplePathSegment &final_seg = path.get_segments ().back (); + if (import.is_glob ()) + continue; - auto decl - = CanonicalPath::new_seg (resolved_node_id, final_seg.as_string ()); + auto decl = CanonicalPath::new_seg (resolved_node_id, import.get_name ()); mappings->insert_module_child_item (current_module, decl); resolver->get_type_scope ().insert (decl, resolved_node_id, @@ -1079,13 +1074,13 @@ rust_flatten_nested_glob (void) = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED, foobar, UNDEF_LOCATION); - auto paths = std::vector (); - Rust::Resolver::flatten_glob (glob, paths); + auto imports = std::vector (); + Rust::Resolver::flatten_glob (glob, imports); - ASSERT_TRUE (!paths.empty ()); - ASSERT_EQ (paths.size (), 1); - ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar"); + ASSERT_TRUE (!imports.empty ()); + ASSERT_EQ (imports.size (), 1); + ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); + ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); } static void @@ -1097,12 +1092,12 @@ rust_flatten_glob (void) = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED, frob, UNDEF_LOCATION); - auto paths = std::vector (); - Rust::Resolver::flatten_glob (glob, paths); + auto imports = std::vector (); + Rust::Resolver::flatten_glob (glob, imports); - ASSERT_TRUE (!paths.empty ()); - ASSERT_EQ (paths.size (), 1); - ASSERT_EQ (paths[0], "frobulator"); + ASSERT_TRUE (!imports.empty ()); + ASSERT_EQ (imports.size (), 1); + ASSERT_EQ (imports[0].get_path (), "frobulator"); } static void @@ -1115,13 +1110,13 @@ rust_flatten_rebind_none (void) auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, foobar, UNDEF_LOCATION); - auto paths = std::vector (); - Rust::Resolver::flatten_rebind (rebind, paths); + auto imports = std::vector (); + Rust::Resolver::flatten_rebind (rebind, imports); - ASSERT_TRUE (!paths.empty ()); - ASSERT_EQ (paths.size (), 1); - ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar"); + ASSERT_TRUE (!imports.empty ()); + ASSERT_EQ (imports.size (), 1); + ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); + ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); } static void @@ -1132,13 +1127,13 @@ rust_flatten_rebind (void) auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER, frob, UNDEF_LOCATION, {"saindoux"}); - auto paths = std::vector (); - Rust::Resolver::flatten_rebind (rebind, paths); + auto imports = std::vector (); + Rust::Resolver::flatten_rebind (rebind, imports); - ASSERT_TRUE (!paths.empty ()); - ASSERT_EQ (paths.size (), 2); - ASSERT_EQ (paths[0], "frobulator"); - ASSERT_EQ (paths[1], "saindoux"); + ASSERT_TRUE (!imports.empty ()); + ASSERT_EQ (imports.size (), 1); + ASSERT_EQ (imports[0].get_path (), "frobulator"); + ASSERT_EQ (imports[0].get_name (), "saindoux"); } static void @@ -1154,17 +1149,15 @@ rust_flatten_rebind_nested (void) = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER, foo_bar_baz, UNDEF_LOCATION, {"saindoux"}); - auto paths = std::vector (); - Rust::Resolver::flatten_rebind (rebind, paths); - - ASSERT_TRUE (!paths.empty ()); - ASSERT_EQ (paths.size (), 2); - ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (paths[0].get_segments ()[2].as_string (), "baz"); - ASSERT_EQ (paths[1].get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (paths[1].get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (paths[1].get_segments ()[2].as_string (), "saindoux"); + auto imports = std::vector (); + Rust::Resolver::flatten_rebind (rebind, imports); + + ASSERT_TRUE (!imports.empty ()); + ASSERT_EQ (imports.size (), 1); + ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); + ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); + ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz"); + ASSERT_EQ (imports[0].get_name (), "saindoux"); } static void @@ -1194,17 +1187,17 @@ rust_flatten_list (void) = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED, foo_bar, std::move (uses), UNDEF_LOCATION); - auto paths = std::vector (); - Rust::Resolver::flatten_list (list, paths); - - ASSERT_TRUE (!paths.empty ()); - ASSERT_EQ (paths.size (), 2); - ASSERT_EQ (paths[0].get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (paths[0].get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (paths[0].get_segments ()[2].as_string (), "baz"); - ASSERT_EQ (paths[1].get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (paths[1].get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (paths[1].get_segments ()[2].as_string (), "bul"); + auto imports = std::vector (); + Rust::Resolver::flatten_list (list, imports); + + ASSERT_TRUE (!imports.empty ()); + ASSERT_EQ (imports.size (), 2); + ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); + ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); + ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz"); + ASSERT_EQ (imports[1].get_path ().get_segments ()[0].as_string (), "foo"); + ASSERT_EQ (imports[1].get_path ().get_segments ()[1].as_string (), "bar"); + ASSERT_EQ (imports[1].get_path ().get_segments ()[2].as_string (), "bul"); } static void diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 0c7b7527c44..e397ffdfe8b 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -124,6 +124,29 @@ private: const CanonicalPath &canonical_prefix; }; +class Import +{ +public: + Import (AST::SimplePath path, bool is_glob, std::string name) + : path (path), is_glob_f (is_glob), name (name) + {} + + AST::SimplePath &get_path () { return path; } + + const AST::SimplePath &get_path () const { return path; } + + bool is_glob () const { return is_glob_f; } + + const std::string &get_name () const { return name; } + + void add_prefix (AST::SimplePath prefix); + +private: + AST::SimplePath path; + bool is_glob_f; + std::string name; +}; + } // namespace Resolver } // namespace Rust diff --git a/gcc/testsuite/rust/compile/use_2.rs b/gcc/testsuite/rust/compile/use_2.rs new file mode 100644 index 00000000000..b89ff82caaa --- /dev/null +++ b/gcc/testsuite/rust/compile/use_2.rs @@ -0,0 +1,7 @@ +mod foo { + pub struct S; +} + +use foo::S as T; + +const V: T = T; // { dg-warning "unused name" } -- 2.42.1