diff options
Diffstat (limited to 'gcc/rust/util')
-rw-r--r-- | gcc/rust/util/expected.h | 4 | ||||
-rw-r--r-- | gcc/rust/util/optional.h | 86 | ||||
-rw-r--r-- | gcc/rust/util/rust-attribute-values.h | 32 | ||||
-rw-r--r-- | gcc/rust/util/rust-attributes.cc | 36 | ||||
-rw-r--r-- | gcc/rust/util/rust-attributes.h | 13 | ||||
-rw-r--r-- | gcc/rust/util/rust-canonical-path.h | 12 | ||||
-rw-r--r-- | gcc/rust/util/rust-common.h | 1 | ||||
-rw-r--r-- | gcc/rust/util/rust-edition.cc | 40 | ||||
-rw-r--r-- | gcc/rust/util/rust-edition.h (renamed from gcc/rust/util/rust-make-unique.h) | 26 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.cc | 385 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 140 | ||||
-rw-r--r-- | gcc/rust/util/rust-lang-item.cc | 84 | ||||
-rw-r--r-- | gcc/rust/util/rust-lang-item.h | 45 | ||||
-rw-r--r-- | gcc/rust/util/rust-operators.h | 8 | ||||
-rw-r--r-- | gcc/rust/util/rust-stacked-contexts.h | 14 | ||||
-rw-r--r-- | gcc/rust/util/rust-token-converter.cc | 3 | ||||
-rw-r--r-- | gcc/rust/util/rust-token-converter.h | 2 | ||||
-rw-r--r-- | gcc/rust/util/rust-unwrap-segment.cc | 61 | ||||
-rw-r--r-- | gcc/rust/util/rust-unwrap-segment.h | 121 |
19 files changed, 855 insertions, 258 deletions
diff --git a/gcc/rust/util/expected.h b/gcc/rust/util/expected.h index a7ddd55..6f5ef1c 100644 --- a/gcc/rust/util/expected.h +++ b/gcc/rust/util/expected.h @@ -212,10 +212,8 @@ template <typename E> throw std::forward<E>(e); #else (void)e; -#ifdef _MSC_VER gcc_unreachable(); #endif -#endif } #ifndef TL_TRAITS_MUTEX @@ -2437,4 +2435,4 @@ void swap(expected<T, E> &lhs, } } // namespace tl -#endif
\ No newline at end of file +#endif diff --git a/gcc/rust/util/optional.h b/gcc/rust/util/optional.h index 4518b42..a8ef545 100644 --- a/gcc/rust/util/optional.h +++ b/gcc/rust/util/optional.h @@ -1249,19 +1249,56 @@ public: /// Returns a pointer to the stored value constexpr const T *operator->() const { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + return std::addressof(this->m_value); } TL_OPTIONAL_11_CONSTEXPR T *operator->() { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + return std::addressof(this->m_value); } /// Returns the stored value - TL_OPTIONAL_11_CONSTEXPR T &operator*() & { return this->m_value; } + TL_OPTIONAL_11_CONSTEXPR T &operator*() & + { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif - constexpr const T &operator*() const & { return this->m_value; } + return this->m_value; + } + + constexpr const T &operator*() const & + { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + + return this->m_value; + } + + TL_OPTIONAL_11_CONSTEXPR T &&operator*() && + { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif - TL_OPTIONAL_11_CONSTEXPR T &&operator*() && { return std::move(this->m_value); } @@ -1988,14 +2025,49 @@ public: void swap(optional &rhs) noexcept { std::swap(m_value, rhs.m_value); } /// Returns a pointer to the stored value - constexpr const T *operator->() const noexcept { return m_value; } + constexpr const T *operator->() const noexcept + { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + + return m_value; + } - TL_OPTIONAL_11_CONSTEXPR T *operator->() noexcept { return m_value; } + TL_OPTIONAL_11_CONSTEXPR T *operator->() noexcept + { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + + return m_value; + } /// Returns the stored value - TL_OPTIONAL_11_CONSTEXPR T &operator*() noexcept { return *m_value; } + TL_OPTIONAL_11_CONSTEXPR T &operator*() noexcept { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + + return *m_value; + } - constexpr const T &operator*() const noexcept { return *m_value; } + constexpr const T &operator*() const noexcept + { + // constexpr function must only contain a return statement in C++11 +#ifdef TL_OPTIONAL_CXX14 + // undefined behavior if we don't have a value + rust_assert(has_value ()); +#endif + + return *m_value; + } constexpr bool has_value() const noexcept { return m_value != nullptr; } diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h index a8551c0..6e0aa48 100644 --- a/gcc/rust/util/rust-attribute-values.h +++ b/gcc/rust/util/rust-attribute-values.h @@ -29,6 +29,7 @@ public: static constexpr auto &COLD = "cold"; static constexpr auto &CFG = "cfg"; static constexpr auto &CFG_ATTR = "cfg_attr"; + static constexpr auto &DERIVE_ATTR = "derive"; static constexpr auto &DEPRECATED = "deprecated"; static constexpr auto &ALLOW = "allow"; static constexpr auto &ALLOW_INTERNAL_UNSTABLE = "allow_internal_unstable"; @@ -39,12 +40,14 @@ public: static constexpr auto &NO_MANGLE = "no_mangle"; static constexpr auto &REPR = "repr"; static constexpr auto &RUSTC_BUILTIN_MACRO = "rustc_builtin_macro"; + static constexpr auto &RUSTC_MACRO_TRANSPARENCY = "rustc_macro_transparency"; static constexpr auto &PATH = "path"; static constexpr auto &MACRO_USE = "macro_use"; static constexpr auto &MACRO_EXPORT = "macro_export"; static constexpr auto &PROC_MACRO = "proc_macro"; static constexpr auto &PROC_MACRO_DERIVE = "proc_macro_derive"; static constexpr auto &PROC_MACRO_ATTRIBUTE = "proc_macro_attribute"; + static constexpr auto &TARGET_FEATURE = "target_feature"; // From now on, these are reserved by the compiler and gated through // #![feature(rustc_attrs)] @@ -53,6 +56,35 @@ public: = "rustc_inherit_overflow_checks"; static constexpr auto &STABLE = "stable"; static constexpr auto &UNSTABLE = "unstable"; + + static constexpr auto &RUSTC_PROMOTABLE = "rustc_promotable"; + static constexpr auto &RUSTC_CONST_STABLE = "rustc_const_stable"; + static constexpr auto &RUSTC_CONST_UNSTABLE = "rustc_const_unstable"; + + static constexpr auto &RUSTC_SPECIALIZATION_TRAIT + = "rustc_specialization_trait"; + static constexpr auto &RUSTC_UNSAFE_SPECIALIZATION_MARKER + = "rustc_unsafe_specialization_marker"; + static constexpr auto &RUSTC_RESERVATION_IMPL = "rustc_reservation_impl"; + static constexpr auto &RUSTC_PAREN_SUGAR = "rustc_paren_sugar"; + static constexpr auto &RUSTC_NONNULL_OPTIMIZATION_GUARANTEED + = "rustc_nonnull_optimization_guaranteed"; + + static constexpr auto &RUSTC_LAYOUT_SCALAR_VALID_RANGE_START + = "rustc_layout_scalar_valid_range_start"; + + static constexpr auto &MAY_DANGLE = "may_dangle"; + static constexpr auto &PRELUDE_IMPORT = "prelude_import"; + static constexpr auto &TRACK_CALLER = "track_caller"; + + static constexpr auto &RUSTC_DIAGNOSTIC_ITEM = "rustc_diagnostic_item"; + static constexpr auto &RUSTC_ON_UNIMPLEMENTED = "rustc_on_unimplemented"; + + static constexpr auto &FUNDAMENTAL = "fundamental"; + + static constexpr auto &NON_EXHAUSTIVE = "non_exhaustive"; + + static constexpr auto &RUSTFMT = "rustfmt"; }; } // namespace Values } // namespace Rust diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc index 84d1781..2c1bd19 100644 --- a/gcc/rust/util/rust-attributes.cc +++ b/gcc/rust/util/rust-attributes.cc @@ -29,6 +29,15 @@ namespace Rust { namespace Analysis { +bool +Attributes::is_known (const std::string &attribute_path) +{ + const auto &lookup + = BuiltinAttributeMappings::get ()->lookup_builtin (attribute_path); + + return !lookup.is_error (); +} + using Attrs = Values::Attributes; // https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248 @@ -37,6 +46,7 @@ static const BuiltinAttrDefinition __definitions[] {Attrs::COLD, CODE_GENERATION}, {Attrs::CFG, EXPANSION}, {Attrs::CFG_ATTR, EXPANSION}, + {Attrs::DERIVE_ATTR, EXPANSION}, {Attrs::DEPRECATED, STATIC_ANALYSIS}, {Attrs::ALLOW, STATIC_ANALYSIS}, {Attrs::ALLOW_INTERNAL_UNSTABLE, STATIC_ANALYSIS}, @@ -47,6 +57,7 @@ static const BuiltinAttrDefinition __definitions[] {Attrs::NO_MANGLE, CODE_GENERATION}, {Attrs::REPR, CODE_GENERATION}, {Attrs::RUSTC_BUILTIN_MACRO, EXPANSION}, + {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION}, {Attrs::PATH, EXPANSION}, {Attrs::MACRO_USE, NAME_RESOLUTION}, {Attrs::MACRO_EXPORT, NAME_RESOLUTION}, @@ -61,7 +72,30 @@ static const BuiltinAttrDefinition __definitions[] {Attrs::RUSTC_DEPRECATED, STATIC_ANALYSIS}, {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION}, {Attrs::STABLE, STATIC_ANALYSIS}, - {Attrs::UNSTABLE, STATIC_ANALYSIS}}; + {Attrs::UNSTABLE, STATIC_ANALYSIS}, + + // assuming we keep these for static analysis + {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION}, + {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS}, + {Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS}, + {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}, + {Attrs::TRACK_CALLER, CODE_GENERATION}, + {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK}, + {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK}, + {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK}, + {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK}, + {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK}, + + {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION}, + + {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION}, + + {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS}, + {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS}, + + {Attrs::FUNDAMENTAL, TYPE_CHECK}, + {Attrs::NON_EXHAUSTIVE, TYPE_CHECK}, + {Attrs::RUSTFMT, EXTERNAL}}; BuiltinAttributeMappings * BuiltinAttributeMappings::get () diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h index f557b2d..16e4847 100644 --- a/gcc/rust/util/rust-attributes.h +++ b/gcc/rust/util/rust-attributes.h @@ -25,6 +25,12 @@ namespace Rust { namespace Analysis { +class Attributes +{ +public: + static bool is_known (const std::string &attribute_path); +}; + enum CompilerPass { UNKNOWN, @@ -34,7 +40,12 @@ enum CompilerPass HIR_LOWERING, TYPE_CHECK, STATIC_ANALYSIS, - CODE_GENERATION + CODE_GENERATION, + + // External Rust tooling attributes, like #[rustfmt::skip] + EXTERNAL, + + // Do we need to add something here for const fns? }; struct BuiltinAttrDefinition diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h index 969ac7f..33fead9 100644 --- a/gcc/rust/util/rust-canonical-path.h +++ b/gcc/rust/util/rust-canonical-path.h @@ -46,7 +46,9 @@ namespace Resolver { class CanonicalPath { public: - CanonicalPath (const CanonicalPath &other) : segs (other.segs) {} + CanonicalPath (const CanonicalPath &other) + : segs (other.segs), crate_num (other.crate_num) + {} CanonicalPath &operator= (const CanonicalPath &other) { @@ -66,14 +68,18 @@ public: trait_impl_projection_seg (NodeId id, const CanonicalPath &trait_seg, const CanonicalPath &impl_type_seg) { - return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + " as " + // https://doc.rust-lang.org/reference/paths.html#canonical-paths + // should be "<X>"? + return CanonicalPath::new_seg (id, "<impl " + impl_type_seg.get () + " as " + trait_seg.get () + ">"); } static CanonicalPath inherent_impl_seg (NodeId id, const CanonicalPath &impl_type_seg) { - return CanonicalPath::new_seg (id, "<" + impl_type_seg.get () + ">"); + // https://doc.rust-lang.org/reference/paths.html#canonical-paths + // should be "<X as Y>"? + return CanonicalPath::new_seg (id, "<impl " + impl_type_seg.get () + ">"); } std::string get () const diff --git a/gcc/rust/util/rust-common.h b/gcc/rust/util/rust-common.h index 299ae71..c4222d2 100644 --- a/gcc/rust/util/rust-common.h +++ b/gcc/rust/util/rust-common.h @@ -21,7 +21,6 @@ #ifndef RUST_COMMON #define RUST_COMMON #include "rust-system.h" -#include <string> namespace Rust { diff --git a/gcc/rust/util/rust-edition.cc b/gcc/rust/util/rust-edition.cc new file mode 100644 index 0000000..4e44a91 --- /dev/null +++ b/gcc/rust/util/rust-edition.cc @@ -0,0 +1,40 @@ +// Copyright (C) 2025 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include "rust-edition.h" +#include "rust-session-manager.h" + +namespace Rust { + +Edition +get_rust_edition () +{ + switch (Session::get_instance ().options.get_edition ()) + { + case CompileOptions::Edition::E2015: + return Edition::E2015; + case CompileOptions::Edition::E2018: + return Edition::E2018; + case CompileOptions::Edition::E2021: + return Edition::E2021; + default: + rust_unreachable (); + } +} + +} // namespace Rust diff --git a/gcc/rust/util/rust-make-unique.h b/gcc/rust/util/rust-edition.h index 09c1d4b..d034ea0 100644 --- a/gcc/rust/util/rust-make-unique.h +++ b/gcc/rust/util/rust-edition.h @@ -1,4 +1,4 @@ -// Copyright (C) 2020-2024 Free Software Foundation, Inc. +// Copyright (C) 2025 Free Software Foundation, Inc. // This file is part of GCC. @@ -16,20 +16,26 @@ // along with GCC; see the file COPYING3. If not see // <http://www.gnu.org/licenses/>. -#ifndef RUST_MAKE_UNIQUE_H -#define RUST_MAKE_UNIQUE_H +#ifndef RUST_EDITION_H +#define RUST_EDITION_H -#include "rust-system.h" +/* + * This header exists to avoid including rust-session-manager.h + * when we only need information on the selected rust edition + */ namespace Rust { -template <typename T, typename... Ts> -std::unique_ptr<T> -make_unique (Ts &&... params) +enum class Edition { - return std::unique_ptr<T> (new T (std::forward<Ts> (params)...)); -} + E2015, + E2018, + E2021 +}; + +Edition +get_rust_edition (); } // namespace Rust -#endif // RUST_MAKE_UNIQUE_H +#endif // !RUST_EDITION_H diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 05b26d6..0917828 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -110,14 +110,11 @@ Mappings::Mappings () Mappings::~Mappings () { delete builtinMarker; } -Mappings * +Mappings & Mappings::get () { - static std::unique_ptr<Mappings> instance; - if (!instance) - instance = std::unique_ptr<Mappings> (new Mappings ()); - - return instance.get (); + static Mappings instance{}; + return instance; } CrateNum @@ -141,15 +138,24 @@ Mappings::get_current_crate () const return currentCrateNum; } -bool -Mappings::get_crate_name (CrateNum crate_num, std::string &name) const +tl::optional<const std::string &> +Mappings::get_crate_name (CrateNum crate_num) const { auto it = crate_names.find (crate_num); if (it == crate_names.end ()) - return false; + return tl::nullopt; + + return it->second; +} + +tl::optional<CrateNum> +Mappings::lookup_crate_num (NodeId node_id) const +{ + auto it = crate_node_to_crate_num.find (node_id); + if (it == crate_node_to_crate_num.end ()) + return tl::nullopt; - name.assign (it->second); - return true; + return it->second; } void @@ -158,51 +164,37 @@ Mappings::set_crate_name (CrateNum crate_num, const std::string &name) crate_names[crate_num] = name; } -std::string +const std::string & Mappings::get_current_crate_name () const { - std::string name; - bool ok = get_crate_name (get_current_crate (), name); - rust_assert (ok); - return name; + return get_crate_name (get_current_crate ()).value (); } -bool -Mappings::lookup_crate_name (const std::string &crate_name, - CrateNum &resolved_crate_num) const +tl::optional<CrateNum> +Mappings::lookup_crate_name (const std::string &crate_name) const { for (const auto &it : crate_names) { if (it.second.compare (crate_name) == 0) - { - resolved_crate_num = it.first; - return true; - } + return it.first; } - return false; + return tl::nullopt; } -bool -Mappings::crate_num_to_nodeid (const CrateNum &crate_num, NodeId &node_id) const +tl::optional<NodeId> +Mappings::crate_num_to_nodeid (const CrateNum &crate_num) const { auto it = ast_crate_mappings.find (crate_num); if (it == ast_crate_mappings.end ()) - return false; + return tl::nullopt; - node_id = it->second->get_node_id (); - return true; + return it->second->get_node_id (); } bool Mappings::node_is_crate (NodeId node_id) const { - for (const auto &it : ast_crate_mappings) - { - NodeId crate_node_id = it.second->get_node_id (); - if (crate_node_id == node_id) - return true; - } - return false; + return lookup_crate_num (node_id).has_value (); } NodeId @@ -274,6 +266,7 @@ Mappings::insert_ast_crate (std::unique_ptr<AST::Crate> &&crate, rust_assert (it == ast_crate_mappings.end ()); // store it + crate_node_to_crate_num.insert ({crate->get_node_id (), crate_num}); ast_crate_mappings.insert ({crate_num, crate.release ()}); // return the reference to it @@ -324,20 +317,20 @@ Mappings::insert_defid_mapping (DefId id, HIR::Item *item) CrateNum crate_num = id.crateNum; LocalDefId local_def_id = id.localDefId; - rust_assert (lookup_defid (id) == nullptr); - rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr); - rust_assert (lookup_trait_item_defid (id) == nullptr); + rust_assert (!lookup_defid (id)); + rust_assert (!lookup_local_defid (crate_num, local_def_id)); + rust_assert (!lookup_trait_item_defid (id)); defIdMappings[id] = item; insert_local_defid_mapping (crate_num, local_def_id, item); } -HIR::Item * +tl::optional<HIR::Item *> Mappings::lookup_defid (DefId id) { auto it = defIdMappings.find (id); if (it == defIdMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -348,19 +341,19 @@ Mappings::insert_defid_mapping (DefId id, HIR::TraitItem *item) CrateNum crate_num = id.crateNum; LocalDefId local_def_id = id.localDefId; - rust_assert (lookup_defid (id) == nullptr); - rust_assert (lookup_local_defid (crate_num, local_def_id) == nullptr); - rust_assert (lookup_trait_item_defid (id) == nullptr); + rust_assert (!lookup_defid (id)); + rust_assert (!lookup_local_defid (crate_num, local_def_id)); + rust_assert (!lookup_trait_item_defid (id)); defIdTraitItemMappings[id] = item; } -HIR::TraitItem * +tl::optional<HIR::TraitItem *> Mappings::lookup_trait_item_defid (DefId id) { auto it = defIdTraitItemMappings.find (id); if (it == defIdTraitItemMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -369,19 +362,18 @@ void Mappings::insert_hir_item (HIR::Item *item) { auto id = item->get_mappings ().get_hirid (); - rust_assert (lookup_hir_item (id) == nullptr); + rust_assert (!lookup_hir_item (id).has_value ()); hirItemMappings[id] = item; insert_node_to_hir (item->get_mappings ().get_nodeid (), id); } -HIR::Item * +tl::optional<HIR::Item *> Mappings::lookup_hir_item (HirId id) { auto it = hirItemMappings.find (id); if (it == hirItemMappings.end ()) - return nullptr; - + return tl::nullopt; return it->second; } @@ -410,18 +402,18 @@ void Mappings::insert_hir_trait_item (HIR::TraitItem *item) { auto id = item->get_mappings ().get_hirid (); - rust_assert (lookup_hir_trait_item (id) == nullptr); + rust_assert (!lookup_hir_trait_item (id).has_value ()); hirTraitItemMappings[id] = item; insert_node_to_hir (item->get_mappings ().get_nodeid (), id); } -HIR::TraitItem * +tl::optional<HIR::TraitItem *> Mappings::lookup_hir_trait_item (HirId id) { auto it = hirTraitItemMappings.find (id); if (it == hirTraitItemMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -430,18 +422,18 @@ void Mappings::insert_hir_extern_block (HIR::ExternBlock *block) { auto id = block->get_mappings ().get_hirid (); - rust_assert (lookup_hir_extern_block (id) == nullptr); + rust_assert (!lookup_hir_extern_block (id).has_value ()); hirExternBlockMappings[id] = block; insert_node_to_hir (block->get_mappings ().get_nodeid (), id); } -HIR::ExternBlock * +tl::optional<HIR::ExternBlock *> Mappings::lookup_hir_extern_block (HirId id) { auto it = hirExternBlockMappings.find (id); if (it == hirExternBlockMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -450,73 +442,70 @@ void Mappings::insert_hir_extern_item (HIR::ExternalItem *item, HirId parent_block) { auto id = item->get_mappings ().get_hirid (); - rust_assert (lookup_hir_extern_item (id, nullptr) == nullptr); + rust_assert (!lookup_hir_extern_item (id)); hirExternItemMappings[id] = {item, parent_block}; insert_node_to_hir (item->get_mappings ().get_nodeid (), id); } -HIR::ExternalItem * -Mappings::lookup_hir_extern_item (HirId id, HirId *parent_block) +tl::optional<std::pair<HIR::ExternalItem *, HirId>> +Mappings::lookup_hir_extern_item (HirId id) { auto it = hirExternItemMappings.find (id); if (it == hirExternItemMappings.end ()) - return nullptr; - - *parent_block = it->second.second; + return tl::nullopt; - return it->second.first; + return it->second; } void Mappings::insert_hir_impl_block (HIR::ImplBlock *item) { auto id = item->get_mappings ().get_hirid (); - rust_assert (lookup_hir_impl_block (id) == nullptr); + rust_assert (!lookup_hir_impl_block (id)); - HirId impl_type_id = item->get_type ()->get_mappings ().get_hirid (); + HirId impl_type_id = item->get_type ().get_mappings ().get_hirid (); hirImplBlockMappings[id] = item; hirImplBlockTypeMappings[impl_type_id] = item; insert_node_to_hir (item->get_mappings ().get_nodeid (), id); } -HIR::ImplBlock * +tl::optional<HIR::ImplBlock *> Mappings::lookup_hir_impl_block (HirId id) { auto it = hirImplBlockMappings.find (id); if (it == hirImplBlockMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } -bool -Mappings::lookup_impl_block_type (HirId id, HIR::ImplBlock **impl_block) +tl::optional<HIR::ImplBlock *> +Mappings::lookup_impl_block_type (HirId id) { auto it = hirImplBlockTypeMappings.find (id); if (it == hirImplBlockTypeMappings.end ()) - return false; + return tl::nullopt; - *impl_block = it->second; - return true; + return it->second; } void Mappings::insert_module (HIR::Module *module) { auto id = module->get_mappings ().get_hirid (); - rust_assert (lookup_module (id) == nullptr); + rust_assert (!lookup_module (id)); hirModuleMappings[id] = module; insert_node_to_hir (module->get_mappings ().get_nodeid (), id); } -HIR::Module * +tl::optional<HIR::Module *> Mappings::lookup_module (HirId id) { auto it = hirModuleMappings.find (id); if (it == hirModuleMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -525,25 +514,21 @@ void Mappings::insert_hir_implitem (HirId parent_impl_id, HIR::ImplItem *item) { auto id = item->get_impl_mappings ().get_hirid (); - rust_assert (lookup_hir_implitem (id, nullptr) == nullptr); + rust_assert (!lookup_hir_implitem (id)); hirImplItemMappings[id] = std::pair<HirId, HIR::ImplItem *> (parent_impl_id, item); insert_node_to_hir (item->get_impl_mappings ().get_nodeid (), id); } -HIR::ImplItem * -Mappings::lookup_hir_implitem (HirId id, HirId *parent_impl_id) +tl::optional<std::pair<HIR::ImplItem *, HirId>> +Mappings::lookup_hir_implitem (HirId id) { auto it = hirImplItemMappings.find (id); if (it == hirImplItemMappings.end ()) - return nullptr; - - std::pair<HirId, HIR::ImplItem *> &ref = it->second; - if (parent_impl_id != nullptr) - *parent_impl_id = ref.first; + return tl::nullopt; - return ref.second; + return std::make_pair (it->second.second, it->second.first); } void @@ -556,12 +541,12 @@ Mappings::insert_hir_expr (HIR::Expr *expr) insert_location (id, expr->get_locus ()); } -HIR::Expr * +tl::optional<HIR::Expr *> Mappings::lookup_hir_expr (HirId id) { auto it = hirExprMappings.find (id); if (it == hirExprMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -570,19 +555,19 @@ void Mappings::insert_hir_path_expr_seg (HIR::PathExprSegment *expr) { auto id = expr->get_mappings ().get_hirid (); - rust_assert (lookup_hir_path_expr_seg (id) == nullptr); + rust_assert (!lookup_hir_path_expr_seg (id)); hirPathSegMappings[id] = expr; insert_node_to_hir (expr->get_mappings ().get_nodeid (), id); insert_location (id, expr->get_locus ()); } -HIR::PathExprSegment * +tl::optional<HIR::PathExprSegment *> Mappings::lookup_hir_path_expr_seg (HirId id) { auto it = hirPathSegMappings.find (id); if (it == hirPathSegMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -591,19 +576,19 @@ void Mappings::insert_hir_generic_param (HIR::GenericParam *param) { auto id = param->get_mappings ().get_hirid (); - rust_assert (lookup_hir_generic_param (id) == nullptr); + rust_assert (!lookup_hir_generic_param (id)); hirGenericParamMappings[id] = param; insert_node_to_hir (param->get_mappings ().get_nodeid (), id); insert_location (id, param->get_locus ()); } -HIR::GenericParam * +tl::optional<HIR::GenericParam *> Mappings::lookup_hir_generic_param (HirId id) { auto it = hirGenericParamMappings.find (id); if (it == hirGenericParamMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -612,18 +597,18 @@ void Mappings::insert_hir_type (HIR::Type *type) { auto id = type->get_mappings ().get_hirid (); - rust_assert (lookup_hir_type (id) == nullptr); + rust_assert (!lookup_hir_type (id)); hirTypeMappings[id] = type; insert_node_to_hir (type->get_mappings ().get_nodeid (), id); } -HIR::Type * +tl::optional<HIR::Type *> Mappings::lookup_hir_type (HirId id) { auto it = hirTypeMappings.find (id); if (it == hirTypeMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -632,18 +617,18 @@ void Mappings::insert_hir_stmt (HIR::Stmt *stmt) { auto id = stmt->get_mappings ().get_hirid (); - rust_assert (lookup_hir_stmt (id) == nullptr); + rust_assert (!lookup_hir_stmt (id)); hirStmtMappings[id] = stmt; insert_node_to_hir (stmt->get_mappings ().get_nodeid (), id); } -HIR::Stmt * +tl::optional<HIR::Stmt *> Mappings::lookup_hir_stmt (HirId id) { auto it = hirStmtMappings.find (id); if (it == hirStmtMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -652,18 +637,18 @@ void Mappings::insert_hir_param (HIR::FunctionParam *param) { auto id = param->get_mappings ().get_hirid (); - rust_assert (lookup_hir_param (id) == nullptr); + rust_assert (!lookup_hir_param (id)); hirParamMappings[id] = param; insert_node_to_hir (param->get_mappings ().get_nodeid (), id); } -HIR::FunctionParam * +tl::optional<HIR::FunctionParam *> Mappings::lookup_hir_param (HirId id) { auto it = hirParamMappings.find (id); if (it == hirParamMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -672,18 +657,18 @@ void Mappings::insert_hir_self_param (HIR::SelfParam *param) { auto id = param->get_mappings ().get_hirid (); - rust_assert (lookup_hir_self_param (id) == nullptr); + rust_assert (!lookup_hir_self_param (id)); hirSelfParamMappings[id] = param; insert_node_to_hir (param->get_mappings ().get_nodeid (), id); } -HIR::SelfParam * +tl::optional<HIR::SelfParam *> Mappings::lookup_hir_self_param (HirId id) { auto it = hirSelfParamMappings.find (id); if (it == hirSelfParamMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -692,18 +677,18 @@ void Mappings::insert_hir_struct_field (HIR::StructExprField *field) { auto id = field->get_mappings ().get_hirid (); - rust_assert (lookup_hir_struct_field (id) == nullptr); + rust_assert (!lookup_hir_struct_field (id)); hirStructFieldMappings[id] = field; insert_node_to_hir (field->get_mappings ().get_nodeid (), id); } -HIR::StructExprField * +tl::optional<HIR::StructExprField *> Mappings::lookup_hir_struct_field (HirId id) { auto it = hirStructFieldMappings.find (id); if (it == hirStructFieldMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -712,18 +697,18 @@ void Mappings::insert_hir_pattern (HIR::Pattern *pattern) { auto id = pattern->get_mappings ().get_hirid (); - rust_assert (lookup_hir_pattern (id) == nullptr); + rust_assert (!lookup_hir_pattern (id)); hirPatternMappings[id] = pattern; insert_node_to_hir (pattern->get_mappings ().get_nodeid (), id); } -HIR::Pattern * +tl::optional<HIR::Pattern *> Mappings::lookup_hir_pattern (HirId id) { auto it = hirPatternMappings.find (id); if (it == hirPatternMappings.end ()) - return nullptr; + return tl::nullopt; return it->second; } @@ -732,20 +717,20 @@ void Mappings::insert_local_defid_mapping (CrateNum crateNum, LocalDefId id, HIR::Item *item) { - rust_assert (lookup_local_defid (crateNum, id) == nullptr); + rust_assert (!lookup_local_defid (crateNum, id)); localDefIdMappings[crateNum][id] = item; } -HIR::Item * +tl::optional<HIR::Item *> Mappings::lookup_local_defid (CrateNum crateNum, LocalDefId id) { auto it = localDefIdMappings.find (crateNum); if (it == localDefIdMappings.end ()) - return nullptr; + return tl::nullopt; auto iy = it->second.find (id); if (iy == it->second.end ()) - return nullptr; + return tl::nullopt; return iy->second; } @@ -772,26 +757,24 @@ Mappings::insert_node_to_hir (NodeId id, HirId ref) hirIdToNodeMappings[ref] = id; } -bool -Mappings::lookup_node_to_hir (NodeId id, HirId *ref) +tl::optional<HirId> +Mappings::lookup_node_to_hir (NodeId id) { auto it = nodeIdToHirMappings.find (id); if (it == nodeIdToHirMappings.end ()) - return false; + return tl::nullopt; - *ref = it->second; - return true; + return {it->second}; } -bool -Mappings::lookup_hir_to_node (HirId id, NodeId *ref) +tl::optional<NodeId> +Mappings::lookup_hir_to_node (HirId id) { auto it = hirIdToNodeMappings.find (id); if (it == hirIdToNodeMappings.end ()) - return false; + return tl::nullopt; - *ref = it->second; - return true; + return {it->second}; } void @@ -810,17 +793,15 @@ Mappings::lookup_location (HirId id) return it->second; } -bool -Mappings::resolve_nodeid_to_stmt (NodeId id, HIR::Stmt **stmt) +tl::optional<HIR::Stmt *> +Mappings::resolve_nodeid_to_stmt (NodeId id) { auto it = nodeIdToHirMappings.find (id); if (it == nodeIdToHirMappings.end ()) - return false; + return tl::nullopt; HirId resolved = it->second; - auto resolved_stmt = lookup_hir_stmt (resolved); - *stmt = resolved_stmt; - return resolved_stmt != nullptr; + return lookup_hir_stmt (resolved); } void @@ -898,18 +879,27 @@ Mappings::insert_macro_def (AST::MacroRulesDefinition *macro) auto it = macroMappings.find (macro->get_node_id ()); rust_assert (it == macroMappings.end ()); - macroMappings[macro->get_node_id ()] = macro; + macroMappings[macro->get_node_id ()] = {macro, currentCrateNum}; } -bool -Mappings::lookup_macro_def (NodeId id, AST::MacroRulesDefinition **def) +tl::optional<AST::MacroRulesDefinition *> +Mappings::lookup_macro_def (NodeId id) { auto it = macroMappings.find (id); if (it == macroMappings.end ()) - return false; + return tl::nullopt; + + return it->second.first; +} + +tl::optional<CrateNum> +Mappings::lookup_macro_def_crate (NodeId id) +{ + auto it = macroMappings.find (id); + if (it == macroMappings.end ()) + return tl::nullopt; - *def = it->second; - return true; + return it->second.second; } void @@ -922,16 +912,14 @@ Mappings::insert_macro_invocation (AST::MacroInvocation &invoc, macroInvocations[invoc.get_macro_node_id ()] = def; } -bool -Mappings::lookup_macro_invocation (AST::MacroInvocation &invoc, - AST::MacroRulesDefinition **def) +tl::optional<AST::MacroRulesDefinition *> +Mappings::lookup_macro_invocation (AST::MacroInvocation &invoc) { auto it = macroInvocations.find (invoc.get_macro_node_id ()); if (it == macroInvocations.end ()) - return false; + return tl::nullopt; - *def = it->second; - return true; + return it->second; } void @@ -1129,15 +1117,14 @@ Mappings::insert_visibility (NodeId id, Privacy::ModuleVisibility visibility) visibility_map.insert ({id, visibility}); } -bool -Mappings::lookup_visibility (NodeId id, Privacy::ModuleVisibility &def) +tl::optional<Privacy::ModuleVisibility &> +Mappings::lookup_visibility (NodeId id) { auto it = visibility_map.find (id); if (it == visibility_map.end ()) - return false; + return tl::nullopt; - def = it->second; - return true; + return it->second; } void @@ -1253,15 +1240,14 @@ Mappings::insert_ast_item (AST::Item *item) ast_item_mappings[item->get_node_id ()] = item; } -bool -Mappings::lookup_ast_item (NodeId id, AST::Item **result) +tl::optional<AST::Item *> +Mappings::lookup_ast_item (NodeId id) { auto it = ast_item_mappings.find (id); if (it == ast_item_mappings.end ()) - return false; + return tl::nullopt; - *result = it->second; - return true; + return it->second; } HIR::ImplBlock * @@ -1270,24 +1256,105 @@ Mappings::lookup_builtin_marker () return builtinMarker; } +// FIXME: Before merging: Should we remove the `locus` parameter here? since +// lang items are looked up mostly for code generation, it doesn't make sense to +// error out on the locus of the node trying to access an inexistant lang item DefId Mappings::get_lang_item (LangItem::Kind item_type, location_t locus) { - DefId item = UNKNOWN_DEFID; - bool ok = lookup_lang_item (item_type, &item); - if (!ok) - rust_fatal_error (locus, "failed to find lang item %s", - LangItem::ToString (item_type).c_str ()); + if (auto item = lookup_lang_item (item_type)) + return *item; - return item; + rust_fatal_error (locus, "failed to find lang item %s", + LangItem::ToString (item_type).c_str ()); } -HIR::TraitItem * +tl::optional<HIR::TraitItem *> Mappings::lookup_trait_item_lang_item (LangItem::Kind item, location_t locus) { DefId trait_item_id = get_lang_item (item, locus); return lookup_trait_item_defid (trait_item_id); } +void +Mappings::insert_lang_item (LangItem::Kind item_type, DefId id) +{ + auto it = lang_item_mappings.find (item_type); + rust_assert (it == lang_item_mappings.end ()); + + lang_item_mappings[item_type] = id; +} + +tl::optional<DefId &> +Mappings::lookup_lang_item (LangItem::Kind item_type) +{ + auto it = lang_item_mappings.find (item_type); + if (it == lang_item_mappings.end ()) + return tl::nullopt; + + return it->second; +} + +void +Mappings::insert_lang_item_node (LangItem::Kind item_type, NodeId node_id) +{ + auto it = lang_item_nodes.find (item_type); + rust_assert (it == lang_item_nodes.end ()); + + lang_item_nodes.insert ({item_type, node_id}); +} + +tl::optional<NodeId &> +Mappings::lookup_lang_item_node (LangItem::Kind item_type) +{ + auto it = lang_item_nodes.find (item_type); + if (it == lang_item_nodes.end ()) + return tl::nullopt; + + return it->second; +} + +NodeId +Mappings::get_lang_item_node (LangItem::Kind item_type) +{ + if (auto lookup = lookup_lang_item_node (item_type)) + return *lookup; + + rust_fatal_error (UNKNOWN_LOCATION, "undeclared lang item: %qs", + LangItem::PrettyString (item_type).c_str ()); +} + +void +Mappings::insert_auto_trait (HIR::Trait *trait) +{ + auto_traits.emplace_back (trait); +} + +std::vector<HIR::Trait *> & +Mappings::get_auto_traits () +{ + return auto_traits; +} + +void +Mappings::add_capture (NodeId closure, NodeId definition) +{ + auto cap = captures.find (closure); + if (cap == captures.end ()) + captures[closure] = {definition}; + else + cap->second.push_back (definition); +} + +tl::optional<std::vector<NodeId>> +Mappings::lookup_captures (NodeId closure) +{ + auto cap = captures.find (closure); + if (cap == captures.end ()) + return tl::nullopt; + else + return cap->second; +} + } // namespace Analysis } // namespace Rust diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index 92af067..86191f6 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -74,18 +74,20 @@ private: class Mappings { public: - static Mappings *get (); + static Mappings &get (); ~Mappings (); CrateNum get_next_crate_num (const std::string &name); void set_current_crate (CrateNum crateNum); CrateNum get_current_crate () const; - bool get_crate_name (CrateNum crate_num, std::string &name) const; + tl::optional<const std::string &> get_crate_name (CrateNum crate_num) const; + + tl::optional<CrateNum> lookup_crate_num (NodeId node_id) const; void set_crate_name (CrateNum crate_num, const std::string &name); - std::string get_current_crate_name () const; - bool lookup_crate_name (const std::string &crate_name, - CrateNum &resolved_crate_num) const; - bool crate_num_to_nodeid (const CrateNum &crate_num, NodeId &node_id) const; + const std::string &get_current_crate_name () const; + tl::optional<CrateNum> + lookup_crate_name (const std::string &crate_name) const; + tl::optional<NodeId> crate_num_to_nodeid (const CrateNum &crate_num) const; bool node_is_crate (NodeId node_id) const; NodeId get_next_node_id (); @@ -106,77 +108,83 @@ public: bool is_local_hirid_crate (HirId crateNum); void insert_defid_mapping (DefId id, HIR::Item *item); - HIR::Item *lookup_defid (DefId id); + tl::optional<HIR::Item *> lookup_defid (DefId id); void insert_defid_mapping (DefId id, HIR::TraitItem *item); - HIR::TraitItem *lookup_trait_item_defid (DefId id); + tl::optional<HIR::TraitItem *> lookup_trait_item_defid (DefId id); void insert_local_defid_mapping (CrateNum crateNum, LocalDefId id, HIR::Item *item); - HIR::Item *lookup_local_defid (CrateNum crateNum, LocalDefId id); + tl::optional<HIR::Item *> lookup_local_defid (CrateNum crateNum, + LocalDefId id); void insert_hir_item (HIR::Item *item); - HIR::Item *lookup_hir_item (HirId id); + tl::optional<HIR::Item *> lookup_hir_item (HirId id); void insert_hir_enumitem (HIR::Enum *parent, HIR::EnumItem *item); std::pair<HIR::Enum *, HIR::EnumItem *> lookup_hir_enumitem (HirId id); void insert_hir_trait_item (HIR::TraitItem *item); - HIR::TraitItem *lookup_hir_trait_item (HirId id); + tl::optional<HIR::TraitItem *> lookup_hir_trait_item (HirId id); void insert_hir_extern_block (HIR::ExternBlock *block); - HIR::ExternBlock *lookup_hir_extern_block (HirId id); + tl::optional<HIR::ExternBlock *> lookup_hir_extern_block (HirId id); void insert_hir_extern_item (HIR::ExternalItem *item, HirId parent_block); - HIR::ExternalItem *lookup_hir_extern_item (HirId id, HirId *parent_block); + + // std::pair<hir_extern_item, parent hirid> + tl::optional<std::pair<HIR::ExternalItem *, HirId>> + lookup_hir_extern_item (HirId id); void insert_hir_impl_block (HIR::ImplBlock *item); - HIR::ImplBlock *lookup_hir_impl_block (HirId id); - bool lookup_impl_block_type (HirId id, HIR::ImplBlock **impl_block); + tl::optional<HIR::ImplBlock *> lookup_hir_impl_block (HirId id); + tl::optional<HIR::ImplBlock *> lookup_impl_block_type (HirId id); void insert_module (HIR::Module *module); - HIR::Module *lookup_module (HirId id); + tl::optional<HIR::Module *> lookup_module (HirId id); void insert_hir_implitem (HirId parent_impl_id, HIR::ImplItem *item); - HIR::ImplItem *lookup_hir_implitem (HirId id, HirId *parent_impl_id); + // Optional<ImpItem, ParentImpl Hir id> + tl::optional<std::pair<HIR::ImplItem *, HirId>> + lookup_hir_implitem (HirId id); void insert_hir_expr (HIR::Expr *expr); - HIR::Expr *lookup_hir_expr (HirId id); + tl::optional<HIR::Expr *> lookup_hir_expr (HirId id); void insert_hir_path_expr_seg (HIR::PathExprSegment *expr); - HIR::PathExprSegment *lookup_hir_path_expr_seg (HirId id); + tl::optional<HIR::PathExprSegment *> lookup_hir_path_expr_seg (HirId id); void insert_hir_generic_param (HIR::GenericParam *expr); - HIR::GenericParam *lookup_hir_generic_param (HirId id); + tl::optional<HIR::GenericParam *> lookup_hir_generic_param (HirId id); void insert_hir_type (HIR::Type *type); - HIR::Type *lookup_hir_type (HirId id); + tl::optional<HIR::Type *> lookup_hir_type (HirId id); void insert_hir_stmt (HIR::Stmt *stmt); - HIR::Stmt *lookup_hir_stmt (HirId id); + tl::optional<HIR::Stmt *> lookup_hir_stmt (HirId id); void insert_hir_param (HIR::FunctionParam *type); - HIR::FunctionParam *lookup_hir_param (HirId id); + tl::optional<HIR::FunctionParam *> lookup_hir_param (HirId id); void insert_hir_self_param (HIR::SelfParam *type); - HIR::SelfParam *lookup_hir_self_param (HirId id); + tl::optional<HIR::SelfParam *> lookup_hir_self_param (HirId id); void insert_hir_struct_field (HIR::StructExprField *type); - HIR::StructExprField *lookup_hir_struct_field (HirId id); + tl::optional<HIR::StructExprField *> lookup_hir_struct_field (HirId id); void insert_hir_pattern (HIR::Pattern *pattern); - HIR::Pattern *lookup_hir_pattern (HirId id); + tl::optional<HIR::Pattern *> lookup_hir_pattern (HirId id); void walk_local_defids_for_crate (CrateNum crateNum, std::function<bool (HIR::Item *)> cb); void insert_node_to_hir (NodeId id, HirId ref); - bool lookup_node_to_hir (NodeId id, HirId *ref); - bool lookup_hir_to_node (HirId id, NodeId *ref); + tl::optional<HirId> lookup_node_to_hir (NodeId id); + tl::optional<NodeId> lookup_hir_to_node (HirId id); void insert_location (HirId id, location_t locus); location_t lookup_location (HirId id); - bool resolve_nodeid_to_stmt (NodeId id, HIR::Stmt **stmt); + tl::optional<HIR::Stmt *> resolve_nodeid_to_stmt (NodeId id); std::set<HirId> &get_hirids_within_crate (CrateNum crate) { @@ -205,11 +213,7 @@ public: void iterate_trait_items ( std::function<bool (HIR::TraitItem *item, HIR::Trait *)> cb); - bool is_impl_item (HirId id) - { - HirId parent_impl_block_id = UNKNOWN_HIRID; - return lookup_hir_implitem (id, &parent_impl_block_id) != nullptr; - } + bool is_impl_item (HirId id) { return lookup_hir_implitem (id).has_value (); } void insert_trait_item_mapping (HirId trait_item_id, HIR::Trait *trait) { @@ -227,8 +231,7 @@ public: void insert_canonical_path (NodeId id, const Resolver::CanonicalPath path) { - const Resolver::CanonicalPath *p = nullptr; - if (lookup_canonical_path (id, &p)) + if (auto p = lookup_canonical_path (id)) { // if we have already stored a canonical path this is ok so long as // this new path is equal or is smaller that the existing one but in @@ -245,45 +248,35 @@ public: paths.emplace (id, std::move (path)); } - bool lookup_canonical_path (NodeId id, const Resolver::CanonicalPath **path) + tl::optional<const Resolver::CanonicalPath &> + lookup_canonical_path (NodeId id) { auto it = paths.find (id); if (it == paths.end ()) - return false; + return tl::nullopt; - *path = &it->second; - return true; + return it->second; } - void insert_lang_item (LangItem::Kind item_type, DefId id) - { - auto it = lang_item_mappings.find (item_type); - rust_assert (it == lang_item_mappings.end ()); - - lang_item_mappings[item_type] = id; - } + void insert_lang_item (LangItem::Kind item_type, DefId id); + tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type); - bool lookup_lang_item (LangItem::Kind item_type, DefId *id) - { - auto it = lang_item_mappings.find (item_type); - if (it == lang_item_mappings.end ()) - return false; - - *id = it->second; - return true; - } + void insert_lang_item_node (LangItem::Kind item_type, NodeId node_id); + tl::optional<NodeId &> lookup_lang_item_node (LangItem::Kind item_type); + NodeId get_lang_item_node (LangItem::Kind item_type); // This will fatal_error when this lang item does not exist DefId get_lang_item (LangItem::Kind item_type, location_t locus); void insert_macro_def (AST::MacroRulesDefinition *macro); - bool lookup_macro_def (NodeId id, AST::MacroRulesDefinition **def); + tl::optional<AST::MacroRulesDefinition *> lookup_macro_def (NodeId id); + tl::optional<CrateNum> lookup_macro_def_crate (NodeId id); void insert_macro_invocation (AST::MacroInvocation &invoc, AST::MacroRulesDefinition *def); - bool lookup_macro_invocation (AST::MacroInvocation &invoc, - AST::MacroRulesDefinition **def); + tl::optional<AST::MacroRulesDefinition *> + lookup_macro_invocation (AST::MacroInvocation &invoc); void insert_exported_macro (AST::MacroRulesDefinition &def); std::vector<NodeId> &get_exported_macros (); @@ -326,7 +319,7 @@ public: AttributeProcMacro def); void insert_visibility (NodeId id, Privacy::ModuleVisibility visibility); - bool lookup_visibility (NodeId id, Privacy::ModuleVisibility &def); + tl::optional<Privacy::ModuleVisibility &> lookup_visibility (NodeId id); void insert_ast_module (AST::Module *); tl::optional<AST::Module *> lookup_ast_module (NodeId id); @@ -345,12 +338,17 @@ public: bool node_is_module (NodeId query); void insert_ast_item (AST::Item *item); - bool lookup_ast_item (NodeId id, AST::Item **result); + tl::optional<AST::Item *> lookup_ast_item (NodeId id); HIR::ImplBlock *lookup_builtin_marker (); - HIR::TraitItem *lookup_trait_item_lang_item (LangItem::Kind item, - location_t locus); + tl::optional<HIR::TraitItem *> + lookup_trait_item_lang_item (LangItem::Kind item, location_t locus); + + void insert_auto_trait (HIR::Trait *trait); + std::vector<HIR::Trait *> &get_auto_traits (); + void add_capture (NodeId closure, NodeId definition); + tl::optional<std::vector<NodeId>> lookup_captures (NodeId closure); private: Mappings (); @@ -389,8 +387,16 @@ private: std::map<HirId, HIR::GenericParam *> hirGenericParamMappings; std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings; std::map<HirId, HIR::Pattern *> hirPatternMappings; + + // FIXME: Add documentation + std::vector<HIR::Trait *> auto_traits; + + // We need to have two maps here, as lang-items need to be used for both AST + // passes and HIR passes. Thus those two maps are created at different times. std::map<LangItem::Kind, DefId> lang_item_mappings; - std::map<NodeId, const Resolver::CanonicalPath> paths; + std::map<LangItem::Kind, NodeId> lang_item_nodes; + + std::map<NodeId, Resolver::CanonicalPath> paths; std::map<NodeId, location_t> locations; std::map<NodeId, HirId> nodeIdToHirMappings; std::map<HirId, NodeId> hirIdToNodeMappings; @@ -399,7 +405,8 @@ private: std::map<CrateNum, std::set<HirId>> hirNodesWithinCrate; // MBE macros - std::map<NodeId, AST::MacroRulesDefinition *> macroMappings; + std::map<NodeId, std::pair<AST::MacroRulesDefinition *, CrateNum>> + macroMappings; std::map<NodeId, AST::MacroRulesDefinition *> macroInvocations; std::vector<NodeId> exportedMacros; @@ -433,6 +440,9 @@ private: // AST mappings std::map<NodeId, AST::Item *> ast_item_mappings; + + // Closure AST NodeId -> vector of Definition node ids + std::unordered_map<NodeId, std::vector<NodeId>> captures; }; } // namespace Analysis diff --git a/gcc/rust/util/rust-lang-item.cc b/gcc/rust/util/rust-lang-item.cc index 0d8a98077..0bd74b2 100644 --- a/gcc/rust/util/rust-lang-item.cc +++ b/gcc/rust/util/rust-lang-item.cc @@ -46,6 +46,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{ {"shr_assign", Kind::SHR_ASSIGN}, {"deref", Kind::DEREF}, {"deref_mut", Kind::DEREF_MUT}, + {"receiver", Kind::RECEIVER}, {"index", Kind::INDEX}, {"index_mut", Kind::INDEX_MUT}, {"RangeFull", Kind::RANGE_FULL}, @@ -62,6 +63,7 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{ {"copy", Kind::COPY}, {"clone", Kind::CLONE}, {"sized", Kind::SIZED}, + {"sync", Kind::SYNC}, {"slice_alloc", Kind::SLICE_ALLOC}, {"slice_u8_alloc", Kind::SLICE_U8_ALLOC}, {"str_alloc", Kind::STR_ALLOC}, @@ -91,6 +93,32 @@ const BiMap<std::string, LangItem::Kind> Rust::LangItem::lang_items = {{ {"str", Kind::STR}, {"f32_runtime", Kind::F32_RUNTIME}, {"f64_runtime", Kind::F64_RUNTIME}, + + {"Some", Kind::OPTION_SOME}, + {"None", Kind::OPTION_NONE}, + + {"Ok", Kind::RESULT_OK}, + {"Err", Kind::RESULT_ERR}, + + {"into_iter", Kind::INTOITER_INTOITER}, + {"next", Kind::ITERATOR_NEXT}, + + {"eq", Kind::EQ}, + {"partial_ord", Kind::PARTIAL_ORD}, + + {"try", Kind::TRY}, + {"into_result", Kind::TRY_INTO_RESULT}, + {"from_error", Kind::TRY_FROM_ERROR}, + {"from_ok", Kind::TRY_FROM_OK}, + + {"from", Kind::FROM_FROM}, + + {"structural_peq", Kind::STRUCTURAL_PEQ}, + {"structural_teq", Kind::STRUCTURAL_TEQ}, + + {"discriminant_kind", Kind::DISCRIMINANT_KIND}, + {"discriminant_type", Kind::DISCRIMINANT_TYPE}, + {"manually_drop", Kind::MANUALLY_DROP}, }}; tl::optional<LangItem::Kind> @@ -108,6 +136,12 @@ LangItem::ToString (LangItem::Kind type) return str.value (); } +std::string +LangItem::PrettyString (LangItem::Kind type) +{ + return "#[lang = \"" + LangItem::ToString (type) + "\"]"; +} + LangItem::Kind LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op) { @@ -139,6 +173,47 @@ LangItem::OperatorToLangItem (ArithmeticOrLogicalOperator op) } LangItem::Kind +LangItem::ComparisonToLangItem (ComparisonOperator op) +{ + switch (op) + { + case ComparisonOperator::NOT_EQUAL: + case ComparisonOperator::EQUAL: + return LangItem::Kind::EQ; + + case ComparisonOperator::GREATER_THAN: + case ComparisonOperator::LESS_THAN: + case ComparisonOperator::GREATER_OR_EQUAL: + case ComparisonOperator::LESS_OR_EQUAL: + return LangItem::Kind::PARTIAL_ORD; + } + + rust_unreachable (); +} + +std::string +LangItem::ComparisonToSegment (ComparisonOperator op) +{ + switch (op) + { + case ComparisonOperator::NOT_EQUAL: + return "ne"; + case ComparisonOperator::EQUAL: + return "eq"; + case ComparisonOperator::GREATER_THAN: + return "gt"; + case ComparisonOperator::LESS_THAN: + return "lt"; + case ComparisonOperator::GREATER_OR_EQUAL: + return "ge"; + case ComparisonOperator::LESS_OR_EQUAL: + return "le"; + } + + rust_unreachable (); +} + +LangItem::Kind LangItem::CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op) { switch (op) @@ -182,4 +257,13 @@ LangItem::NegationOperatorToLangItem (NegationOperator op) rust_unreachable (); } +bool +LangItem::IsEnumVariant (LangItem::Kind type) +{ + const static std::set<LangItem::Kind> enum_variants + = {Kind::OPTION_NONE, Kind::OPTION_SOME, Kind::RESULT_OK, Kind::RESULT_ERR}; + + return enum_variants.find (type) != enum_variants.end (); +} + } // namespace Rust diff --git a/gcc/rust/util/rust-lang-item.h b/gcc/rust/util/rust-lang-item.h index 414436f..c7dff93 100644 --- a/gcc/rust/util/rust-lang-item.h +++ b/gcc/rust/util/rust-lang-item.h @@ -23,12 +23,15 @@ namespace Rust { -// https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs class LangItem { public: + // FIXME: We should clean up that enum to make it more inline with the list of + // lang-items in Rust 1.49 + // https://github.com/rust-lang/rust/blob/1.49.0/compiler/rustc_hir/src/lang_items.rs enum class Kind { + // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/arith.rs ADD, SUBTRACT, MULTIPLY, @@ -42,6 +45,8 @@ public: NEGATION, NOT, + EQ, + PARTIAL_ORD, ADD_ASSIGN, SUB_ASSIGN, @@ -56,6 +61,7 @@ public: DEREF, DEREF_MUT, + RECEIVER, // https://github.com/rust-lang/rust/blob/master/library/core/src/ops/index.rs INDEX, @@ -82,6 +88,7 @@ public: COPY, CLONE, SIZED, + SYNC, // https://github.com/Rust-GCC/gccrs/issues/1896 // https://github.com/rust-lang/rust/commit/afbecc0f68c4dcfc4878ba5bcb1ac942544a1bdc @@ -116,16 +123,52 @@ public: STR, F32_RUNTIME, F64_RUNTIME, + + OPTION_SOME, + OPTION_NONE, + + RESULT_OK, + RESULT_ERR, + + INTOITER_INTOITER, + ITERATOR_NEXT, + + // NOTE: These lang items are *not* necessarily present in later versions of + // Rust (I am unsure at which point they have been removed as the `Try` + // trait is unstable). They will need to be changed when updating the + // targeted Rust version of gccrs + TRY, + TRY_INTO_RESULT, + TRY_FROM_ERROR, + TRY_FROM_OK, + + // NOTE: This is not a lang item in later versions of Rust + FROM_FROM, + + STRUCTURAL_PEQ, + STRUCTURAL_TEQ, + + DISCRIMINANT_TYPE, + DISCRIMINANT_KIND, + + MANUALLY_DROP, }; static const BiMap<std::string, Kind> lang_items; static tl::optional<Kind> Parse (const std::string &item); + static std::string ToString (Kind type); + static std::string PrettyString (Kind type); + static Kind OperatorToLangItem (ArithmeticOrLogicalOperator op); static Kind CompoundAssignmentOperatorToLangItem (ArithmeticOrLogicalOperator op); static Kind NegationOperatorToLangItem (NegationOperator op); + static Kind ComparisonToLangItem (ComparisonOperator op); + static std::string ComparisonToSegment (ComparisonOperator op); + + static bool IsEnumVariant (Kind type); }; } // namespace Rust diff --git a/gcc/rust/util/rust-operators.h b/gcc/rust/util/rust-operators.h index e3d6205..f460f4f 100644 --- a/gcc/rust/util/rust-operators.h +++ b/gcc/rust/util/rust-operators.h @@ -43,10 +43,10 @@ enum class ComparisonOperator { EQUAL, // std::cmp::PartialEq::eq NOT_EQUAL, // std::cmp::PartialEq::ne - GREATER_THAN, // std::cmp::PartialEq::gt - LESS_THAN, // std::cmp::PartialEq::lt - GREATER_OR_EQUAL, // std::cmp::PartialEq::ge - LESS_OR_EQUAL // std::cmp::PartialEq::le + GREATER_THAN, // std::cmp::PartialOrd::gt + LESS_THAN, // std::cmp::PartialOrd::lt + GREATER_OR_EQUAL, // std::cmp::PartialOrd::ge + LESS_OR_EQUAL // std::cmp::PartialOrd::le }; enum class LazyBooleanOperator diff --git a/gcc/rust/util/rust-stacked-contexts.h b/gcc/rust/util/rust-stacked-contexts.h index 86cdf9f..cabc65d 100644 --- a/gcc/rust/util/rust-stacked-contexts.h +++ b/gcc/rust/util/rust-stacked-contexts.h @@ -71,6 +71,20 @@ public: return last; } + const T &peek () const + { + rust_assert (!stack.empty ()); + + return stack.back (); + } + + T &peek () + { + rust_assert (!stack.empty ()); + + return stack.back (); + } + /** * Are we currently inside of a special context? */ diff --git a/gcc/rust/util/rust-token-converter.cc b/gcc/rust/util/rust-token-converter.cc index 220e891..fc34adb 100644 --- a/gcc/rust/util/rust-token-converter.cc +++ b/gcc/rust/util/rust-token-converter.cc @@ -18,8 +18,7 @@ #include "rust-token-converter.h" #include "bi-map.h" #include "line-map.h" - -#include <string> +#include "rust-system.h" namespace Rust { diff --git a/gcc/rust/util/rust-token-converter.h b/gcc/rust/util/rust-token-converter.h index 0498041..5405d6e 100644 --- a/gcc/rust/util/rust-token-converter.h +++ b/gcc/rust/util/rust-token-converter.h @@ -17,7 +17,7 @@ #ifndef RUST_TOKEN_CONVERTER_H #define RUST_TOKEN_CONVERTER_H -#include <vector> +#include "rust-system.h" #include "rust-token.h" #include "libproc_macro_internal/proc_macro.h" diff --git a/gcc/rust/util/rust-unwrap-segment.cc b/gcc/rust/util/rust-unwrap-segment.cc new file mode 100644 index 0000000..083a0e5 --- /dev/null +++ b/gcc/rust/util/rust-unwrap-segment.cc @@ -0,0 +1,61 @@ +// Copyright (C) 2025 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include "ast/rust-path.h" + +namespace Rust { + +NodeId +unwrap_segment_node_id (const AST::TypePathSegment &seg) +{ + return seg.get_node_id (); +} + +NodeId +unwrap_segment_node_id (const AST::SimplePathSegment &seg) +{ + return seg.get_node_id (); +} + +NodeId +unwrap_segment_node_id (const AST::PathExprSegment &seg) +{ + return seg.get_node_id (); +} + +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const AST::TypePathSegment &seg) +{ + if (seg.is_lang_item ()) + return seg.get_lang_item (); + return tl::nullopt; +} + +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg) +{ + return tl::nullopt; +} + +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const AST::PathExprSegment &seg) +{ + return tl::nullopt; +} + +} // namespace Rust diff --git a/gcc/rust/util/rust-unwrap-segment.h b/gcc/rust/util/rust-unwrap-segment.h new file mode 100644 index 0000000..bebdc3a --- /dev/null +++ b/gcc/rust/util/rust-unwrap-segment.h @@ -0,0 +1,121 @@ +// Copyright (C) 2025 Free Software Foundation, Inc. + +// This file is part of GCC. + +// GCC is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3, or (at your option) any later +// version. + +// GCC is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. + +// You should have received a copy of the GNU General Public License +// along with GCC; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <ast/rust-ast-full-decls.h> + +namespace Rust { + +/* + * Used to convert different path segment object references + * into SimplePathSegment/PathIdentSegment references + * + * unwrap_type_segment: + * expands to a call to unwrap_type_segment_inner::unwrap, + * used for type inference + */ +#define unwrap_type_segment(x) \ + (unwrap_type_segment_inner<typename std::remove_const< \ + typename std::remove_reference<decltype (x)>::type>::type>::unwrap (x)) + +template <class T> class unwrap_type_segment_inner; + +/* base case */ +template <> class unwrap_type_segment_inner<AST::SimplePathSegment> +{ +public: + /* The return type of unwrap */ + using ret = AST::SimplePathSegment; + + /* non-const qualified unwrap */ + static AST::SimplePathSegment &unwrap (AST::SimplePathSegment &x) + { + return x; + } + + /* const qualified unwrap */ + static const AST::SimplePathSegment &unwrap (const AST::SimplePathSegment &x) + { + return x; + } +}; + +/* case which dereferences unique_ptr */ +template <class T> class unwrap_type_segment_inner<std::unique_ptr<T>> +{ +public: + using ret = typename unwrap_type_segment_inner<T>::ret; + + static ret &unwrap (std::unique_ptr<T> &x) + { + return unwrap_type_segment (*x); + } + static const ret &unwrap (const std::unique_ptr<T> &x) + { + return unwrap_type_segment (*x); + } +}; + +/* case which handles objects with a get_ident_segment member function */ +template <class T> class unwrap_type_segment_inner +{ +public: + using ret = AST::PathIdentSegment; + + static ret &unwrap (T &x) { return x.get_ident_segment (); } + static const ret &unwrap (const T &x) { return x.get_ident_segment (); } +}; + +/* + * Used to get the node id of a path segment object + */ +NodeId +unwrap_segment_node_id (const AST::TypePathSegment &seg); + +NodeId +unwrap_segment_node_id (const AST::SimplePathSegment &seg); + +NodeId +unwrap_segment_node_id (const AST::PathExprSegment &seg); + +template <class T> +NodeId +unwrap_segment_node_id (const std::unique_ptr<T> &ptr) +{ + return unwrap_segment_node_id (*ptr); +} + +/** + * Used to check if a path segment is associated with a lang item + */ +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const AST::TypePathSegment &seg); + +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const AST::SimplePathSegment &seg); + +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const AST::PathExprSegment &seg); + +template <class T> +tl::optional<LangItem::Kind> +unwrap_segment_get_lang_item (const std::unique_ptr<T> &ptr) +{ + return unwrap_segment_get_lang_item (*ptr); +} + +} // namespace Rust |