From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id B37D43857C76 for ; Tue, 30 Jan 2024 12:11:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org B37D43857C76 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 B37D43857C76 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::332 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706616710; cv=none; b=EqnxqWEzkhML4xa7vw94tyiUvhh6rNtXvarQNpWOH8CNQ7eZOP62TvVkCd5BphjiWbB69KCPvzWonNvRkKXc5vTfYwWtQhJ42dcvV4gaSGc3Siy5HaEGIzs6IYM70IucVrppdXmJIfdhRyesHpopYHjqfn1i0urrP0WWm681tjE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706616710; c=relaxed/simple; bh=BVKJ8sACXVsmhFc//7BqHY5D2+2LOSvczYxW6em1ET8=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=hzHavnMMYRw11k9dqgVVP0L3+tQYunNYF15mZs6pKUCaAbFO5kzcugcyYA3Ew077TLcsTgRKoLdvuDUyTiEAef52m7e/tw9hfEGUxVnSn6St9bw1J1p7akOzkfqVczfw+6eFXj41E/tevqXD7oIM6ixD9wry/cMh8RJcDqusIkM= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-40e7e2e04f0so44312545e9.1 for ; Tue, 30 Jan 2024 04:11:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1706616682; x=1707221482; 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=wGS4ALiOUPQYlG2nSV3vFitujulFJ0ez2ghcKPHcTGI=; b=X2Hj9FDcRFTP+nqNQIGLYYOV8riEIuIuz3OA7rM269Gm5DQhhA45YFkwmXFR8GQJ4b eEkilMipSE7p80t54XcndCbUM+DRtmoaufN1Aj5YXCQv+Ed8ayUZNDG1jDGyGdz6OgqY bnubyUrFWbXESZQch1WQ66HAWf1I285B3GLyRDpxfE8n8nzqz1lHjkBTAwb+S23rKfIy E/wJfQ1354H3wjFVPRQo9b8XNa+CI1Td/dPbpI+5qU48enynHZj41fdePQc2v8ByTozi FpBDV/RMRAAo8UFfxLyfcLthP8uZfHcDWj3FGeEXTesbFp+nEESH9hNSrFJ8vwdsIo3n iqGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706616682; x=1707221482; 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=wGS4ALiOUPQYlG2nSV3vFitujulFJ0ez2ghcKPHcTGI=; b=tJTd1ErdC0VIDxXFEBCW4xcuREMY4hUZ1Ma2d4rbr2MpE1CjFicy3Kys7sCumvAK5w lbNgNalwbujEp89nhdWdIM5BAu+u0YRFMf3X1uUEvLGWTO3kAVGCpvbNEK6Jt1HcAIvi KSY7bC9QhUSR/nI2oBaUF2aEQKJWzLpFQ9JAV3VElKMhittCZDxZAy7KGY7IOZuAE3kh 3pacePc9yp0v92cvvEk4/s0hi9DRDcTyRBu5N4s5Fu1vIrTT6GMad7hWGZOVQUegtV0c 5umduI/vBE0y1EQXLZssm53ROihC8GxGRrvODX/w864X0ncL1jLN3kohaIuhlFD+pvGJ fnRA== X-Gm-Message-State: AOJu0YzUmSpxRYQSTBUXx6p/xicBtXNepE06zmQMIhxNkPcYHOPfQ4mh jzWv8THouaSvFToYf7M0DYg2CUI8di1S8WDh62oHEWWyFUbTGvwPH3ApH9Xi+g== X-Google-Smtp-Source: AGHT+IGig/rqVithMSgU7aKWeOyH5T1lTPcrCLpN1oio8uIqQIIcwV4ic/RiT05/YzhaIW1n897UIQ== X-Received: by 2002:a5d:4d01:0:b0:337:bfe8:5bfd with SMTP id z1-20020a5d4d01000000b00337bfe85bfdmr5158861wrt.50.1706616682519; Tue, 30 Jan 2024 04:11:22 -0800 (PST) Received: from platypus.localdomain ([62.23.166.218]) by smtp.gmail.com with ESMTPSA id f9-20020a056000036900b00339307d9d31sm10569894wrf.112.2024.01.30.04.11.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 04:11:22 -0800 (PST) From: arthur.cohen@embecosm.com To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Arthur Cohen Subject: [COMMITTED 043/101] gccrs: toplevel: Resolve `use` declarations Date: Tue, 30 Jan 2024 13:06:59 +0100 Message-ID: <20240130121026.807464-46-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.42.1 In-Reply-To: <20240130121026.807464-2-arthur.cohen@embecosm.com> References: <20240130121026.807464-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,KAM_SHORT,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: Arthur Cohen gcc/rust/ChangeLog: * resolve/rust-toplevel-name-resolver-2.0.cc (TopLevel::insert_or_error_out): New functions. (TopLevel::handle_use_dec): New function. (flatten_rebind): Likewise. (flatten_list): Likewise. (flatten_glob): Likewise. (flatten): Likewise. (TopLevel::visit): Visit various `use` declaration nodes. * resolve/rust-toplevel-name-resolver-2.0.h: Declare functions and visitors. --- .../rust-toplevel-name-resolver-2.0.cc | 187 +++++++++++++++++- .../resolve/rust-toplevel-name-resolver-2.0.h | 11 ++ 2 files changed, 194 insertions(+), 4 deletions(-) diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc index b9d0bc7c0ac..46113a8a46b 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc @@ -17,6 +17,7 @@ // . #include "rust-toplevel-name-resolver-2.0.h" +#include "optional.h" #include "rust-ast-full.h" #include "rust-hir-map.h" #include "rust-attribute-values.h" @@ -33,11 +34,16 @@ void TopLevel::insert_or_error_out (const Identifier &identifier, const T &node, Namespace ns) { - auto loc = node.get_locus (); - auto node_id = node.get_node_id (); + insert_or_error_out (identifier, node.get_locus (), node.get_node_id (), ns); +} +void +TopLevel::insert_or_error_out (const Identifier &identifier, + const location_t &locus, const NodeId &node_id, + Namespace ns) +{ // keep track of each node's location to provide useful errors - node_locations.emplace (node_id, loc); + node_locations.emplace (node_id, locus); auto result = ctx.insert (identifier, node_id, ns); @@ -46,7 +52,7 @@ TopLevel::insert_or_error_out (const Identifier &identifier, const T &node, // can we do something like check if the node id is the same? if it is the // same, it's not an error, just the resolver running multiple times? - rich_location rich_loc (line_table, loc); + rich_location rich_loc (line_table, locus); rich_loc.add_range (node_locations[result.error ().existing]); rust_error_at (rich_loc, ErrorCode::E0428, "%qs defined multiple times", @@ -308,5 +314,178 @@ TopLevel::visit (AST::ConstantItem &const_item) ctx.scoped (Rib::Kind::ConstantItem, const_item.get_node_id (), expr_vis); } +bool +TopLevel::handle_use_dec (AST::SimplePath path) +{ + // TODO: Glob imports can get shadowed by regular imports and regular items. + // So we need to store them in a specific way in the ForeverStack - which can + // also probably be used by labels and macros etc. Like store it as a + // `Shadowable(NodeId)` instead of just a `NodeId` + + auto locus = path.get_final_segment ().get_locus (); + auto declared_name = path.get_final_segment ().as_string (); + + // in what namespace do we perform path resolution? All of them? see which one + // matches? Error out on ambiguities? + // so, apparently, for each one that matches, add it to the proper namespace + // :( + + auto found = false; + + auto resolve_and_insert = [this, &found, &declared_name, + locus] (Namespace ns, + const AST::SimplePath &path) { + tl::optional resolved = tl::nullopt; + + // FIXME: resolve_path needs to return an `expected` so + // that we can improve it with hints or location or w/ever. and maybe + // only emit it the first time. + switch (ns) + { + case Namespace::Values: + resolved = ctx.values.resolve_path (path.get_segments ()); + break; + case Namespace::Types: + resolved = ctx.types.resolve_path (path.get_segments ()); + break; + case Namespace::Macros: + resolved = ctx.macros.resolve_path (path.get_segments ()); + break; + case Namespace::Labels: + // TODO: Is that okay? + rust_unreachable (); + } + + // FIXME: Ugly + (void) resolved.map ([this, &found, &declared_name, locus, ns] (NodeId id) { + found = true; + + // what do we do with the id? + insert_or_error_out (declared_name, locus, id, ns); + + return id; + }); + }; + + // do this for all namespaces (even Labels?) + + resolve_and_insert (Namespace::Values, path); + resolve_and_insert (Namespace::Types, path); + resolve_and_insert (Namespace::Macros, path); + + // TODO: No labels? No, right? + + return found; +} + +static void +flatten_rebind (const AST::UseTreeRebind &glob, + std::vector &paths); +static void +flatten_list (const AST::UseTreeList &glob, + std::vector &paths); +static void +flatten_glob (const AST::UseTreeGlob &glob, + std::vector &paths); + +static void +flatten (const AST::UseTree *tree, std::vector &paths) +{ + switch (tree->get_kind ()) + { + case AST::UseTree::Rebind: { + auto rebind = static_cast (tree); + flatten_rebind (*rebind, paths); + break; + } + case AST::UseTree::List: { + auto list = static_cast (tree); + flatten_list (*list, paths); + break; + } + case AST::UseTree::Glob: { + rust_sorry_at (tree->get_locus (), "cannot resolve glob imports yet"); + auto glob = static_cast (tree); + flatten_glob (*glob, paths); + break; + } + break; + } +} + +static void +flatten_rebind (const AST::UseTreeRebind &rebind, + std::vector &paths) +{ + auto path = rebind.get_path (); + + // FIXME: Do we want to emplace the rebind here as well? + 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); + + paths.emplace_back (rebind_path); + } + else + { + paths.emplace_back (path); + } +} + +static void +flatten_list (const AST::UseTreeList &list, std::vector &paths) +{ + auto prefix = AST::SimplePath::create_empty (); + if (list.has_path ()) + prefix = list.get_path (); + + for (const auto &tree : list.get_trees ()) + { + auto sub_paths = std::vector (); + flatten (tree.get (), sub_paths); + + 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); + } + } +} + +static void +flatten_glob (const AST::UseTreeGlob &glob, std::vector &paths) +{ + if (glob.has_path ()) + paths.emplace_back (glob.get_path ()); +} + +void +TopLevel::visit (AST::UseDeclaration &use) +{ + auto paths = std::vector (); + + // FIXME: How do we handle `use foo::{self}` imports? Some beforehand cleanup? + // How do we handle module imports in general? Should they get added to all + // namespaces? + + const auto &tree = use.get_tree (); + flatten (tree.get (), paths); + + for (auto &path : paths) + if (!handle_use_dec (path)) + rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433, + "could not resolve import %qs", + path.as_string ().c_str ()); +} + } // namespace Resolver2_0 } // namespace Rust diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h index 95187d7b3fd..996899b0848 100644 --- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h @@ -53,6 +53,9 @@ private: template void insert_or_error_out (const Identifier &identifier, const T &node, Namespace ns); + void insert_or_error_out (const Identifier &identifier, + const location_t &locus, const NodeId &id, + Namespace ns); // FIXME: Do we move these to our mappings? std::unordered_map node_locations; @@ -73,6 +76,14 @@ private: void visit (AST::Union &union_item) override; void visit (AST::ConstantItem &const_item) override; void visit (AST::ExternCrate &crate) override; + + // FIXME: Documentation + // Call this on all the paths of a UseDec - so each flattened path in a + // UseTreeList for example + // FIXME: Should that return `found`? + bool handle_use_dec (AST::SimplePath path); + + void visit (AST::UseDeclaration &use) override; }; } // namespace Resolver2_0 -- 2.42.1