From patchwork Thu Aug 1 14:57:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arthur Cohen X-Patchwork-Id: 1967798 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=embecosm.com header.i=@embecosm.com header.a=rsa-sha256 header.s=google header.b=dODb+I55; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WZXpw0X1Vz1ybV for ; Fri, 2 Aug 2024 01:25:44 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 20D683860008 for ; Thu, 1 Aug 2024 15:25:42 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ed1-x52a.google.com (mail-ed1-x52a.google.com [IPv6:2a00:1450:4864:20::52a]) by sourceware.org (Postfix) with ESMTPS id 65C553860C30 for ; Thu, 1 Aug 2024 14:59:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 65C553860C30 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 65C553860C30 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::52a ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722524409; cv=none; b=rLGDsM6DlP6862+/YgXcDy7BFz0sUamY0wh467tFs23jDEQyMkOZ3MxsW3Hf1prlz2kMZKc33nVdMWWBho1diWnhCK5eeuajyEMRiqVuSEOHhe6SxEckadn8V2s9Ci4iOhSPD9rAHoGphHUtQoFt5pAxzuYN1Vea/mfaUuZ5FxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722524409; c=relaxed/simple; bh=e87ULrDkDDHB0Swy9844qDGBPCkU/d3lB5tPJeKVVfg=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=YnOw54EGVpYo9WflaPB7jhXPMKpH3cWqppkm7J46JIKvbfKdxmkkfrgB2crxbrrsmBtTbEeE0AMqRU2q0Nw6wOTo83uP40i/CizEx+/hoZu9rSW1dZeoqRyg9Vh1xcFhMkXCEgyjOCZcdsZFw9JM/+b3vKxpExEiefoc4KdcYdY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-ed1-x52a.google.com with SMTP id 4fb4d7f45d1cf-5a1337cfbb5so11614334a12.3 for ; Thu, 01 Aug 2024 07:59:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; t=1722524374; x=1723129174; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PG52CyfCFAZngyPJ7/Hx01vARfyX6NfzCo/sNn9QnTA=; b=dODb+I55PiPnjC0X7m8bW19U/GdESQ3UMccis/IBPgnmKLwAcsQJRkDtRjl6ZY70HQ V3lIezF8lhGbHqo3EB10QfwWuabpODxcI+UMUuX252rK/Pt38CL9bUCd+3gl74gEOQAL Nv0I7XtB51dxR34+t9js2gQYzsArMlSWtyQBHPjdUbJugB71hApDBBvIPoI39MFpEQ4I 0sJkIjSMtDmpDZ26IkaRnuWDeP0lGvVmjocCsdR6jHA0Zon5sZ6ZANYf6xrmszD8ND5y 1yUFM9AA4wb1gT1BBjmIUlLCCDrP7E559a7LY4DYr0ywZkDf2c3I5hJoXY6UbskfGLsO xzUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722524374; x=1723129174; h=content-transfer-encoding:mime-version: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=PG52CyfCFAZngyPJ7/Hx01vARfyX6NfzCo/sNn9QnTA=; b=mDDbWnnShzZDod63asnvKXOofZtLVVQfTUxHweZy8lW2uOu57Au87CyrXLCrv6olul PH8Xi9SCopZ0zNrZqt6epGLDISkjVKe1hzNgMVJXs/xLBqyLjogqfw4s7hx5ZwwA+fxm XK9WpczGltABD6er0roQEVUazHt//sPwZGDB8MB0RFQQyfy7kUm6plhfG1DIviW9mQ+9 7T4qdEqreLLc/E4zqnLmcldPZlkxHQHMBBcWIyInpBjcWlLzUB/sN6oT/rZRjxsdZWrz 2Tu8DTorWXA/vp/QS6M0nCHLdsT+xgf9N6ZYxbpTWC2klyMcuZpMFY4ub4eEAu4lFOQm wFeA== X-Gm-Message-State: AOJu0Yxzmv8daUx6OQHJLSOMX6JL1RNQ+QO7uB/CMTmoBSpHHzQItw8l 97abhYSbc+FWcC3qS4Zyfj5PffQFDCvhHi9FY1oDgrdYHbJ/aoM5bVWfgDJ8hYzBn2KWzfguZ2Y 361cY X-Google-Smtp-Source: AGHT+IHPxB26U2kSOyeRF6gLcvzHspF49kbYQEmze7uaBgceQ34T2PPMJz5fUKY99iJxGISaV0k2Ig== X-Received: by 2002:a50:ec8d:0:b0:5a2:2b56:e090 with SMTP id 4fb4d7f45d1cf-5b7f3bcf9aemr412036a12.13.1722524373706; Thu, 01 Aug 2024 07:59:33 -0700 (PDT) Received: from platypus.lan ([2a04:cec2:9:dc84:3622:6733:ff49:ee91]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5ac63590592sm10252456a12.25.2024.08.01.07.59.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Aug 2024 07:59:33 -0700 (PDT) From: Arthur Cohen To: gcc-patches@gcc.gnu.org Cc: gcc-rust@gcc.gnu.org, Arthur Cohen Subject: [PATCH 067/125] gccrs: late: Setup builtin types properly, change Rib API Date: Thu, 1 Aug 2024 16:57:03 +0200 Message-ID: <20240801145809.366388-69-arthur.cohen@embecosm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240801145809.366388-2-arthur.cohen@embecosm.com> References: <20240801145809.366388-2-arthur.cohen@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-14.1 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 autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org gcc/rust/ChangeLog: * resolve/rust-forever-stack.hxx: Start using Rib::Definition for shadowable information. * resolve/rust-late-name-resolver-2.0.cc (next_node_id): New. (next_hir_id): New. (Late::setup_builtin_types): Improve builtin type setup. * resolve/rust-rib.cc (Rib::Definition::Definition): New constructor. (Rib::Definition::Shadowable): Likewise. (Rib::Definition::NonShadowable): Likewise. (Rib::Rib): Fix general constructor. (Rib::insert): Use Definition class. (Rib::get): Likewise. * resolve/rust-rib.h: New Definition class, new prototypes. --- gcc/rust/resolve/rust-forever-stack.hxx | 22 +++-- .../resolve/rust-late-name-resolver-2.0.cc | 84 +++++++++++++------ gcc/rust/resolve/rust-rib.cc | 38 +++++++-- gcc/rust/resolve/rust-rib.h | 30 +++++-- 4 files changed, 126 insertions(+), 48 deletions(-) diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 0aa9943191e..a2fdce98362 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -100,9 +100,9 @@ ForeverStack::pop () } static tl::expected -insert_inner (Rib &rib, std::string name, NodeId node, bool can_shadow) +insert_inner (Rib &rib, std::string name, Rib::Definition definition) { - return rib.insert (name, node, can_shadow); + return rib.insert (name, definition); } template @@ -115,7 +115,8 @@ ForeverStack::insert (Identifier name, NodeId node) // pass, we might end up in a situation where it is okay to re-add new names. // Do we just ignore that here? Do we keep track of if the Rib is new or not? // should our cursor have info on the current node like "is it newly pushed"? - return insert_inner (innermost_rib, name.as_string (), node, false); + return insert_inner (innermost_rib, name.as_string (), + Rib::Definition::NonShadowable (node)); } template @@ -126,7 +127,8 @@ ForeverStack::insert_at_root (Identifier name, NodeId node) // inserting in the root of the crate is never a shadowing operation, even for // macros - return insert_inner (root_rib, name.as_string (), node, false); + return insert_inner (root_rib, name.as_string (), + Rib::Definition::NonShadowable (node)); } // Specialization for Macros and Labels - where we are allowed to shadow @@ -135,14 +137,16 @@ template <> inline tl::expected ForeverStack::insert (Identifier name, NodeId node) { - return insert_inner (peek (), name.as_string (), node, true); + return insert_inner (peek (), name.as_string (), + Rib::Definition::Shadowable (node)); } template <> inline tl::expected ForeverStack::insert (Identifier name, NodeId node) { - return insert_inner (peek (), name.as_string (), node, true); + return insert_inner (peek (), name.as_string (), + Rib::Definition::Shadowable (node)); } template @@ -455,10 +459,10 @@ template tl::optional::Node &, std::string>> ForeverStack::dfs (ForeverStack::Node &starting_point, NodeId to_find) { - auto &values = starting_point.rib.get_values (); + auto values = starting_point.rib.get_values (); for (auto &kv : values) - if (kv.second == to_find) + if (kv.second.id == to_find) return {{starting_point, kv.first}}; for (auto &child : starting_point.children) @@ -568,7 +572,7 @@ ForeverStack::stream_rib (std::stringstream &stream, const Rib &rib, stream << next << "rib: {\n"; for (const auto &kv : rib.get_values ()) - stream << next_next << kv.first << ": " << kv.second << "\n"; + stream << next_next << kv.first << ": " << kv.second.id << "\n"; stream << next << "},\n"; } diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index 50034073edf..3090bbeff2a 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -18,8 +18,10 @@ #include "optional.h" #include "rust-ast-full.h" +#include "rust-hir-map.h" #include "rust-late-name-resolver-2.0.h" #include "rust-default-resolver.h" +#include "rust-name-resolution-context.h" #include "rust-path.h" #include "rust-tyty.h" #include "rust-hir-type-check.h" @@ -29,41 +31,75 @@ namespace Resolver2_0 { Late::Late (NameResolutionContext &ctx) : DefaultResolver (ctx) {} +static NodeId +next_node_id () +{ + return Analysis::Mappings::get ()->get_next_node_id (); +}; + +static HirId +next_hir_id () +{ + return Analysis::Mappings::get ()->get_next_hir_id (); +}; + void Late::setup_builtin_types () { - auto next_id = [this] () { return ctx.mappings.get_next_hir_id (); }; - - static const std::pair builtins[] = { - {"u8", new TyTy::UintType (next_id (), TyTy::UintType::U8)}, - {"u16", new TyTy::UintType (next_id (), TyTy::UintType::U16)}, - {"u32", new TyTy::UintType (next_id (), TyTy::UintType::U32)}, - {"u64", new TyTy::UintType (next_id (), TyTy::UintType::U64)}, - {"u128", new TyTy::UintType (next_id (), TyTy::UintType::U128)}, - {"i8", new TyTy::IntType (next_id (), TyTy::IntType::I8)}, - {"i16", new TyTy::IntType (next_id (), TyTy::IntType::I16)}, - {"i32", new TyTy::IntType (next_id (), TyTy::IntType::I32)}, - {"i64", new TyTy::IntType (next_id (), TyTy::IntType::I64)}, - {"i128", new TyTy::IntType (next_id (), TyTy::IntType::I128)}, - {"f32", new TyTy::FloatType (next_id (), TyTy::FloatType::F32)}, - {"f64", new TyTy::FloatType (next_id (), TyTy::FloatType::F64)}, - {"usize", new TyTy::USizeType (next_id ())}, - {"isize", new TyTy::ISizeType (next_id ())}, - // missing char, str, never, () - // does name resolution play a part for this? or is it all at typechecking? - // yeah it seems to be name resolution as well, which makes sense + // access the global type context to setup the TyTys + auto &ty_ctx = *Resolver::TypeCheckContext::get (); + + // Late builtin type struct helper + struct LType + { + std::string name; + NodeId node_id; + NodeId hir_id; + TyTy::BaseType *type; + + explicit LType (std::string name, TyTy::BaseType *type) + : name (name), node_id (next_node_id ()), hir_id (type->get_ref ()), + type (type) + {} + }; + + static const LType builtins[] = { + {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))}, + {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))}, + {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))}, + {LType ("u64", new TyTy::UintType (next_hir_id (), TyTy::UintType::U64))}, + {LType ("u128", new TyTy::UintType (next_hir_id (), TyTy::UintType::U128))}, + {LType ("i8", new TyTy::IntType (next_hir_id (), TyTy::IntType::I8))}, + {LType ("i16", new TyTy::IntType (next_hir_id (), TyTy::IntType::I16))}, + {LType ("i32", new TyTy::IntType (next_hir_id (), TyTy::IntType::I32))}, + {LType ("i64", new TyTy::IntType (next_hir_id (), TyTy::IntType::I64))}, + {LType ("i128", new TyTy::IntType (next_hir_id (), TyTy::IntType::I128))}, + {LType ("f32", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F32))}, + {LType ("f64", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F64))}, + {LType ("usize", new TyTy::USizeType (next_hir_id ()))}, + {LType ("isize", new TyTy::ISizeType (next_hir_id ()))}, + {LType ("char", new TyTy::CharType (next_hir_id ()))}, + {LType ("str", new TyTy::StrType (next_hir_id ()))}, + {LType ("!", new TyTy::NeverType (next_hir_id ()))}, + + // the unit type `()` does not play a part in name-resolution - so we only + // insert it in the type context... }; for (const auto &builtin : builtins) { // we should be able to use `insert_at_root` or `insert` here, since we're // at the root :) hopefully! - auto ok - = ctx.types.insert (builtin.first, builtin.second->get_ref () - /* FIXME: Invalid! This returns an *HirId* */); - + auto ok = ctx.types.insert (builtin.name, builtin.node_id); rust_assert (ok); + + ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id); + ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type); } + + // ...here! + auto *unit_type = TyTy::TupleType::get_unit_type (next_hir_id ()); + ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type); } void diff --git a/gcc/rust/resolve/rust-rib.cc b/gcc/rust/resolve/rust-rib.cc index a1981498673..dee3a09ad49 100644 --- a/gcc/rust/resolve/rust-rib.cc +++ b/gcc/rust/resolve/rust-rib.cc @@ -17,10 +17,27 @@ // . #include "rust-rib.h" +#include "rust-name-resolution-context.h" namespace Rust { namespace Resolver2_0 { +Rib::Definition::Definition (NodeId id, bool shadowable) + : id (id), shadowable (shadowable) +{} + +Rib::Definition +Rib::Definition::Shadowable (NodeId id) +{ + return Definition (id, true); +} + +Rib::Definition +Rib::Definition::NonShadowable (NodeId id) +{ + return Definition (id, false); +} + DuplicateNameError::DuplicateNameError (std::string name, NodeId existing) : name (name), existing (existing) {} @@ -31,20 +48,23 @@ Rib::Rib (Kind kind, std::string identifier, NodeId id) : Rib (kind, {{identifier, id}}) {} -Rib::Rib (Kind kind, std::unordered_map values) - : kind (kind), values (std::move (values)) -{} +Rib::Rib (Kind kind, std::unordered_map to_insert) + : kind (kind) +{ + for (auto &value : to_insert) + values.insert ({value.first, Definition::NonShadowable (value.second)}); +} tl::expected -Rib::insert (std::string name, NodeId id, bool can_shadow) +Rib::insert (std::string name, Definition def) { - auto res = values.insert ({name, id}); - auto inserted_id = res.first->second; + auto res = values.insert ({name, def}); + auto inserted_id = res.first->second.id; auto existed = !res.second; // if we couldn't insert, the element already exists - exit with an error, // unless shadowing is allowed - if (existed && !can_shadow) + if (existed && !def.shadowable) return tl::make_unexpected (DuplicateNameError (name, inserted_id)); // return the NodeId @@ -59,10 +79,10 @@ Rib::get (const std::string &name) if (it == values.end ()) return {}; - return it->second; + return it->second.id; } -const std::unordered_map & +const std::unordered_map & Rib::get_values () const { return values; diff --git a/gcc/rust/resolve/rust-rib.h b/gcc/rust/resolve/rust-rib.h index da777bb9ba7..732ad76b805 100644 --- a/gcc/rust/resolve/rust-rib.h +++ b/gcc/rust/resolve/rust-rib.h @@ -103,6 +103,24 @@ struct DuplicateNameError class Rib { public: + // TODO: Rename the class? to what? Binding? Declaration? + // This is useful for items which are in namespaces where shadowing is not + // allowed, but which are still shadowable! for example, when you do a glob + // import, if a later import has the same name as an item imported in the glob + // import, that glob imported item will need to get shadowed + class Definition + { + public: + static Definition NonShadowable (NodeId id); + static Definition Shadowable (NodeId id); + + NodeId id; + bool shadowable; + + private: + Definition (NodeId id, bool shadowable); + }; + enum class Kind { Normal, @@ -131,15 +149,14 @@ public: * Insert a new node in the rib * * @param name The name associated with the AST node - * @param id Its NodeId - * @param can_shadow If the newly inserted value can shadow an existing one + * @param def The `Definition` to insert * * @return `DuplicateNameError` if the node is already present in the rib. The * `DuplicateNameError` class contains the NodeId of the existing * node. Returns the new NodeId on success. */ - tl::expected insert (std::string name, NodeId id, - bool can_shadow = false); + tl::expected insert (std::string name, + Definition def); /** * Access an inserted NodeId. @@ -149,10 +166,11 @@ public: tl::optional get (const std::string &name); /* View all the values stored in the rib */ - const std::unordered_map &get_values () const; + const std::unordered_map &get_values () const; private: - std::unordered_map values; + // TODO: Switch this to (NodeId, shadowable = false); + std::unordered_map values; }; } // namespace Resolver2_0