aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/util
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/util')
-rw-r--r--gcc/rust/util/rust-attribute-values.h1
-rw-r--r--gcc/rust/util/rust-attributes.cc10
-rw-r--r--gcc/rust/util/rust-attributes.h6
-rw-r--r--gcc/rust/util/rust-common.h1
-rw-r--r--gcc/rust/util/rust-edition.cc40
-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.cc118
-rw-r--r--gcc/rust/util/rust-hir-map.h42
-rw-r--r--gcc/rust/util/rust-lang-item.cc83
-rw-r--r--gcc/rust/util/rust-lang-item.h43
-rw-r--r--gcc/rust/util/rust-operators.h8
-rw-r--r--gcc/rust/util/rust-stacked-contexts.h7
-rw-r--r--gcc/rust/util/rust-token-converter.cc3
-rw-r--r--gcc/rust/util/rust-token-converter.h2
-rw-r--r--gcc/rust/util/rust-unwrap-segment.cc61
-rw-r--r--gcc/rust/util/rust-unwrap-segment.h121
16 files changed, 527 insertions, 45 deletions
diff --git a/gcc/rust/util/rust-attribute-values.h b/gcc/rust/util/rust-attribute-values.h
index ef01e67..9ef5cc5 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";
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 958f7c3..03452c7 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},
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index 1345168..c928c8e 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,
diff --git a/gcc/rust/util/rust-common.h b/gcc/rust/util/rust-common.h
index 2033694..71637ce 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 ef58991..d034ea0 100644
--- a/gcc/rust/util/rust-make-unique.h
+++ b/gcc/rust/util/rust-edition.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2025 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 03b3343..eaa640c 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -148,6 +148,16 @@ Mappings::get_crate_name (CrateNum crate_num) const
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;
+
+ return it->second;
+}
+
void
Mappings::set_crate_name (CrateNum crate_num, const std::string &name)
{
@@ -184,13 +194,7 @@ Mappings::crate_num_to_nodeid (const CrateNum &crate_num) const
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
@@ -262,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
@@ -459,7 +464,7 @@ Mappings::insert_hir_impl_block (HIR::ImplBlock *item)
auto id = item->get_mappings ().get_hirid ();
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);
@@ -874,7 +879,7 @@ 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};
}
tl::optional<AST::MacroRulesDefinition *>
@@ -884,7 +889,17 @@ Mappings::lookup_macro_def (NodeId id)
if (it == macroMappings.end ())
return tl::nullopt;
- return it->second;
+ 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;
+
+ return it->second.second;
}
void
@@ -1241,6 +1256,9 @@ 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)
{
@@ -1258,5 +1276,85 @@ Mappings::lookup_trait_item_lang_item (LangItem::Kind item, location_t 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 bb7318e..b523a36 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -81,6 +81,8 @@ public:
void set_current_crate (CrateNum crateNum);
CrateNum get_current_crate () 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);
const std::string &get_current_crate_name () const;
tl::optional<CrateNum>
@@ -256,22 +258,12 @@ public:
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;
- }
-
- tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type)
- {
- auto it = lang_item_mappings.find (item_type);
- if (it == lang_item_mappings.end ())
- return tl::nullopt;
+ void insert_lang_item (LangItem::Kind item_type, DefId id);
+ tl::optional<DefId &> lookup_lang_item (LangItem::Kind item_type);
- return it->second;
- }
+ 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);
@@ -279,6 +271,7 @@ public:
void insert_macro_def (AST::MacroRulesDefinition *macro);
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);
@@ -352,6 +345,11 @@ public:
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,7 +387,15 @@ 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<LangItem::Kind, NodeId> lang_item_nodes;
+
std::map<NodeId, Resolver::CanonicalPath> paths;
std::map<NodeId, location_t> locations;
std::map<NodeId, HirId> nodeIdToHirMappings;
@@ -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 5ddffaa..a76cc7f 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,31 @@ 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},
}};
tl::optional<LangItem::Kind>
@@ -108,6 +135,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 +172,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 +256,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 951e4a3..8f3af36 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,50 @@ 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,
};
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 608e771..02b1820 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 39a0c08..fe0bc8a 100644
--- a/gcc/rust/util/rust-stacked-contexts.h
+++ b/gcc/rust/util/rust-stacked-contexts.h
@@ -71,6 +71,13 @@ public:
return last;
}
+ const 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