aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/util
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/util')
-rw-r--r--gcc/rust/util/rust-hir-map.cc33
-rw-r--r--gcc/rust/util/rust-hir-map.h10
-rw-r--r--gcc/rust/util/rust-optional-test.cc110
-rw-r--r--gcc/rust/util/rust-optional.h288
4 files changed, 22 insertions, 419 deletions
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index 783e899..793d547 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -1035,14 +1035,14 @@ Mappings::insert_module_child (NodeId module, NodeId child)
it->second.emplace_back (child);
}
-Optional<std::vector<NodeId> &>
+tl::optional<std::vector<NodeId> &>
Mappings::lookup_module_children (NodeId module)
{
auto it = module_child_map.find (module);
if (it == module_child_map.end ())
- return Optional<std::vector<NodeId> &>::none ();
+ return tl::nullopt;
- return Optional<std::vector<NodeId> &>::some (it->second);
+ return it->second;
}
void
@@ -1059,33 +1059,34 @@ Mappings::insert_module_child_item (NodeId module,
it->second.emplace_back (child);
}
-Optional<std::vector<Resolver::CanonicalPath> &>
+tl::optional<std::vector<Resolver::CanonicalPath> &>
Mappings::lookup_module_chidren_items (NodeId module)
{
auto it = module_child_items.find (module);
if (it == module_child_items.end ())
- return Optional<std::vector<Resolver::CanonicalPath> &>::none ();
+ return tl::nullopt;
- return Optional<std::vector<Resolver::CanonicalPath> &>::some (it->second);
+ return it->second;
}
-Optional<Resolver::CanonicalPath &>
+tl::optional<Resolver::CanonicalPath &>
Mappings::lookup_module_child (NodeId module, const std::string &item_name)
{
- Optional<std::vector<Resolver::CanonicalPath> &> children
+ tl::optional<std::vector<Resolver::CanonicalPath> &> children
= lookup_module_chidren_items (module);
- if (children.is_none ())
- return Optional<Resolver::CanonicalPath &>::none ();
+ if (!children.has_value ())
+ return tl::nullopt;
// lookup the children to match the name if we can
- for (auto &child : children.get ())
+ for (auto &child : children.value ())
{
const std::string &raw_identifier = child.get ();
bool found = raw_identifier.compare (item_name) == 0;
if (found)
- return Optional<Resolver::CanonicalPath &>::some (child);
+ return child;
}
- return Optional<Resolver::CanonicalPath &>::none ();
+
+ return tl::nullopt;
}
void
@@ -1095,14 +1096,14 @@ Mappings::insert_child_item_to_parent_module_mapping (NodeId child_item,
child_to_parent_module_map.insert ({child_item, parent_module});
}
-Optional<NodeId>
+tl::optional<NodeId>
Mappings::lookup_parent_module (NodeId child_item)
{
auto it = child_to_parent_module_map.find (child_item);
if (it == child_to_parent_module_map.end ())
- return Optional<NodeId>::none ();
+ return tl::nullopt;
- return Optional<NodeId>::some (it->second);
+ return it->second;
}
bool
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index 964b626..495bca2 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -19,7 +19,7 @@
#ifndef RUST_HIR_MAP_H
#define RUST_HIR_MAP_H
-#include "rust-optional.h"
+#include "optional.h"
#include "rust-system.h"
#include "rust-location.h"
#include "rust-mapping-common.h"
@@ -303,17 +303,17 @@ public:
bool lookup_visibility (NodeId id, Privacy::ModuleVisibility &def);
void insert_module_child (NodeId module, NodeId child);
- Optional<std::vector<NodeId> &> lookup_module_children (NodeId module);
+ tl::optional<std::vector<NodeId> &> lookup_module_children (NodeId module);
void insert_module_child_item (NodeId module, Resolver::CanonicalPath item);
- Optional<std::vector<Resolver::CanonicalPath> &>
+ tl::optional<std::vector<Resolver::CanonicalPath> &>
lookup_module_chidren_items (NodeId module);
- Optional<Resolver::CanonicalPath &>
+ tl::optional<Resolver::CanonicalPath &>
lookup_module_child (NodeId module, const std::string &item_name);
void insert_child_item_to_parent_module_mapping (NodeId child_item,
NodeId parent_module);
- Optional<NodeId> lookup_parent_module (NodeId child_item);
+ tl::optional<NodeId> lookup_parent_module (NodeId child_item);
bool node_is_module (NodeId query);
void insert_ast_item (AST::Item *item);
diff --git a/gcc/rust/util/rust-optional-test.cc b/gcc/rust/util/rust-optional-test.cc
deleted file mode 100644
index 9fbbe7d..0000000
--- a/gcc/rust/util/rust-optional-test.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (C) 2020-2023 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-system.h"
-#include "rust-optional.h"
-#include "selftest.h"
-
-#if CHECKING_P
-
-static void
-rust_optional_create ()
-{
- auto opt = Rust::Optional<int>::some (15);
-
- ASSERT_TRUE (opt.is_some ());
- ASSERT_EQ (opt.get (), 15);
-
- Rust::Optional<int> const_opt = Rust::Optional<int>::some (15);
- const int &value = const_opt.get ();
-
- ASSERT_EQ (value, 15);
-}
-
-static void
-rust_optional_operators ()
-{
- auto opt = Rust::Optional<int>::some (15);
-
- // as bool
- ASSERT_TRUE (opt);
-
- // deref
- ASSERT_EQ (*opt, 15);
-
- class Methodable
- {
- public:
- int method () { return 15; }
- };
-
- auto m_opt = Rust::Optional<Methodable>::some (Methodable ());
- ASSERT_EQ (m_opt->method (), 15);
-}
-
-static void
-rust_optional_take ()
-{
- auto opt = Rust::Optional<int>::some (15);
- auto value = opt.take ();
-
- ASSERT_EQ (value, 15);
- ASSERT_TRUE (opt.is_none ());
-}
-
-static void
-rust_optional_map ()
-{
- auto opt = Rust::Optional<int>::some (15);
- auto twice = opt.map<int> ([] (int value) { return value * 2; });
-
- ASSERT_FALSE (opt);
- ASSERT_TRUE (twice);
- ASSERT_EQ (*twice, 30);
-}
-
-static void
-rust_optional_reference ()
-{
- auto value = std::vector<std::string> ();
- value.emplace_back ("rust");
- value.emplace_back ("+");
- value.emplace_back ("gcc");
- value.emplace_back ("=");
- value.emplace_back ("<3");
-
- auto opt = Rust::Optional<std::vector<std::string> &>::some (value);
-
- ASSERT_EQ (opt->at (0), "rust");
- ASSERT_EQ (opt->at (2), "gcc");
-}
-
-#endif /* #if CHECKING_P */
-
-void
-rust_optional_test ()
-{
-#if CHECKING_P
- rust_optional_create ();
- rust_optional_operators ();
- rust_optional_take ();
- rust_optional_map ();
- rust_optional_reference ();
-
-#endif /* #if CHECKING_P */
-}
diff --git a/gcc/rust/util/rust-optional.h b/gcc/rust/util/rust-optional.h
deleted file mode 100644
index bdfbd28..0000000
--- a/gcc/rust/util/rust-optional.h
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (C) 2020-2023 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/>.
-
-#ifndef RUST_OPTIONAL_H
-#define RUST_OPTIONAL_H
-
-#include "config.h"
-#include "rust-system.h"
-
-#include "selftest.h"
-
-namespace Rust {
-
-/**
- * Tagged union to try and simulate a sum type. This is safer and more ergonomic
- * than one of the two alternatives we're currently using in the compiler:
- *
- * 1. Storing a raw pointer, which can be `nullptr` or valid
- *
- * This is wildly unsafe, and usable in conjunction with local references, stack
- * variables, or pointers managed elsewhere, which can cause crashes, hard to
- * debug issues or undefined behavior. Likewise, if you do not check for the
- * pointer's validity, this will cause a crash.
- *
- * 2. Storing an extra boolean alongside the object
- *
- * This causes implementors to use a "dummy object": Either an empty version or
- * an error version. But what happens if what you really wanted to store was
- * the empty or error version? You can also easily incorporate logic bugs if you
- * forget to check for the associated boolean.
- *
- * The `Optional<T>` type has the same "ergonomic" cost: You need to check
- * whether your option is valid or not. However, the main advantage is that it
- * is more restrictive: You can only acess the member it contains "safely".
- * It is similar to storing a value + an associated boolean, but has the
- * advantage of making up only one member in your class.
- * You also benefit from some helper methods such as `map()`.
- *
- * You also get helper functions and operator overloading to "seamlessly"
- * replace raw pointer alternatives.
- *
- * ```c++
- * MyType *raw_pointer = something_that_can_fail();
- * if (raw_pointer)
- * raw_pointer->method();
- *
- * // or
- *
- * Optional<MyType> opt = something_that_can_fail2();
- * if (opt)
- * opt->method();
- *
- * // equivalent to
- *
- * if (opt.is_some())
- * opt.get().method();
- * ```
- */
-template <typename T> class Optional
-{
-private:
- struct tag_some
- {
- };
- struct tag_none
- {
- };
-
- bool field_is_some;
-
- union
- {
- T value;
- // prevents initialization warnings
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635#c53
- // FIXME: remove
- volatile char unused;
- };
-
- Optional (tag_some, const T &value) : field_is_some (true), value (value) {}
- Optional (tag_some, T &&value) : field_is_some (true), value (value) {}
-
- Optional (tag_none) : field_is_some (false) {}
-
-public:
- Optional (const Optional &other)
- {
- if ((field_is_some = other.field_is_some))
- new (&value) T (other.value);
- }
-
- Optional (Optional &&other)
- {
- if ((field_is_some = other.field_is_some))
- new (&value) T (other.value);
- }
-
- Optional &operator= (const Optional &other)
- {
- if (is_some ())
- value.~T ();
- if ((field_is_some = other.field_is_some))
- new (&value) T (other.value);
- return *this;
- }
-
- Optional &operator= (Optional &&other)
- {
- if (is_some ())
- value.~T ();
- if ((field_is_some = other.field_is_some))
- new (&value) T (other.value);
- return *this;
- }
-
- ~Optional ()
- {
- if (is_some ())
- value.~T ();
- }
-
- static Optional some (const T &value)
- {
- return Optional (tag_some (), value);
- }
-
- static Optional some (T &&value) { return Optional (tag_some (), value); }
-
- static Optional none () { return Optional (tag_none ()); }
-
- bool is_some () const { return field_is_some; }
- bool is_none () const { return !is_some (); }
-
- /**
- * Enable boolean-like comparisons.
- */
- operator bool () { return is_some (); }
-
- /**
- * Enables dereferencing to access the contained value
- */
- T &operator* () { return get (); }
- const T &operator* () const { return get (); }
- T *operator-> () { return &get (); }
- const T *operator-> () const { return &get (); }
-
- const T &get () const
- {
- rust_assert (is_some ());
-
- return value;
- }
-
- T &get ()
- {
- rust_assert (is_some ());
-
- return value;
- }
-
- T take ()
- {
- rust_assert (is_some ());
-
- T to_return = std::move (value);
- value.~T ();
-
- field_is_some = false;
-
- return to_return;
- }
-
- template <typename U> Optional<U> map (std::function<U (T)> functor)
- {
- if (is_none ())
- return Optional::none ();
-
- auto value = functor (take ());
-
- return Optional::some (value);
- }
-};
-
-template <typename T> class Optional<T &>
-{
-private:
- T *inner;
-
- Optional (T *inner) : inner (inner) {}
-
-public:
- static Optional<T &> some (T &value) { return Optional (&value); }
-
- static Optional<T &> none () { return Optional (nullptr); }
-
- bool is_some () const { return inner; }
- bool is_none () const { return !is_some (); }
-
- // FIXME: Can we factor this in a single class?
-
- /**
- * Enable boolean-like comparisons.
- */
- operator bool () { return is_some (); }
-
- /**
- * Enables dereferencing to access the contained value
- */
- T &operator* () { return get (); }
- const T &operator* () const { return get (); }
- T *operator-> () { return &get (); }
- const T *operator-> () const { return &get (); }
-
- T &get () const
- {
- rust_assert (is_some ());
-
- return *inner;
- }
-
- T &take ()
- {
- rust_assert (is_some ());
-
- T *to_return = inner;
- inner = nullptr;
-
- return *to_return;
- }
-
- template <typename U> Optional<U &> map (std::function<U &(T &)> functor)
- {
- if (is_none ())
- return Optional::none ();
-
- auto value = functor (take ());
-
- return Optional::some (value);
- }
-};
-
-template <typename T, typename U>
-bool
-operator== (const Optional<T> &t, const Optional<U> &u)
-{
- if (t.is_some ())
- return u.is_some () && t.get () == u.get ();
- else
- return u.is_none ();
-}
-
-} // namespace Rust
-
-namespace std {
-
-template <typename T> struct hash<Rust::Optional<T>>
-{
- size_t operator() (const Rust::Optional<T> &op) const
- {
- return op.is_some () ? std::hash<T> () (op.get ()) : 0;
- }
-};
-
-} // namespace std
-
-#ifdef CHECKING_P
-
-void
-rust_optional_test ();
-
-#endif // !CHECKING_P
-
-#endif // !RUST_OPTIONAL_H