]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/resolve/rust-ast-resolve-stmt.h
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-full.h"
24 #include "rust-ast-resolve-type.h"
25 #include "rust-ast-resolve-pattern.h"
26 #include "rust-ast-resolve-expr.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::ExprStmtWithBlock
&stmt
) override
49 ResolveExpr::go (stmt
.get_expr ().get (), prefix
, canonical_prefix
);
52 void visit (AST::ExprStmtWithoutBlock
&stmt
) override
54 ResolveExpr::go (stmt
.get_expr ().get (), prefix
, canonical_prefix
);
57 void visit (AST::ConstantItem
&constant
) override
59 auto decl
= CanonicalPath::new_seg (constant
.get_node_id (),
60 constant
.get_identifier ());
61 auto path
= decl
; // this ensures we have the correct relative resolution
62 auto cpath
= canonical_prefix
.append (decl
);
63 mappings
->insert_canonical_path (constant
.get_node_id (), cpath
);
65 resolver
->get_name_scope ().insert (
66 path
, constant
.get_node_id (), constant
.get_locus (), false,
68 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
69 RichLocation
r (constant
.get_locus ());
71 rust_error_at (r
, "redefined multiple times");
74 ResolveType::go (constant
.get_type ().get ());
75 ResolveExpr::go (constant
.get_expr ().get (), prefix
, canonical_prefix
);
78 void visit (AST::LetStmt
&stmt
) override
80 if (stmt
.has_init_expr ())
82 ResolveExpr::go (stmt
.get_init_expr ().get (), prefix
,
86 PatternDeclaration::go (stmt
.get_pattern ().get (), Rib::ItemType::Var
);
88 ResolveType::go (stmt
.get_type ().get ());
91 void visit (AST::TupleStruct
&struct_decl
) override
93 auto decl
= CanonicalPath::new_seg (struct_decl
.get_node_id (),
94 struct_decl
.get_identifier ());
95 auto path
= decl
; // this ensures we have the correct relative resolution
96 auto cpath
= canonical_prefix
.append (decl
);
97 mappings
->insert_canonical_path (struct_decl
.get_node_id (), cpath
);
99 resolver
->get_type_scope ().insert (
100 path
, struct_decl
.get_node_id (), struct_decl
.get_locus (), false,
102 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
103 RichLocation
r (struct_decl
.get_locus ());
105 rust_error_at (r
, "redefined multiple times");
108 NodeId scope_node_id
= struct_decl
.get_node_id ();
109 resolver
->get_type_scope ().push (scope_node_id
);
111 if (struct_decl
.has_generics ())
113 for (auto &generic
: struct_decl
.get_generic_params ())
114 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
117 for (AST::TupleField
&field
: struct_decl
.get_fields ())
118 ResolveType::go (field
.get_field_type ().get ());
120 resolver
->get_type_scope ().pop ();
123 void visit (AST::Enum
&enum_decl
) override
125 auto decl
= CanonicalPath::new_seg (enum_decl
.get_node_id (),
126 enum_decl
.get_identifier ());
127 auto path
= decl
; // this ensures we have the correct relative resolution
128 auto cpath
= canonical_prefix
.append (decl
);
129 mappings
->insert_canonical_path (enum_decl
.get_node_id (), cpath
);
131 resolver
->get_type_scope ().insert (
132 path
, enum_decl
.get_node_id (), enum_decl
.get_locus (), false,
134 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
135 RichLocation
r (enum_decl
.get_locus ());
137 rust_error_at (r
, "redefined multiple times");
140 NodeId scope_node_id
= enum_decl
.get_node_id ();
141 resolver
->get_type_scope ().push (scope_node_id
);
143 if (enum_decl
.has_generics ())
145 for (auto &generic
: enum_decl
.get_generic_params ())
146 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
149 for (auto &variant
: enum_decl
.get_variants ())
150 ResolveStmt::go (variant
.get (), path
, canonical_prefix
, path
);
152 resolver
->get_type_scope ().pop ();
155 void visit (AST::EnumItem
&item
) override
157 auto decl
= enum_prefix
.append (
158 CanonicalPath::new_seg (item
.get_node_id (), item
.get_identifier ()));
159 auto path
= decl
; // this ensures we have the correct relative resolution
160 auto cpath
= canonical_prefix
.append (decl
);
161 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
163 resolver
->get_type_scope ().insert (
164 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
165 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
166 RichLocation
r (item
.get_locus ());
168 rust_error_at (r
, "redefined multiple times");
174 void visit (AST::EnumItemTuple
&item
) override
176 auto decl
= enum_prefix
.append (
177 CanonicalPath::new_seg (item
.get_node_id (), item
.get_identifier ()));
178 auto path
= decl
; // this ensures we have the correct relative resolution
179 auto cpath
= canonical_prefix
.append (decl
);
180 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
182 resolver
->get_type_scope ().insert (
183 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
184 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
185 RichLocation
r (item
.get_locus ());
187 rust_error_at (r
, "redefined multiple times");
190 for (auto &field
: item
.get_tuple_fields ())
192 if (field
.get_field_type ()->is_marked_for_strip ())
195 ResolveType::go (field
.get_field_type ().get ());
199 void visit (AST::EnumItemStruct
&item
) override
201 auto decl
= enum_prefix
.append (
202 CanonicalPath::new_seg (item
.get_node_id (), item
.get_identifier ()));
203 auto path
= decl
; // this ensures we have the correct relative resolution
204 auto cpath
= canonical_prefix
.append (decl
);
205 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
207 resolver
->get_type_scope ().insert (
208 path
, item
.get_node_id (), item
.get_locus (), false, Rib::ItemType::Type
,
209 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
210 RichLocation
r (item
.get_locus ());
212 rust_error_at (r
, "redefined multiple times");
215 for (auto &field
: item
.get_struct_fields ())
217 if (field
.get_field_type ()->is_marked_for_strip ())
220 ResolveType::go (field
.get_field_type ().get ());
224 void visit (AST::EnumItemDiscriminant
&item
) override
226 auto decl
= enum_prefix
.append (
227 CanonicalPath::new_seg (item
.get_node_id (), item
.get_identifier ()));
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 locus
) -> void {
235 RichLocation
r (item
.get_locus ());
237 rust_error_at (r
, "redefined multiple times");
243 void visit (AST::StructStruct
&struct_decl
) override
245 auto decl
= CanonicalPath::new_seg (struct_decl
.get_node_id (),
246 struct_decl
.get_identifier ());
247 auto path
= decl
; // this ensures we have the correct relative resolution
248 auto cpath
= canonical_prefix
.append (decl
);
249 mappings
->insert_canonical_path (struct_decl
.get_node_id (), cpath
);
251 resolver
->get_type_scope ().insert (
252 path
, struct_decl
.get_node_id (), struct_decl
.get_locus (), false,
254 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
255 RichLocation
r (struct_decl
.get_locus ());
257 rust_error_at (r
, "redefined multiple times");
260 NodeId scope_node_id
= struct_decl
.get_node_id ();
261 resolver
->get_type_scope ().push (scope_node_id
);
263 if (struct_decl
.has_generics ())
265 for (auto &generic
: struct_decl
.get_generic_params ())
266 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
269 for (AST::StructField
&field
: struct_decl
.get_fields ())
271 if (field
.get_field_type ()->is_marked_for_strip ())
274 ResolveType::go (field
.get_field_type ().get ());
277 resolver
->get_type_scope ().pop ();
280 void visit (AST::Union
&union_decl
) override
282 auto decl
= CanonicalPath::new_seg (union_decl
.get_node_id (),
283 union_decl
.get_identifier ());
284 auto path
= decl
; // this ensures we have the correct relative resolution
285 auto cpath
= canonical_prefix
.append (decl
);
286 mappings
->insert_canonical_path (union_decl
.get_node_id (), cpath
);
288 resolver
->get_type_scope ().insert (
289 path
, union_decl
.get_node_id (), union_decl
.get_locus (), false,
291 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
292 RichLocation
r (union_decl
.get_locus ());
294 rust_error_at (r
, "redefined multiple times");
297 NodeId scope_node_id
= union_decl
.get_node_id ();
298 resolver
->get_type_scope ().push (scope_node_id
);
300 if (union_decl
.has_generics ())
301 for (auto &generic
: union_decl
.get_generic_params ())
302 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
304 for (AST::StructField
&field
: union_decl
.get_variants ())
306 if (field
.get_field_type ()->is_marked_for_strip ())
309 ResolveType::go (field
.get_field_type ().get ());
312 resolver
->get_type_scope ().pop ();
315 void visit (AST::Function
&function
) override
317 auto decl
= CanonicalPath::new_seg (function
.get_node_id (),
318 function
.get_function_name ());
319 auto path
= decl
; // this ensures we have the correct relative resolution
320 auto cpath
= canonical_prefix
.append (decl
);
321 mappings
->insert_canonical_path (function
.get_node_id (), cpath
);
323 resolver
->get_name_scope ().insert (
324 path
, function
.get_node_id (), function
.get_locus (), false,
325 Rib::ItemType::Function
,
326 [&] (const CanonicalPath
&, NodeId
, Location locus
) -> void {
327 RichLocation
r (function
.get_locus ());
329 rust_error_at (r
, "redefined multiple times");
332 NodeId scope_node_id
= function
.get_node_id ();
333 resolver
->get_name_scope ().push (scope_node_id
);
334 resolver
->get_type_scope ().push (scope_node_id
);
335 resolver
->get_label_scope ().push (scope_node_id
);
336 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
337 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
338 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
340 if (function
.has_generics ())
341 for (auto &generic
: function
.get_generic_params ())
342 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
344 if (function
.has_return_type ())
345 ResolveType::go (function
.get_return_type ().get ());
347 // we make a new scope so the names of parameters are resolved and shadowed
349 for (auto ¶m
: function
.get_function_params ())
351 ResolveType::go (param
.get_type ().get ());
352 PatternDeclaration::go (param
.get_pattern ().get (),
353 Rib::ItemType::Param
);
356 // resolve the function body
357 ResolveExpr::go (function
.get_definition ().get (), path
, cpath
);
359 resolver
->get_name_scope ().pop ();
360 resolver
->get_type_scope ().pop ();
361 resolver
->get_label_scope ().pop ();
364 void visit (AST::ExternBlock
&extern_block
) override
;
367 ResolveStmt (const CanonicalPath
&prefix
,
368 const CanonicalPath
&canonical_prefix
,
369 const CanonicalPath
&enum_prefix
)
370 : ResolverBase (), prefix (prefix
), canonical_prefix (canonical_prefix
),
371 enum_prefix (enum_prefix
)
374 const CanonicalPath
&prefix
;
375 const CanonicalPath
&canonical_prefix
;
377 /* item declaration statements are not given a canonical path, but enum items
378 * (variants) do inherit the enum path/identifier name. */
379 const CanonicalPath
&enum_prefix
;
382 } // namespace Resolver
385 #endif // RUST_AST_RESOLVE_STMT_H