1 // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 // This file is part of GCC.
5 // GCC is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 3, or (at your option) any later
10 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // You should have received a copy of the GNU General Public License
16 // along with GCC; see the file COPYING3. If not see
17 // <http://www.gnu.org/licenses/>.
22 #include "rust-system.h"
28 namespace Resolver2_0
{
33 /// The type namespace includes `struct`s, `enum`s, `union`s, `trait`s, and
35 /// (and, by extension, crates).
37 /// Note that the type namespace includes other items; this is not an
40 /// The value namespace includes `fn`s, `const`s, `static`s, and local
41 variables (including function arguments). ValueNS,
42 /// The macro namespace includes `macro_rules!` macros, declarative `macro`s,
43 /// procedural macros, attribute macros, `derive` macros, and non-macro
45 /// like `#[inline]` and `#[rustfmt::skip]`.
51 // FIXME: There's no `labels` namespace, not sure if we need one or how to keep
53 // FIXME: And where are things like loop labels kept?
56 * All namespaces that Rust's name resolution needs to handle
58 // TODO: Move to `rust-forever-stack.h`?
65 // TODO: Which namespaces are we missing?
69 * Error returned by `Rib::insert` when the key was already present in the Rib's
70 * map. The class contains the previously-inserted NodeId as well as the name of
73 struct DuplicateNameError
75 // TODO: We might need multiple kinds of errors later down the line
76 DuplicateNameError (std::string name
, NodeId existing
);
83 * A rib is a container of nodes, either declaration or usages, as well as the
84 * identifier each node uses. They are used to delimit lexical scopes, and have
85 * an impact on name resolution - they restrict certain name accesses and serve
86 * as boundaries between scopes.
88 * For example, if we are resolving the following *variable* use:
99 * The `Function` rib we will have pushed will restrict the access to `outer`'s
100 * `a` declaration: Variable uses cannot cross function boundaries. On the other
101 * hand, if we were resolving a type usage, this would be perfectly allowed.
106 // TODO: Rename the class? to what? Binding? Declaration?
107 // This is useful for items which are in namespaces where shadowing is not
108 // allowed, but which are still shadowable! for example, when you do a glob
109 // import, if a later import has the same name as an item imported in the glob
110 // import, that glob imported item will need to get shadowed
114 static Definition
NonShadowable (NodeId id
);
115 static Definition
Shadowable (NodeId id
);
117 std::vector
<NodeId
> ids
;
120 Definition () = default;
122 Definition
&operator= (const Definition
&) = default;
123 Definition (Definition
const &) = default;
125 bool is_ambiguous () const;
127 NodeId
get_node_id ()
129 rust_assert (!is_ambiguous ());
133 std::string
to_string () const;
136 Definition (NodeId id
, bool shadowable
);
144 ConstantItem
, // -> this variant has a boolean
146 /* Any item other than a Module, Function, Constant, Trait or Impl block */
150 /* Ban the use of forward-declared generic parameters in defaults */
152 /* Const generic, as in the following example: fn foo<T, const X: T>() {} */
157 Rib (Kind kind
, std::string identifier
, NodeId id
);
158 Rib (Kind kind
, std::unordered_map
<std::string
, NodeId
> values
);
160 // TODO: What's the correctbehavior if the key already exists? What if a decl
161 // and use are in the same rib? Is that possible? Okay based on RibKind?
164 * Insert a new node in the rib
166 * @param name The name associated with the AST node
167 * @param def The `Definition` to insert
169 * @return `DuplicateNameError` if the node is already present in the rib. The
170 * `DuplicateNameError` class contains the NodeId of the existing
171 * node. Returns the new NodeId on success.
173 tl::expected
<NodeId
, DuplicateNameError
> insert (std::string name
,
177 * Access an inserted NodeId.
179 * @return tl::nullopt if the key does not exist, the NodeId otherwise
181 tl::optional
<Rib::Definition
> get (const std::string
&name
);
183 /* View all the values stored in the rib */
184 const std::unordered_map
<std::string
, Definition
> &get_values () const;
187 // TODO: Switch this to (NodeId, shadowable = false);
188 std::unordered_map
<std::string
, Definition
> values
;
191 } // namespace Resolver2_0
194 #endif // !RUST_RIB_H