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 #include "rust-ast-resolve-item.h"
20 #include "rust-ast-full-decls.h"
21 #include "rust-ast-resolve-toplevel.h"
22 #include "rust-ast-resolve-type.h"
23 #include "rust-ast-resolve-pattern.h"
24 #include "rust-ast-resolve-path.h"
26 #include "rust-item.h"
32 ResolveTraitItems::ResolveTraitItems (const CanonicalPath
&prefix
,
33 const CanonicalPath
&canonical_prefix
)
34 : ResolverBase (), prefix (prefix
), canonical_prefix (canonical_prefix
)
38 ResolveTraitItems::go (AST::AssociatedItem
*item
, const CanonicalPath
&prefix
,
39 const CanonicalPath
&canonical_prefix
)
41 if (item
->is_marked_for_strip ())
44 ResolveTraitItems
resolver (prefix
, canonical_prefix
);
45 item
->accept_vis (resolver
);
49 ResolveTraitItems::visit (AST::Function
&function
)
52 = CanonicalPath::new_seg (function
.get_node_id (),
53 function
.get_function_name ().as_string ());
54 auto path
= prefix
.append (decl
);
55 auto cpath
= canonical_prefix
.append (decl
);
56 mappings
->insert_canonical_path (function
.get_node_id (), cpath
);
58 NodeId scope_node_id
= function
.get_node_id ();
59 resolver
->get_name_scope ().push (scope_node_id
);
60 resolver
->get_type_scope ().push (scope_node_id
);
61 resolver
->get_label_scope ().push (scope_node_id
);
62 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
63 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
64 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
66 if (function
.has_generics ())
67 for (auto &generic
: function
.get_generic_params ())
68 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
70 if (function
.has_return_type ())
71 ResolveType::go (function
.get_return_type ().get ());
73 // self turns into (self: Self) as a function param
74 std::vector
<PatternBinding
> bindings
75 = {PatternBinding (PatternBoundCtx::Product
, std::set
<Identifier
> ())};
77 // we make a new scope so the names of parameters are resolved and shadowed
79 for (auto &p
: function
.get_function_params ())
81 if (p
->is_variadic ())
83 auto param
= static_cast<AST::VariadicParam
*> (p
.get ());
84 PatternDeclaration::go (param
->get_pattern ().get (),
85 Rib::ItemType::Param
, bindings
);
87 else if (p
->is_self ())
89 auto param
= static_cast<AST::SelfParam
*> (p
.get ());
90 // FIXME: which location should be used for Rust::Identifier `self`?
91 AST::IdentifierPattern
self_pattern (
92 param
->get_node_id (), {"self"}, param
->get_locus (),
93 param
->get_has_ref (), param
->get_is_mut (),
94 std::unique_ptr
<AST::Pattern
> (nullptr));
96 PatternDeclaration::go (&self_pattern
, Rib::ItemType::Param
);
98 if (param
->has_type ())
100 // This shouldn't happen the parser should already error for this
101 rust_assert (!param
->get_has_ref ());
102 ResolveType::go (param
->get_type ().get ());
106 // here we implicitly make self have a type path of Self
107 std::vector
<std::unique_ptr
<AST::TypePathSegment
>> segments
;
108 segments
.push_back (std::unique_ptr
<AST::TypePathSegment
> (
109 new AST::TypePathSegment ("Self", false, param
->get_locus ())));
111 AST::TypePath
self_type_path (std::move (segments
),
112 param
->get_locus ());
113 ResolveType::go (&self_type_path
);
118 auto param
= static_cast<AST::FunctionParam
*> (p
.get ());
119 ResolveType::go (param
->get_type ().get ());
120 PatternDeclaration::go (param
->get_pattern ().get (),
121 Rib::ItemType::Param
, bindings
);
125 if (function
.has_where_clause ())
126 ResolveWhereClause::Resolve (function
.get_where_clause ());
128 // trait items have an optional body
129 if (function
.has_body ())
130 ResolveExpr::go (function
.get_definition ()->get (), path
, cpath
);
132 resolver
->get_name_scope ().pop ();
133 resolver
->get_type_scope ().pop ();
134 resolver
->get_label_scope ().pop ();
137 ResolveTraitItems::visit (AST::TraitItemType
&type
)
139 auto decl
= CanonicalPath::new_seg (type
.get_node_id (),
140 type
.get_identifier ().as_string ());
141 auto path
= prefix
.append (decl
);
142 auto cpath
= canonical_prefix
.append (decl
);
143 mappings
->insert_canonical_path (type
.get_node_id (), cpath
);
145 for (auto &bound
: type
.get_type_param_bounds ())
146 ResolveTypeBound::go (bound
.get ());
150 ResolveTraitItems::visit (AST::TraitItemConst
&constant
)
152 auto decl
= CanonicalPath::new_seg (constant
.get_node_id (),
153 constant
.get_identifier ().as_string ());
154 auto path
= prefix
.append (decl
);
155 auto cpath
= canonical_prefix
.append (decl
);
156 mappings
->insert_canonical_path (constant
.get_node_id (), cpath
);
158 ResolveType::go (constant
.get_type ().get ());
160 if (constant
.has_expr ())
161 ResolveExpr::go (constant
.get_expr ().get (), path
, cpath
);
164 ResolveItem::ResolveItem (const CanonicalPath
&prefix
,
165 const CanonicalPath
&canonical_prefix
)
166 : ResolverBase (), prefix (prefix
), canonical_prefix (canonical_prefix
)
170 ResolveItem::go (AST::Item
*item
, const CanonicalPath
&prefix
,
171 const CanonicalPath
&canonical_prefix
)
173 ResolveItem
resolver (prefix
, canonical_prefix
);
174 item
->accept_vis (resolver
);
178 ResolveItem::visit (AST::TypeAlias
&alias
)
181 = CanonicalPath::new_seg (alias
.get_node_id (),
182 alias
.get_new_type_name ().as_string ());
183 auto path
= prefix
.append (talias
);
184 auto cpath
= canonical_prefix
.append (talias
);
185 mappings
->insert_canonical_path (alias
.get_node_id (), cpath
);
187 NodeId scope_node_id
= alias
.get_node_id ();
188 resolver
->get_type_scope ().push (scope_node_id
);
190 if (alias
.has_generics ())
191 for (auto &generic
: alias
.get_generic_params ())
192 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
194 if (alias
.has_where_clause ())
195 ResolveWhereClause::Resolve (alias
.get_where_clause ());
197 ResolveType::go (alias
.get_type_aliased ().get ());
199 resolver
->get_type_scope ().pop ();
203 ResolveItem::visit (AST::Module
&module
)
205 auto mod
= CanonicalPath::new_seg (module
.get_node_id (),
206 module
.get_name ().as_string ());
207 auto path
= prefix
.append (mod
);
208 auto cpath
= canonical_prefix
.append (mod
);
209 mappings
->insert_canonical_path (module
.get_node_id (), cpath
);
211 resolve_visibility (module
.get_visibility ());
213 NodeId scope_node_id
= module
.get_node_id ();
214 resolver
->get_name_scope ().push (scope_node_id
);
215 resolver
->get_type_scope ().push (scope_node_id
);
216 resolver
->get_label_scope ().push (scope_node_id
);
217 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
218 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
219 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
221 // FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go
222 // in ResolveTopLevel::visit (AST::Module) as well as here?
223 for (auto &item
: module
.get_items ())
224 ResolveTopLevel::go (item
.get (), CanonicalPath::create_empty (), cpath
);
226 resolver
->push_new_module_scope (module
.get_node_id ());
227 for (auto &item
: module
.get_items ())
228 ResolveItem::go (item
.get (), path
, cpath
);
230 resolver
->pop_module_scope ();
232 resolver
->get_name_scope ().pop ();
233 resolver
->get_type_scope ().pop ();
234 resolver
->get_label_scope ().pop ();
238 ResolveItem::visit (AST::TupleStruct
&struct_decl
)
241 = CanonicalPath::new_seg (struct_decl
.get_node_id (),
242 struct_decl
.get_identifier ().as_string ());
243 auto path
= prefix
.append (decl
);
244 auto cpath
= canonical_prefix
.append (decl
);
245 mappings
->insert_canonical_path (struct_decl
.get_node_id (), cpath
);
247 resolve_visibility (struct_decl
.get_visibility ());
249 NodeId scope_node_id
= struct_decl
.get_node_id ();
250 resolver
->get_type_scope ().push (scope_node_id
);
252 if (struct_decl
.has_generics ())
253 for (auto &generic
: struct_decl
.get_generic_params ())
254 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
256 if (struct_decl
.has_where_clause ())
257 ResolveWhereClause::Resolve (struct_decl
.get_where_clause ());
259 for (AST::TupleField
&field
: struct_decl
.get_fields ())
261 if (field
.get_field_type ()->is_marked_for_strip ())
264 resolve_visibility (field
.get_visibility ());
266 ResolveType::go (field
.get_field_type ().get ());
269 resolver
->get_type_scope ().pop ();
273 ResolveItem::visit (AST::Enum
&enum_decl
)
275 auto decl
= CanonicalPath::new_seg (enum_decl
.get_node_id (),
276 enum_decl
.get_identifier ().as_string ());
277 auto path
= prefix
.append (decl
);
278 auto cpath
= canonical_prefix
.append (decl
);
279 mappings
->insert_canonical_path (enum_decl
.get_node_id (), cpath
);
281 resolve_visibility (enum_decl
.get_visibility ());
283 NodeId scope_node_id
= enum_decl
.get_node_id ();
284 resolver
->get_type_scope ().push (scope_node_id
);
286 if (enum_decl
.has_generics ())
287 for (auto &generic
: enum_decl
.get_generic_params ())
288 ResolveGenericParam::go (generic
.get (), prefix
, cpath
);
290 if (enum_decl
.has_where_clause ())
291 ResolveWhereClause::Resolve (enum_decl
.get_where_clause ());
293 /* The actual fields are inside the variants. */
294 for (auto &variant
: enum_decl
.get_variants ())
295 ResolveItem::go (variant
.get (), path
, cpath
);
297 resolver
->get_type_scope ().pop ();
300 /* EnumItem doesn't need to be handled, no fields. */
302 ResolveItem::visit (AST::EnumItem
&item
)
304 // Since at this point we cannot have visibilities on enum items anymore, we
305 // can skip handling them
307 auto decl
= CanonicalPath::new_seg (item
.get_node_id (),
308 item
.get_identifier ().as_string ());
309 auto path
= prefix
.append (decl
);
310 auto cpath
= canonical_prefix
.append (decl
);
311 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
315 ResolveItem::visit (AST::EnumItemTuple
&item
)
317 auto decl
= CanonicalPath::new_seg (item
.get_node_id (),
318 item
.get_identifier ().as_string ());
319 auto path
= prefix
.append (decl
);
320 auto cpath
= canonical_prefix
.append (decl
);
321 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
323 for (auto &field
: item
.get_tuple_fields ())
325 if (field
.get_field_type ()->is_marked_for_strip ())
328 ResolveType::go (field
.get_field_type ().get ());
333 ResolveItem::visit (AST::EnumItemStruct
&item
)
335 auto decl
= CanonicalPath::new_seg (item
.get_node_id (),
336 item
.get_identifier ().as_string ());
337 auto path
= prefix
.append (decl
);
338 auto cpath
= canonical_prefix
.append (decl
);
339 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
341 for (auto &field
: item
.get_struct_fields ())
343 if (field
.get_field_type ()->is_marked_for_strip ())
346 ResolveType::go (field
.get_field_type ().get ());
351 ResolveItem::visit (AST::EnumItemDiscriminant
&item
)
353 auto decl
= CanonicalPath::new_seg (item
.get_node_id (),
354 item
.get_identifier ().as_string ());
355 auto path
= prefix
.append (decl
);
356 auto cpath
= canonical_prefix
.append (decl
);
358 mappings
->insert_canonical_path (item
.get_node_id (), cpath
);
362 ResolveItem::visit (AST::StructStruct
&struct_decl
)
365 = CanonicalPath::new_seg (struct_decl
.get_node_id (),
366 struct_decl
.get_identifier ().as_string ());
367 auto path
= prefix
.append (decl
);
368 auto cpath
= canonical_prefix
.append (decl
);
369 mappings
->insert_canonical_path (struct_decl
.get_node_id (), cpath
);
371 resolve_visibility (struct_decl
.get_visibility ());
373 NodeId scope_node_id
= struct_decl
.get_node_id ();
374 resolver
->get_type_scope ().push (scope_node_id
);
376 if (struct_decl
.has_generics ())
377 for (auto &generic
: struct_decl
.get_generic_params ())
378 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
380 if (struct_decl
.has_where_clause ())
381 ResolveWhereClause::Resolve (struct_decl
.get_where_clause ());
383 for (AST::StructField
&field
: struct_decl
.get_fields ())
385 if (field
.get_field_type ()->is_marked_for_strip ())
388 resolve_visibility (field
.get_visibility ());
390 ResolveType::go (field
.get_field_type ().get ());
393 resolver
->get_type_scope ().pop ();
397 ResolveItem::visit (AST::Union
&union_decl
)
400 = CanonicalPath::new_seg (union_decl
.get_node_id (),
401 union_decl
.get_identifier ().as_string ());
402 auto path
= prefix
.append (decl
);
403 auto cpath
= canonical_prefix
.append (decl
);
404 mappings
->insert_canonical_path (union_decl
.get_node_id (), cpath
);
406 resolve_visibility (union_decl
.get_visibility ());
408 NodeId scope_node_id
= union_decl
.get_node_id ();
409 resolver
->get_type_scope ().push (scope_node_id
);
411 if (union_decl
.has_generics ())
412 for (auto &generic
: union_decl
.get_generic_params ())
413 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
415 if (union_decl
.has_where_clause ())
416 ResolveWhereClause::Resolve (union_decl
.get_where_clause ());
418 for (AST::StructField
&field
: union_decl
.get_variants ())
420 if (field
.get_field_type ()->is_marked_for_strip ())
423 ResolveType::go (field
.get_field_type ().get ());
426 resolver
->get_type_scope ().pop ();
430 ResolveItem::visit (AST::StaticItem
&var
)
432 auto decl
= CanonicalPath::new_seg (var
.get_node_id (),
433 var
.get_identifier ().as_string ());
434 auto path
= prefix
.append (decl
);
435 auto cpath
= canonical_prefix
.append (decl
);
436 mappings
->insert_canonical_path (var
.get_node_id (), cpath
);
438 ResolveType::go (var
.get_type ().get ());
439 ResolveExpr::go (var
.get_expr ().get (), path
, cpath
);
443 ResolveItem::visit (AST::ConstantItem
&constant
)
445 auto decl
= CanonicalPath::new_seg (constant
.get_node_id (),
446 constant
.get_identifier ());
447 auto path
= prefix
.append (decl
);
448 auto cpath
= canonical_prefix
.append (decl
);
449 mappings
->insert_canonical_path (constant
.get_node_id (), cpath
);
451 resolve_visibility (constant
.get_visibility ());
453 ResolveType::go (constant
.get_type ().get ());
454 ResolveExpr::go (constant
.get_expr ().get (), path
, cpath
);
458 ResolveItem::visit (AST::Function
&function
)
461 = CanonicalPath::new_seg (function
.get_node_id (),
462 function
.get_function_name ().as_string ());
463 auto path
= prefix
.append (decl
);
464 auto cpath
= canonical_prefix
.append (decl
);
466 mappings
->insert_canonical_path (function
.get_node_id (), cpath
);
468 resolve_visibility (function
.get_visibility ());
470 NodeId scope_node_id
= function
.get_node_id ();
471 resolver
->get_name_scope ().push (scope_node_id
);
472 resolver
->get_type_scope ().push (scope_node_id
);
473 resolver
->get_label_scope ().push (scope_node_id
);
474 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
475 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
476 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
478 if (function
.has_generics ())
479 for (auto &generic
: function
.get_generic_params ())
480 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
482 // resolve any where clause items
483 if (function
.has_where_clause ())
484 ResolveWhereClause::Resolve (function
.get_where_clause ());
486 if (function
.has_return_type ())
487 ResolveType::go (function
.get_return_type ().get ());
489 if (function
.has_self_param ())
491 // self turns into (self: Self) as a function param
492 std::unique_ptr
<AST::Param
> &s_param
= function
.get_self_param ();
493 auto self_param
= static_cast<AST::SelfParam
*> (s_param
.get ());
495 // FIXME: which location should be used for Rust::Identifier `self`?
496 AST::IdentifierPattern
self_pattern (
497 self_param
->get_node_id (), {"self"}, self_param
->get_locus (),
498 self_param
->get_has_ref (), self_param
->get_is_mut (),
499 std::unique_ptr
<AST::Pattern
> (nullptr));
500 PatternDeclaration::go (&self_pattern
, Rib::ItemType::Param
);
502 if (self_param
->has_type ())
504 // This shouldn't happen the parser should already error for this
505 rust_assert (!self_param
->get_has_ref ());
506 ResolveType::go (self_param
->get_type ().get ());
510 // here we implicitly make self have a type path of Self
511 std::vector
<std::unique_ptr
<AST::TypePathSegment
>> segments
;
512 segments
.push_back (std::unique_ptr
<AST::TypePathSegment
> (
513 new AST::TypePathSegment ("Self", false,
514 self_param
->get_locus ())));
516 AST::TypePath
self_type_path (std::move (segments
),
517 self_param
->get_locus ());
518 ResolveType::go (&self_type_path
);
522 std::vector
<PatternBinding
> bindings
523 = {PatternBinding (PatternBoundCtx::Product
, std::set
<Identifier
> ())};
525 // we make a new scope so the names of parameters are resolved and shadowed
527 for (auto &p
: function
.get_function_params ())
529 if (p
->is_variadic ())
531 auto param
= static_cast<AST::VariadicParam
*> (p
.get ());
532 if (param
->has_pattern ())
533 PatternDeclaration::go (param
->get_pattern ().get (),
534 Rib::ItemType::Param
, bindings
);
536 else if (p
->is_self ())
538 auto param
= static_cast<AST::SelfParam
*> (p
.get ());
539 if (param
->has_type ())
540 ResolveType::go (param
->get_type ().get ());
544 auto param
= static_cast<AST::FunctionParam
*> (p
.get ());
545 ResolveType::go (param
->get_type ().get ());
546 PatternDeclaration::go (param
->get_pattern ().get (),
547 Rib::ItemType::Param
, bindings
);
551 // resolve the function body
552 ResolveExpr::go (function
.get_definition ()->get (), path
, cpath
);
554 resolver
->get_name_scope ().pop ();
555 resolver
->get_type_scope ().pop ();
556 resolver
->get_label_scope ().pop ();
560 ResolveItem::visit (AST::InherentImpl
&impl_block
)
562 NodeId scope_node_id
= impl_block
.get_node_id ();
563 resolver
->get_name_scope ().push (scope_node_id
);
564 resolver
->get_type_scope ().push (scope_node_id
);
565 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
566 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
568 resolve_visibility (impl_block
.get_visibility ());
570 if (impl_block
.has_generics ())
571 for (auto &generic
: impl_block
.get_generic_params ())
572 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
574 // resolve any where clause items
575 if (impl_block
.has_where_clause ())
576 ResolveWhereClause::Resolve (impl_block
.get_where_clause ());
578 // FIXME this needs to be protected behind nominal type-checks see:
579 // rustc --explain E0118
581 ResolveType::go (impl_block
.get_type ().get ());
584 CanonicalPath self_cpath
= CanonicalPath::create_empty ();
585 bool ok
= ResolveTypeToCanonicalPath::go (impl_block
.get_type ().get (),
588 rust_debug ("AST::InherentImpl resolve Self: {%s}",
589 self_cpath
.get ().c_str ());
591 CanonicalPath impl_type
= self_cpath
;
592 CanonicalPath impl_type_seg
593 = CanonicalPath::inherent_impl_seg (impl_block
.get_node_id (), impl_type
);
594 CanonicalPath impl_prefix
= prefix
.append (impl_type_seg
);
596 // see https://godbolt.org/z/a3vMbsT6W
597 CanonicalPath cpath
= CanonicalPath::create_empty ();
598 if (canonical_prefix
.size () <= 1)
604 std::string seg_buf
= "<impl " + self_cpath
.get () + ">";
606 = CanonicalPath::new_seg (impl_block
.get_node_id (), seg_buf
);
607 cpath
= canonical_prefix
.append (seg
);
613 = CanonicalPath::get_big_self (impl_block
.get_type ()->get_node_id ());
615 resolver
->get_type_scope ().insert (Self
,
616 impl_block
.get_type ()->get_node_id (),
617 impl_block
.get_type ()->get_locus ());
619 for (auto &impl_item
: impl_block
.get_impl_items ())
622 "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
623 impl_prefix
.get ().c_str (), cpath
.get ().c_str ());
624 resolve_impl_item (impl_item
.get (), impl_prefix
, cpath
);
627 resolver
->get_type_scope ().peek ()->clear_name (
628 Self
, impl_block
.get_type ()->get_node_id ());
630 resolver
->get_type_scope ().pop ();
631 resolver
->get_name_scope ().pop ();
635 ResolveItem::visit (AST::TraitImpl
&impl_block
)
637 NodeId scope_node_id
= impl_block
.get_node_id ();
639 resolve_visibility (impl_block
.get_visibility ());
641 resolver
->get_name_scope ().push (scope_node_id
);
642 resolver
->get_type_scope ().push (scope_node_id
);
643 resolver
->get_label_scope ().push (scope_node_id
);
644 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
645 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
646 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
648 if (impl_block
.has_generics ())
649 for (auto &generic
: impl_block
.get_generic_params ())
650 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
652 // resolve any where clause items
653 if (impl_block
.has_where_clause ())
654 ResolveWhereClause::Resolve (impl_block
.get_where_clause ());
656 // CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
657 NodeId trait_resolved_node
= ResolveType::go (&impl_block
.get_trait_path ());
658 if (trait_resolved_node
== UNKNOWN_NODEID
)
660 resolver
->get_name_scope ().pop ();
661 resolver
->get_type_scope ().pop ();
662 resolver
->get_label_scope ().pop ();
666 // CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
667 NodeId type_resolved_node
= ResolveType::go (impl_block
.get_type ().get ());
668 if (type_resolved_node
== UNKNOWN_NODEID
)
670 resolver
->get_name_scope ().pop ();
671 resolver
->get_type_scope ().pop ();
672 resolver
->get_label_scope ().pop ();
678 CanonicalPath canonical_trait_type
= CanonicalPath::create_empty ();
679 ok
= ResolveTypeToCanonicalPath::go (&impl_block
.get_trait_path (),
680 canonical_trait_type
);
683 rust_debug ("AST::TraitImpl resolve trait type: {%s}",
684 canonical_trait_type
.get ().c_str ());
686 CanonicalPath canonical_impl_type
= CanonicalPath::create_empty ();
687 ok
= ResolveTypeToCanonicalPath::go (impl_block
.get_type ().get (),
688 canonical_impl_type
);
691 rust_debug ("AST::TraitImpl resolve self: {%s}",
692 canonical_impl_type
.get ().c_str ());
695 CanonicalPath impl_type_seg
= canonical_impl_type
;
696 CanonicalPath trait_type_seg
= canonical_trait_type
;
697 CanonicalPath projection
698 = CanonicalPath::trait_impl_projection_seg (impl_block
.get_node_id (),
699 trait_type_seg
, impl_type_seg
);
700 CanonicalPath impl_prefix
= prefix
.append (projection
);
702 // setup canonical-path
703 CanonicalPath canonical_projection
704 = CanonicalPath::trait_impl_projection_seg (impl_block
.get_node_id (),
705 canonical_trait_type
,
706 canonical_impl_type
);
707 CanonicalPath cpath
= CanonicalPath::create_empty ();
708 if (canonical_prefix
.size () <= 1)
710 cpath
= canonical_projection
;
714 std::string projection_str
= canonical_projection
.get ();
716 = "<impl " + projection_str
.substr (1, projection_str
.size () - 2)
719 = CanonicalPath::new_seg (impl_block
.get_node_id (), seg_buf
);
720 cpath
= canonical_prefix
.append (seg
);
723 // DONE setup canonical-path
726 = CanonicalPath::get_big_self (impl_block
.get_type ()->get_node_id ());
728 resolver
->get_type_scope ().insert (Self
,
729 impl_block
.get_type ()->get_node_id (),
730 impl_block
.get_type ()->get_locus ());
732 for (auto &impl_item
: impl_block
.get_impl_items ())
735 "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
736 impl_prefix
.get ().c_str (), cpath
.get ().c_str ());
737 resolve_impl_item (impl_item
.get (), impl_prefix
, cpath
);
740 Rib
*r
= resolver
->get_type_scope ().peek ();
741 r
->clear_name (Self
, impl_block
.get_type ()->get_node_id ());
743 resolver
->get_name_scope ().pop ();
744 resolver
->get_type_scope ().pop ();
745 resolver
->get_label_scope ().pop ();
749 ResolveItem::visit (AST::Trait
&trait
)
751 NodeId scope_node_id
= trait
.get_node_id ();
753 resolve_visibility (trait
.get_visibility ());
755 resolver
->get_name_scope ().push (scope_node_id
);
756 resolver
->get_type_scope ().push (scope_node_id
);
757 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
758 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
760 // we need to inject an implicit self TypeParam here
761 // FIXME: which location should be used for Rust::Identifier `Self`?
762 AST::TypeParam
*implicit_self
763 = new AST::TypeParam ({"Self"}, trait
.get_locus ());
764 trait
.insert_implict_self (
765 std::unique_ptr
<AST::GenericParam
> (implicit_self
));
766 CanonicalPath Self
= CanonicalPath::get_big_self (trait
.get_node_id ());
768 for (auto &generic
: trait
.get_generic_params ())
769 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
771 // Self is an implicit TypeParam so lets mark it as such
772 resolver
->get_type_scope ().append_reference_for_def (
773 Self
.get_node_id (), implicit_self
->get_node_id ());
775 if (trait
.has_type_param_bounds ())
777 for (auto &bound
: trait
.get_type_param_bounds ())
779 ResolveTypeBound::go (bound
.get ());
783 // resolve any where clause items
784 if (trait
.has_where_clause ())
785 ResolveWhereClause::Resolve (trait
.get_where_clause ());
788 CanonicalPath path
= CanonicalPath::create_empty ();
789 CanonicalPath cpath
= CanonicalPath::create_empty ();
792 for (auto &item
: trait
.get_trait_items ())
794 ResolveTraitItems::go (item
.get (), path
, cpath
);
797 resolver
->get_type_scope ().pop ();
798 resolver
->get_name_scope ().pop ();
802 ResolveItem::visit (AST::ExternBlock
&extern_block
)
804 resolve_visibility (extern_block
.get_visibility ());
806 for (auto &item
: extern_block
.get_extern_items ())
808 resolve_extern_item (item
.get ());
813 ResolveItem::resolve_impl_item (AST::AssociatedItem
*item
,
814 const CanonicalPath
&prefix
,
815 const CanonicalPath
&canonical_prefix
)
817 ResolveImplItems::go (item
, prefix
, canonical_prefix
);
821 ResolveItem::resolve_extern_item (AST::ExternalItem
*item
)
823 ResolveExternItem::go (item
, prefix
, canonical_prefix
);
827 flatten_glob (const AST::UseTreeGlob
&glob
,
828 std::vector
<AST::SimplePath
> &paths
);
830 flatten_rebind (const AST::UseTreeRebind
&glob
,
831 std::vector
<AST::SimplePath
> &paths
);
833 flatten_list (const AST::UseTreeList
&glob
,
834 std::vector
<AST::SimplePath
> &paths
);
837 flatten (const AST::UseTree
*tree
, std::vector
<AST::SimplePath
> &paths
)
839 switch (tree
->get_kind ())
841 case AST::UseTree::Glob
: {
842 auto glob
= static_cast<const AST::UseTreeGlob
*> (tree
);
843 flatten_glob (*glob
, paths
);
846 case AST::UseTree::Rebind
: {
847 auto rebind
= static_cast<const AST::UseTreeRebind
*> (tree
);
848 flatten_rebind (*rebind
, paths
);
851 case AST::UseTree::List
: {
852 auto list
= static_cast<const AST::UseTreeList
*> (tree
);
853 flatten_list (*list
, paths
);
861 flatten_glob (const AST::UseTreeGlob
&glob
, std::vector
<AST::SimplePath
> &paths
)
863 if (glob
.has_path ())
864 paths
.emplace_back (glob
.get_path ());
868 flatten_rebind (const AST::UseTreeRebind
&rebind
,
869 std::vector
<AST::SimplePath
> &paths
)
871 auto path
= rebind
.get_path ();
872 if (rebind
.has_path ())
873 paths
.emplace_back (path
);
875 // FIXME: Do we want to emplace the rebind here as well?
876 if (rebind
.has_identifier ())
878 auto rebind_path
= path
;
879 auto new_seg
= rebind
.get_identifier ();
881 // Add the identifier as a new path
882 rebind_path
.get_segments ().back ()
883 = AST::SimplePathSegment (new_seg
.as_string (), UNDEF_LOCATION
);
885 paths
.emplace_back (rebind_path
);
890 flatten_list (const AST::UseTreeList
&list
, std::vector
<AST::SimplePath
> &paths
)
892 auto prefix
= AST::SimplePath::create_empty ();
893 if (list
.has_path ())
894 prefix
= list
.get_path ();
896 for (const auto &tree
: list
.get_trees ())
898 auto sub_paths
= std::vector
<AST::SimplePath
> ();
899 flatten (tree
.get (), sub_paths
);
901 for (auto &sub_path
: sub_paths
)
903 auto new_path
= prefix
;
904 std::copy (sub_path
.get_segments ().begin (),
905 sub_path
.get_segments ().end (),
906 std::back_inserter (new_path
.get_segments ()));
908 paths
.emplace_back (new_path
);
914 * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve.
916 * Given the following use declarations:
918 * use some::path::to_resolve; #1
919 * use some::path::to_glob::*; #2
920 * use some::path::{one, two}; #2
923 * In the first case, we simply want to return a vector with a single
925 * [some::path::to_resolve]
927 * In the second case, we want to resolve the glob's "origin path":
928 * [some::path::to_glob]
930 * Finally in the third case, we want to create two SimplePaths to resolve:
931 * [some::path::one, some::path::two]
933 static std::vector
<AST::SimplePath
>
934 flatten_use_dec_to_paths (const AST::UseDeclaration
&use_item
)
936 auto paths
= std::vector
<AST::SimplePath
> ();
938 const auto &tree
= use_item
.get_tree ();
939 flatten (tree
.get (), paths
);
945 ResolveItem::visit (AST::UseDeclaration
&use_item
)
947 std::vector
<AST::SimplePath
> to_resolve
= flatten_use_dec_to_paths (use_item
);
949 // FIXME: I think this does not actually resolve glob use-decls and is going
950 // the wrong way about it. RFC #1560 specifies the following:
952 // > When we find a glob import, we have to record a 'back link', so that when
953 // a public name is added for the supplying module, we can add it for the
956 // Which is the opposite of what we're doing if I understand correctly?
958 NodeId current_module
= resolver
->peek_current_module_scope ();
959 for (auto &path
: to_resolve
)
961 rust_debug ("resolving use-decl path: [%s]", path
.as_string ().c_str ());
962 NodeId resolved_node_id
= ResolvePath::go (&path
);
963 bool ok
= resolved_node_id
!= UNKNOWN_NODEID
;
967 const AST::SimplePathSegment
&final_seg
= path
.get_segments ().back ();
970 = CanonicalPath::new_seg (resolved_node_id
, final_seg
.as_string ());
971 mappings
->insert_module_child_item (current_module
, decl
);
973 resolver
->get_type_scope ().insert (decl
, resolved_node_id
,
975 Rib::ItemType::Type
);
976 rust_debug ("use-decl rexporting: [%s]", decl
.get ().c_str ());
980 ResolveImplItems::ResolveImplItems (const CanonicalPath
&prefix
,
981 const CanonicalPath
&canonical_prefix
)
982 : ResolveItem (prefix
, canonical_prefix
)
986 ResolveImplItems::go (AST::AssociatedItem
*item
, const CanonicalPath
&prefix
,
987 const CanonicalPath
&canonical_prefix
)
989 if (item
->is_marked_for_strip ())
992 ResolveImplItems
resolver (prefix
, canonical_prefix
);
993 item
->accept_vis (resolver
);
997 ResolveImplItems::visit (AST::TypeAlias
&alias
)
999 ResolveItem::visit (alias
);
1001 resolve_visibility (alias
.get_visibility ());
1003 // FIXME this stops the erronious unused decls which will be fixed later on
1004 resolver
->get_type_scope ().append_reference_for_def (alias
.get_node_id (),
1005 alias
.get_node_id ());
1009 ResolveExternItem::go (AST::ExternalItem
*item
, const CanonicalPath
&prefix
,
1010 const CanonicalPath
&canonical_prefix
)
1012 ResolveExternItem
resolver (prefix
, canonical_prefix
);
1013 item
->accept_vis (resolver
);
1017 ResolveExternItem::visit (AST::ExternalFunctionItem
&function
)
1019 NodeId scope_node_id
= function
.get_node_id ();
1020 auto decl
= CanonicalPath::new_seg (function
.get_node_id (),
1021 function
.get_identifier ().as_string ());
1022 auto path
= prefix
.append (decl
);
1023 auto cpath
= canonical_prefix
.append (decl
);
1025 mappings
->insert_canonical_path (function
.get_node_id (), cpath
);
1027 resolve_visibility (function
.get_visibility ());
1029 resolver
->get_name_scope ().push (scope_node_id
);
1030 resolver
->get_type_scope ().push (scope_node_id
);
1031 resolver
->get_label_scope ().push (scope_node_id
);
1032 resolver
->push_new_name_rib (resolver
->get_name_scope ().peek ());
1033 resolver
->push_new_type_rib (resolver
->get_type_scope ().peek ());
1034 resolver
->push_new_label_rib (resolver
->get_type_scope ().peek ());
1036 // resolve the generics
1037 if (function
.has_generics ())
1038 for (auto &generic
: function
.get_generic_params ())
1039 ResolveGenericParam::go (generic
.get (), prefix
, canonical_prefix
);
1041 if (function
.has_return_type ())
1042 ResolveType::go (function
.get_return_type ().get ());
1044 // we make a new scope so the names of parameters are resolved and shadowed
1046 for (auto ¶m
: function
.get_function_params ())
1047 if (!param
.is_variadic ())
1048 ResolveType::go (param
.get_type ().get ());
1051 resolver
->get_name_scope ().pop ();
1052 resolver
->get_type_scope ().pop ();
1053 resolver
->get_label_scope ().pop ();
1057 ResolveExternItem::visit (AST::ExternalStaticItem
&item
)
1059 resolve_visibility (item
.get_visibility ());
1061 ResolveType::go (item
.get_type ().get ());
1064 } // namespace Resolver
1069 namespace selftest
{
1072 rust_flatten_nested_glob (void)
1074 auto foo
= Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION
);
1075 auto bar
= Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION
);
1076 auto foobar
= Rust::AST::SimplePath ({foo
, bar
});
1079 = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED
,
1080 foobar
, UNDEF_LOCATION
);
1082 auto paths
= std::vector
<Rust::AST::SimplePath
> ();
1083 Rust::Resolver::flatten_glob (glob
, paths
);
1085 ASSERT_TRUE (!paths
.empty ());
1086 ASSERT_EQ (paths
.size (), 1);
1087 ASSERT_EQ (paths
[0].get_segments ()[0].as_string (), "foo");
1088 ASSERT_EQ (paths
[0].get_segments ()[1].as_string (), "bar");
1092 rust_flatten_glob (void)
1094 auto frob
= Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION
);
1097 = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED
,
1098 frob
, UNDEF_LOCATION
);
1100 auto paths
= std::vector
<Rust::AST::SimplePath
> ();
1101 Rust::Resolver::flatten_glob (glob
, paths
);
1103 ASSERT_TRUE (!paths
.empty ());
1104 ASSERT_EQ (paths
.size (), 1);
1105 ASSERT_EQ (paths
[0], "frobulator");
1109 rust_flatten_rebind_none (void)
1111 auto foo
= Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION
);
1112 auto bar
= Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION
);
1113 auto foobar
= Rust::AST::SimplePath ({foo
, bar
});
1115 auto rebind
= Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE
,
1116 foobar
, UNDEF_LOCATION
);
1118 auto paths
= std::vector
<Rust::AST::SimplePath
> ();
1119 Rust::Resolver::flatten_rebind (rebind
, paths
);
1121 ASSERT_TRUE (!paths
.empty ());
1122 ASSERT_EQ (paths
.size (), 1);
1123 ASSERT_EQ (paths
[0].get_segments ()[0].as_string (), "foo");
1124 ASSERT_EQ (paths
[0].get_segments ()[1].as_string (), "bar");
1128 rust_flatten_rebind (void)
1130 auto frob
= Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION
);
1132 auto rebind
= Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER
,
1133 frob
, UNDEF_LOCATION
, {"saindoux"});
1135 auto paths
= std::vector
<Rust::AST::SimplePath
> ();
1136 Rust::Resolver::flatten_rebind (rebind
, paths
);
1138 ASSERT_TRUE (!paths
.empty ());
1139 ASSERT_EQ (paths
.size (), 2);
1140 ASSERT_EQ (paths
[0], "frobulator");
1141 ASSERT_EQ (paths
[1], "saindoux");
1145 rust_flatten_rebind_nested (void)
1147 auto foo
= Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION
);
1148 auto bar
= Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION
);
1149 auto baz
= Rust::AST::SimplePathSegment ("baz", UNDEF_LOCATION
);
1151 auto foo_bar_baz
= Rust::AST::SimplePath ({foo
, bar
, baz
});
1154 = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER
,
1155 foo_bar_baz
, UNDEF_LOCATION
, {"saindoux"});
1157 auto paths
= std::vector
<Rust::AST::SimplePath
> ();
1158 Rust::Resolver::flatten_rebind (rebind
, paths
);
1160 ASSERT_TRUE (!paths
.empty ());
1161 ASSERT_EQ (paths
.size (), 2);
1162 ASSERT_EQ (paths
[0].get_segments ()[0].as_string (), "foo");
1163 ASSERT_EQ (paths
[0].get_segments ()[1].as_string (), "bar");
1164 ASSERT_EQ (paths
[0].get_segments ()[2].as_string (), "baz");
1165 ASSERT_EQ (paths
[1].get_segments ()[0].as_string (), "foo");
1166 ASSERT_EQ (paths
[1].get_segments ()[1].as_string (), "bar");
1167 ASSERT_EQ (paths
[1].get_segments ()[2].as_string (), "saindoux");
1171 rust_flatten_list (void)
1173 auto foo
= Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION
);
1174 auto bar
= Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION
);
1175 auto foo_bar
= Rust::AST::SimplePath ({foo
, bar
});
1177 auto baz
= Rust::AST::SimplePath::from_str ("baz", UNDEF_LOCATION
);
1178 auto bul
= Rust::AST::SimplePath::from_str ("bul", UNDEF_LOCATION
);
1180 // use foo::bar::{baz, bul};
1182 auto use0
= std::unique_ptr
<Rust::AST::UseTree
> (
1183 new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE
, baz
,
1185 auto use1
= std::unique_ptr
<Rust::AST::UseTree
> (
1186 new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE
, bul
,
1189 auto uses
= std::vector
<std::unique_ptr
<Rust::AST::UseTree
>> ();
1190 uses
.emplace_back (std::move (use0
));
1191 uses
.emplace_back (std::move (use1
));
1194 = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED
, foo_bar
,
1195 std::move (uses
), UNDEF_LOCATION
);
1197 auto paths
= std::vector
<Rust::AST::SimplePath
> ();
1198 Rust::Resolver::flatten_list (list
, paths
);
1200 ASSERT_TRUE (!paths
.empty ());
1201 ASSERT_EQ (paths
.size (), 2);
1202 ASSERT_EQ (paths
[0].get_segments ()[0].as_string (), "foo");
1203 ASSERT_EQ (paths
[0].get_segments ()[1].as_string (), "bar");
1204 ASSERT_EQ (paths
[0].get_segments ()[2].as_string (), "baz");
1205 ASSERT_EQ (paths
[1].get_segments ()[0].as_string (), "foo");
1206 ASSERT_EQ (paths
[1].get_segments ()[1].as_string (), "bar");
1207 ASSERT_EQ (paths
[1].get_segments ()[2].as_string (), "bul");
1211 rust_use_dec_flattening (void)
1213 rust_flatten_glob ();
1214 rust_flatten_nested_glob ();
1215 rust_flatten_rebind_none ();
1216 rust_flatten_rebind ();
1217 rust_flatten_rebind_nested ();
1218 rust_flatten_list ();
1222 rust_simple_path_resolve_test (void)
1224 rust_use_dec_flattening ();
1227 } // namespace selftest
1229 #endif // CHECKING_P