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/>.
19 #ifndef RUST_AST_RESOLVE_STMT_H
20 #define RUST_AST_RESOLVE_STMT_H
22 #include "rust-ast-resolve-base.h"
23 #include "rust-ast-resolve-type.h"
24 #include "rust-ast-resolve-pattern.h"
25 #include "rust-ast-resolve-expr.h"
26 #include "rust-item.h"
31 class ResolveStmt
: public ResolverBase
33 using Rust::Resolver::ResolverBase::visit
;
36 static void go (AST::Stmt
&stmt
, const CanonicalPath
&prefix
,
37 const CanonicalPath
&canonical_prefix
,
38 const CanonicalPath
&enum_prefix
)
40 if (stmt
.is_marked_for_strip ())
43 ResolveStmt
resolver (prefix
, canonical_prefix
, enum_prefix
);
44 stmt
.accept_vis (resolver
);
47 void visit (AST::ExprStmt
&stmt
) override
49 ResolveExpr::go (stmt
.get_expr (), prefix
, canonical_prefix
);
52 void visit (AST::ConstantItem
&constant
) override
54 auto decl
= CanonicalPath::new_seg (constant
.get_node_id (),
55 constant
.get_identifier ());
56 auto path
= decl
; // this ensures we have the correct relative resolution
57 auto cpath
= canonical_prefix
.append (decl
);
58 mappings
->insert_canonical_path (constant
.get_node_id (), cpath
);
60 resolver
->get_name_scope ().insert (
61 path
, constant
.get_node_id (), constant
.get_locus (), false,
63 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
64 rich_location
r (line_table
, constant
.get_locus ());
66 rust_error_at (r
, "redefined multiple times");
69 ResolveType::go (constant
.get_type ());
70 ResolveExpr::go (constant
.get_expr (), prefix
, canonical_prefix
);
73 void visit (AST::LetStmt
&stmt
) override
75 if (stmt
.has_init_expr ())
77 ResolveExpr::go (stmt
.get_init_expr (), prefix
, canonical_prefix
);
80 PatternDeclaration::go (stmt
.get_pattern (), Rib::ItemType::Var
);
82 ResolveType::go (stmt
.get_type ());
85 void visit (AST::TupleStruct
&struct_decl
) override
88 = CanonicalPath::new_seg (struct_decl
.get_node_id (),
89 struct_decl
.get_identifier ().as_string ());
90 auto path
= decl
; // this ensures we have the correct relative resolution
91 auto cpath
= canonical_prefix
.append (decl
);
92 mappings
->insert_canonical_path (struct_decl
.get_node_id (), cpath
);
94 resolver
->get_type_scope ().insert (
95 path
, struct_decl
.get_node_id (), struct_decl
.get_locus (), false,
97 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
98 rich_location
r (line_table
, struct_decl
.get_locus ());
100 rust_error_at (r
, "redefined multiple times");
103 NodeId scope_node_id
= struct_decl
.get_node_id ();
104 resolver
->get_type_scope ().push (scope_node_id
);
106 if (struct_decl
.has_generics ())
108 for (auto &generic
: struct_decl
.get_generic_params ())
109 ResolveGenericParam::go (*generic
, prefix
, canonical_prefix
);
112 for (AST::TupleField
&field
: struct_decl
.get_fields ())
113 ResolveType::go (field
.get_field_type ());
115 resolver
->get_type_scope ().pop ();
118 void visit (AST::Enum
&enum_decl
) override
121 = CanonicalPath::new_seg (enum_decl
.get_node_id (),
122 enum_decl
.get_identifier ().as_string ());
123 auto path
= decl
; // this ensures we have the correct relative resolution
124 auto cpath
= canonical_prefix
.append (decl
);
125 mappings
->insert_canonical_path (enum_decl
.get_node_id (), cpath
);
127 resolver
->get_type_scope ().insert (
128 path
, enum_decl
.get_node_id (), enum_decl
.get_locus (), false,
130 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
131 rich_location
r (line_table
, enum_decl
.get_locus ());
133 rust_error_at (r
, "redefined multiple times");
136 NodeId scope_node_id
= enum_decl
.get_node_id ();
137 resolver
->get_type_scope ().push (scope_node_id
);
139 if (enum_decl
.has_generics ())
141 for (auto &generic
: enum_decl
.get_generic_params ())
142 ResolveGenericParam::go (*generic
, prefix
, canonical_prefix
);
145 for (auto &variant
: enum_decl
.get_variants ())
146 ResolveStmt::go (*variant
, path
, canonical_prefix
, path
);
148 resolver
->get_type_scope ().pop ();
151 void visit (AST::EnumItem
&item
) override
153 auto decl
= enum_prefix
.append (
154 CanonicalPath::new_seg (item
.get_node_id (),
155 item
.get_identifier ().as_string ()));
156 auto path
= decl
; // this ensures we have the correct relative resolution
157 auto cpath
= canonical_prefix
.append (decl
);
158 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
160 resolver
->get_type_scope ().insert (
161 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
162 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
163 rich_location
r (line_table
, item
.get_locus ());
165 rust_error_at (r
, "redefined multiple times");
171 void visit (AST::EnumItemTuple
&item
) override
173 auto decl
= enum_prefix
.append (
174 CanonicalPath::new_seg (item
.get_node_id (),
175 item
.get_identifier ().as_string ()));
176 auto path
= decl
; // this ensures we have the correct relative resolution
177 auto cpath
= canonical_prefix
.append (decl
);
178 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
180 resolver
->get_type_scope ().insert (
181 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
182 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
183 rich_location
r (line_table
, item
.get_locus ());
185 rust_error_at (r
, "redefined multiple times");
188 for (auto &field
: item
.get_tuple_fields ())
190 if (field
.get_field_type ().is_marked_for_strip ())
193 ResolveType::go (field
.get_field_type ());
197 void visit (AST::EnumItemStruct
&item
) override
199 auto decl
= enum_prefix
.append (
200 CanonicalPath::new_seg (item
.get_node_id (),
201 item
.get_identifier ().as_string ()));
202 auto path
= decl
; // this ensures we have the correct relative resolution
203 auto cpath
= canonical_prefix
.append (decl
);
204 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
206 resolver
->get_type_scope ().insert (
207 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
208 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
209 rich_location
r (line_table
, item
.get_locus ());
211 rust_error_at (r
, "redefined multiple times");
214 for (auto &field
: item
.get_struct_fields ())
216 if (field
.get_field_type ().is_marked_for_strip ())
219 ResolveType::go (field
.get_field_type ());
223 void visit (AST::EnumItemDiscriminant
&item
) override
225 auto decl
= enum_prefix
.append (
226 CanonicalPath::new_seg (item
.get_node_id (),
227 item
.get_identifier ().as_string ()));
228 auto path
= decl
; // this ensures we have the correct relative resolution
229 auto cpath
= canonical_prefix
.append (decl
);
230 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
232 resolver
->get_type_scope ().insert (
233 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
234 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
235 rich_location
r (line_table
, item
.get_locus ());
237 rust_error_at (r
, "redefined multiple times");
243 void visit (AST::StructStruct
&struct_decl
) override
246 = CanonicalPath::new_seg (struct_decl
.get_node_id (),
247 struct_decl
.get_identifier ().as_string ());
248 auto path
= decl
; // this ensures we have the correct relative resolution
249 auto cpath
= canonical_prefix
.append (decl
);
250 mappings
->insert_canonical_path (struct_decl
.get_node_id (), cpath
);
252 resolver
->get_type_scope ().insert (
253 path
, struct_decl
.get_node_id (), struct_decl
.get_locus (), false,
255 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
256 rich_location
r (line_table
, struct_decl
.get_locus ());
258 rust_error_at (r
, "redefined multiple times");
261 NodeId scope_node_id
= struct_decl
.get_node_id ();
262 resolver
->get_type_scope ().push (scope_node_id
);
264 if (struct_decl
.has_generics ())
266 for (auto &generic
: struct_decl
.get_generic_params ())
267 ResolveGenericParam::go (*generic
, prefix
, canonical_prefix
);
270 for (AST::StructField
&field
: struct_decl
.get_fields ())
272 if (field
.get_field_type ().is_marked_for_strip ())
275 ResolveType::go (field
.get_field_type ());
278 resolver
->get_type_scope ().pop ();
281 void visit (AST::Union
&union_decl
) override
284 = CanonicalPath::new_seg (union_decl
.get_node_id (),
285 union_decl
.get_identifier ().as_string ());
286 auto path
= decl
; // this ensures we have the correct relative resolution
287 auto cpath
= canonical_prefix
.append (decl
);
288 mappings
->insert_canonical_path (union_decl
.get_node_id (), cpath
);
290 resolver
->get_type_scope ().insert (
291 path
, union_decl
.get_node_id (), union_decl
.get_locus (), false,
293 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
294 rich_location
r (line_table
, union_decl
.get_locus ());
296 rust_error_at (r
, "redefined multiple times");
299 NodeId scope_node_id
= union_decl
.get_node_id ();
300 resolver
->get_type_scope ().push (scope_node_id
);
302 if (union_decl
.has_generics ())
303 for (auto &generic
: union_decl
.get_generic_params ())
304 ResolveGenericParam::go (*generic
, prefix
, canonical_prefix
);
306 for (AST::StructField
&field
: union_decl
.get_variants ())
308 if (field
.get_field_type ().is_marked_for_strip ())
311 ResolveType::go (field
.get_field_type ());
314 resolver
->get_type_scope ().pop ();
317 void visit (AST::Function
&function
) override
320 = CanonicalPath::new_seg (function
.get_node_id (),
321 function
.get_function_name ().as_string ());
322 auto path
= decl
; // this ensures we have the correct relative resolution
323 auto cpath
= canonical_prefix
.append (decl
);
324 mappings
->insert_canonical_path (function
.get_node_id (), cpath
);
326 resolver
->get_name_scope ().insert (
327 path
, function
.get_node_id (), function
.get_locus (), false,
328 Rib::ItemType::Function
,
329 [&] (const CanonicalPath
&, NodeId
, location_t locus
) -> void {
330 rich_location
r (line_table
, function
.get_locus ());
332 rust_error_at (r
, "redefined multiple times");
335 NodeId scope_node_id
= function
.get_node_id ();
336 resolver
->get_name_scope ().push (scope_node_id
);
337 resolver
->get_type_scope ().push (scope_node_id
);
338 resolver
->get_label_scope ().push (scope_node_id
);
339 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
340 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
341 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
343 if (function
.has_generics ())
344 for (auto &generic
: function
.get_generic_params ())
345 ResolveGenericParam::go (*generic
, prefix
, canonical_prefix
);
347 if (function
.has_return_type ())
348 ResolveType::go (function
.get_return_type ());
350 std::vector
<PatternBinding
> bindings
351 = {PatternBinding (PatternBoundCtx::Product
, std::set
<Identifier
> ())};
353 // we make a new scope so the names of parameters are resolved and shadowed
355 for (auto &p
: function
.get_function_params ())
357 if (p
->is_variadic ())
359 auto ¶m
= static_cast<AST::VariadicParam
&> (*p
);
360 PatternDeclaration::go (param
.get_pattern (), Rib::ItemType::Param
,
364 else if (p
->is_self ())
366 auto ¶m
= static_cast<AST::SelfParam
&> (*p
);
367 ResolveType::go (param
.get_type ());
371 auto ¶m
= static_cast<AST::FunctionParam
&> (*p
);
373 ResolveType::go (param
.get_type ());
374 PatternDeclaration::go (param
.get_pattern (), Rib::ItemType::Param
,
379 // resolve the function body
380 ResolveExpr::go (*function
.get_definition ().value (), path
, cpath
);
382 resolver
->get_name_scope ().pop ();
383 resolver
->get_type_scope ().pop ();
384 resolver
->get_label_scope ().pop ();
387 void visit (AST::ExternBlock
&extern_block
) override
;
388 void visit (AST::Trait
&trait
) override
;
389 void visit (AST::InherentImpl
&impl_block
) override
;
390 void visit (AST::TraitImpl
&impl_block
) override
;
393 ResolveStmt (const CanonicalPath
&prefix
,
394 const CanonicalPath
&canonical_prefix
,
395 const CanonicalPath
&enum_prefix
)
396 : ResolverBase (), prefix (prefix
), canonical_prefix (canonical_prefix
),
397 enum_prefix (enum_prefix
)
400 const CanonicalPath
&prefix
;
401 const CanonicalPath
&canonical_prefix
;
403 /* item declaration statements are not given a canonical path, but enum items
404 * (variants) do inherit the enum path/identifier name. */
405 const CanonicalPath
&enum_prefix
;
408 } // namespace Resolver
411 #endif // RUST_AST_RESOLVE_STMT_H