LCOV - code coverage report
Current view: top level - gcc/rust/resolve - rust-ast-resolve-item.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 20.7 % 695 144
Test Date: 2025-08-30 13:27:53 Functions: 27.7 % 47 13
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       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
       8                 :             : // version.
       9                 :             : 
      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
      13                 :             : // for more details.
      14                 :             : 
      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/>.
      18                 :             : 
      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"
      25                 :             : 
      26                 :             : #include "rust-item.h"
      27                 :             : #include "selftest.h"
      28                 :             : 
      29                 :             : namespace Rust {
      30                 :             : namespace Resolver {
      31                 :             : 
      32                 :           0 : ResolveTraitItems::ResolveTraitItems (const CanonicalPath &prefix,
      33                 :           0 :                                       const CanonicalPath &canonical_prefix)
      34                 :           0 :   : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
      35                 :           0 : {}
      36                 :             : 
      37                 :             : void
      38                 :           0 : ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix,
      39                 :             :                        const CanonicalPath &canonical_prefix)
      40                 :             : {
      41                 :           0 :   if (item->is_marked_for_strip ())
      42                 :           0 :     return;
      43                 :             : 
      44                 :           0 :   ResolveTraitItems resolver (prefix, canonical_prefix);
      45                 :           0 :   item->accept_vis (resolver);
      46                 :           0 : }
      47                 :             : 
      48                 :             : void
      49                 :           0 : ResolveTraitItems::visit (AST::Function &function)
      50                 :             : {
      51                 :           0 :   auto decl
      52                 :           0 :     = CanonicalPath::new_seg (function.get_node_id (),
      53                 :           0 :                               function.get_function_name ().as_string ());
      54                 :           0 :   auto path = prefix.append (decl);
      55                 :           0 :   auto cpath = canonical_prefix.append (decl);
      56                 :           0 :   mappings.insert_canonical_path (function.get_node_id (), cpath);
      57                 :             : 
      58                 :           0 :   NodeId scope_node_id = function.get_node_id ();
      59                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
      60                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
      61                 :           0 :   resolver->get_label_scope ().push (scope_node_id);
      62                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
      63                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
      64                 :           0 :   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
      65                 :             : 
      66                 :           0 :   if (function.has_generics ())
      67                 :           0 :     ResolveGenericParams::go (function.get_generic_params (), prefix,
      68                 :             :                               canonical_prefix);
      69                 :             : 
      70                 :           0 :   if (function.has_return_type ())
      71                 :           0 :     ResolveType::go (function.get_return_type ());
      72                 :             : 
      73                 :             :   // self turns into (self: Self) as a function param
      74                 :           0 :   std::vector<PatternBinding> bindings
      75                 :           0 :     = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
      76                 :             : 
      77                 :             :   // we make a new scope so the names of parameters are resolved and shadowed
      78                 :             :   // correctly
      79                 :           0 :   for (auto &p : function.get_function_params ())
      80                 :             :     {
      81                 :           0 :       if (p->is_variadic ())
      82                 :             :         {
      83                 :           0 :           auto param = static_cast<AST::VariadicParam &> (*p);
      84                 :           0 :           PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
      85                 :             :                                   bindings);
      86                 :           0 :         }
      87                 :           0 :       else if (p->is_self ())
      88                 :             :         {
      89                 :           0 :           auto &param = static_cast<AST::SelfParam &> (*p);
      90                 :             :           // FIXME: which location should be used for Rust::Identifier `self`?
      91                 :           0 :           AST::IdentifierPattern self_pattern (
      92                 :           0 :             param.get_node_id (), {"self"}, param.get_locus (),
      93                 :           0 :             param.get_has_ref (), param.get_is_mut (),
      94                 :           0 :             std::unique_ptr<AST::Pattern> (nullptr));
      95                 :             : 
      96                 :           0 :           PatternDeclaration::go (self_pattern, Rib::ItemType::Param);
      97                 :             : 
      98                 :           0 :           if (param.has_type ())
      99                 :             :             {
     100                 :             :               // This shouldn't happen the parser should already error for this
     101                 :           0 :               rust_assert (!param.get_has_ref ());
     102                 :           0 :               ResolveType::go (param.get_type ());
     103                 :             :             }
     104                 :             :           else
     105                 :             :             {
     106                 :             :               // here we implicitly make self have a type path of Self
     107                 :           0 :               std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
     108                 :           0 :               segments.push_back (std::unique_ptr<AST::TypePathSegment> (
     109                 :           0 :                 new AST::TypePathSegment ("Self", false, param.get_locus ())));
     110                 :             : 
     111                 :           0 :               AST::TypePath self_type_path (std::move (segments),
     112                 :           0 :                                             param.get_locus ());
     113                 :           0 :               ResolveType::go (self_type_path);
     114                 :           0 :             }
     115                 :           0 :         }
     116                 :             :       else
     117                 :             :         {
     118                 :           0 :           auto &param = static_cast<AST::FunctionParam &> (*p);
     119                 :           0 :           ResolveType::go (param.get_type ());
     120                 :           0 :           PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
     121                 :             :                                   bindings);
     122                 :             :         }
     123                 :             :     }
     124                 :             : 
     125                 :           0 :   if (function.has_where_clause ())
     126                 :           0 :     ResolveWhereClause::Resolve (function.get_where_clause ());
     127                 :             : 
     128                 :             :   // trait items have an optional body
     129                 :           0 :   if (function.has_body ())
     130                 :           0 :     ResolveExpr::go (*function.get_definition ().value (), path, cpath);
     131                 :             : 
     132                 :           0 :   resolver->get_name_scope ().pop ();
     133                 :           0 :   resolver->get_type_scope ().pop ();
     134                 :           0 :   resolver->get_label_scope ().pop ();
     135                 :           0 : }
     136                 :             : void
     137                 :           0 : ResolveTraitItems::visit (AST::TraitItemType &type)
     138                 :             : {
     139                 :           0 :   auto decl = CanonicalPath::new_seg (type.get_node_id (),
     140                 :           0 :                                       type.get_identifier ().as_string ());
     141                 :           0 :   auto path = prefix.append (decl);
     142                 :           0 :   auto cpath = canonical_prefix.append (decl);
     143                 :           0 :   mappings.insert_canonical_path (type.get_node_id (), cpath);
     144                 :             : 
     145                 :           0 :   for (auto &bound : type.get_type_param_bounds ())
     146                 :           0 :     ResolveTypeBound::go (*bound);
     147                 :           0 : }
     148                 :             : 
     149                 :             : void
     150                 :           0 : ResolveTraitItems::visit (AST::TraitItemConst &constant)
     151                 :             : {
     152                 :           0 :   auto decl = CanonicalPath::new_seg (constant.get_node_id (),
     153                 :           0 :                                       constant.get_identifier ().as_string ());
     154                 :           0 :   auto path = prefix.append (decl);
     155                 :           0 :   auto cpath = canonical_prefix.append (decl);
     156                 :           0 :   mappings.insert_canonical_path (constant.get_node_id (), cpath);
     157                 :             : 
     158                 :           0 :   ResolveType::go (constant.get_type ());
     159                 :             : 
     160                 :           0 :   if (constant.has_expr ())
     161                 :           0 :     ResolveExpr::go (constant.get_expr (), path, cpath);
     162                 :           0 : }
     163                 :             : 
     164                 :           0 : ResolveItem::ResolveItem (const CanonicalPath &prefix,
     165                 :           0 :                           const CanonicalPath &canonical_prefix)
     166                 :           0 :   : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
     167                 :           0 : {}
     168                 :             : 
     169                 :             : void
     170                 :           0 : ResolveItem::go (AST::Item &item, const CanonicalPath &prefix,
     171                 :             :                  const CanonicalPath &canonical_prefix)
     172                 :             : {
     173                 :           0 :   ResolveItem resolver (prefix, canonical_prefix);
     174                 :           0 :   item.accept_vis (resolver);
     175                 :           0 : }
     176                 :             : 
     177                 :             : void
     178                 :           0 : ResolveItem::visit (AST::TypeAlias &alias)
     179                 :             : {
     180                 :           0 :   auto talias
     181                 :           0 :     = CanonicalPath::new_seg (alias.get_node_id (),
     182                 :           0 :                               alias.get_new_type_name ().as_string ());
     183                 :           0 :   auto path = prefix.append (talias);
     184                 :           0 :   auto cpath = canonical_prefix.append (talias);
     185                 :           0 :   mappings.insert_canonical_path (alias.get_node_id (), cpath);
     186                 :             : 
     187                 :           0 :   NodeId scope_node_id = alias.get_node_id ();
     188                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     189                 :             : 
     190                 :           0 :   if (alias.has_generics ())
     191                 :           0 :     ResolveGenericParams::go (alias.get_generic_params (), prefix,
     192                 :             :                               canonical_prefix);
     193                 :             : 
     194                 :           0 :   if (alias.has_where_clause ())
     195                 :           0 :     ResolveWhereClause::Resolve (alias.get_where_clause ());
     196                 :             : 
     197                 :           0 :   ResolveType::go (alias.get_type_aliased ());
     198                 :             : 
     199                 :           0 :   resolver->get_type_scope ().pop ();
     200                 :           0 : }
     201                 :             : 
     202                 :             : void
     203                 :           0 : ResolveItem::visit (AST::Module &module)
     204                 :             : {
     205                 :           0 :   auto mod = CanonicalPath::new_seg (module.get_node_id (),
     206                 :           0 :                                      module.get_name ().as_string ());
     207                 :           0 :   auto path = prefix.append (mod);
     208                 :           0 :   auto cpath = canonical_prefix.append (mod);
     209                 :           0 :   mappings.insert_canonical_path (module.get_node_id (), cpath);
     210                 :             : 
     211                 :           0 :   resolve_visibility (module.get_visibility ());
     212                 :             : 
     213                 :           0 :   NodeId scope_node_id = module.get_node_id ();
     214                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
     215                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     216                 :           0 :   resolver->get_label_scope ().push (scope_node_id);
     217                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
     218                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
     219                 :           0 :   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
     220                 :             : 
     221                 :             :   // FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go
     222                 :             :   // in ResolveTopLevel::visit (AST::Module) as well as here?
     223                 :           0 :   for (auto &item : module.get_items ())
     224                 :           0 :     ResolveTopLevel::go (*item, CanonicalPath::create_empty (), cpath);
     225                 :             : 
     226                 :           0 :   resolver->push_new_module_scope (module.get_node_id ());
     227                 :           0 :   for (auto &item : module.get_items ())
     228                 :           0 :     ResolveItem::go (*item, path, cpath);
     229                 :             : 
     230                 :           0 :   resolver->pop_module_scope ();
     231                 :             : 
     232                 :           0 :   resolver->get_name_scope ().pop ();
     233                 :           0 :   resolver->get_type_scope ().pop ();
     234                 :           0 :   resolver->get_label_scope ().pop ();
     235                 :           0 : }
     236                 :             : 
     237                 :             : void
     238                 :           0 : ResolveItem::visit (AST::TupleStruct &struct_decl)
     239                 :             : {
     240                 :           0 :   auto decl
     241                 :           0 :     = CanonicalPath::new_seg (struct_decl.get_node_id (),
     242                 :           0 :                               struct_decl.get_identifier ().as_string ());
     243                 :           0 :   auto path = prefix.append (decl);
     244                 :           0 :   auto cpath = canonical_prefix.append (decl);
     245                 :           0 :   mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
     246                 :             : 
     247                 :           0 :   resolve_visibility (struct_decl.get_visibility ());
     248                 :             : 
     249                 :           0 :   NodeId scope_node_id = struct_decl.get_node_id ();
     250                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     251                 :             : 
     252                 :           0 :   if (struct_decl.has_generics ())
     253                 :           0 :     ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
     254                 :             :                               canonical_prefix);
     255                 :             : 
     256                 :           0 :   if (struct_decl.has_where_clause ())
     257                 :           0 :     ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
     258                 :             : 
     259                 :           0 :   for (AST::TupleField &field : struct_decl.get_fields ())
     260                 :             :     {
     261                 :           0 :       if (field.get_field_type ().is_marked_for_strip ())
     262                 :           0 :         continue;
     263                 :             : 
     264                 :           0 :       resolve_visibility (field.get_visibility ());
     265                 :             : 
     266                 :           0 :       ResolveType::go (field.get_field_type ());
     267                 :             :     }
     268                 :             : 
     269                 :           0 :   resolver->get_type_scope ().pop ();
     270                 :           0 : }
     271                 :             : 
     272                 :             : void
     273                 :           0 : ResolveItem::visit (AST::Enum &enum_decl)
     274                 :             : {
     275                 :           0 :   auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (),
     276                 :           0 :                                       enum_decl.get_identifier ().as_string ());
     277                 :           0 :   auto path = prefix.append (decl);
     278                 :           0 :   auto cpath = canonical_prefix.append (decl);
     279                 :           0 :   mappings.insert_canonical_path (enum_decl.get_node_id (), cpath);
     280                 :             : 
     281                 :           0 :   resolve_visibility (enum_decl.get_visibility ());
     282                 :             : 
     283                 :           0 :   NodeId scope_node_id = enum_decl.get_node_id ();
     284                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     285                 :             : 
     286                 :           0 :   if (enum_decl.has_generics ())
     287                 :           0 :     ResolveGenericParams::go (enum_decl.get_generic_params (), prefix,
     288                 :             :                               canonical_prefix);
     289                 :             : 
     290                 :           0 :   if (enum_decl.has_where_clause ())
     291                 :           0 :     ResolveWhereClause::Resolve (enum_decl.get_where_clause ());
     292                 :             : 
     293                 :             :   /* The actual fields are inside the variants.  */
     294                 :           0 :   for (auto &variant : enum_decl.get_variants ())
     295                 :           0 :     ResolveItem::go (*variant, path, cpath);
     296                 :             : 
     297                 :           0 :   resolver->get_type_scope ().pop ();
     298                 :           0 : }
     299                 :             : 
     300                 :             : /* EnumItem doesn't need to be handled, no fields.  */
     301                 :             : void
     302                 :           0 : ResolveItem::visit (AST::EnumItem &item)
     303                 :             : {
     304                 :             :   // Since at this point we cannot have visibilities on enum items anymore, we
     305                 :             :   // can skip handling them
     306                 :             : 
     307                 :           0 :   auto decl = CanonicalPath::new_seg (item.get_node_id (),
     308                 :           0 :                                       item.get_identifier ().as_string ());
     309                 :           0 :   auto path = prefix.append (decl);
     310                 :           0 :   auto cpath = canonical_prefix.append (decl);
     311                 :           0 :   mappings.insert_canonical_path (item.get_node_id (), cpath);
     312                 :           0 : }
     313                 :             : 
     314                 :             : void
     315                 :           0 : ResolveItem::visit (AST::EnumItemTuple &item)
     316                 :             : {
     317                 :           0 :   auto decl = CanonicalPath::new_seg (item.get_node_id (),
     318                 :           0 :                                       item.get_identifier ().as_string ());
     319                 :           0 :   auto path = prefix.append (decl);
     320                 :           0 :   auto cpath = canonical_prefix.append (decl);
     321                 :           0 :   mappings.insert_canonical_path (item.get_node_id (), cpath);
     322                 :             : 
     323                 :           0 :   for (auto &field : item.get_tuple_fields ())
     324                 :             :     {
     325                 :           0 :       if (field.get_field_type ().is_marked_for_strip ())
     326                 :           0 :         continue;
     327                 :             : 
     328                 :           0 :       ResolveType::go (field.get_field_type ());
     329                 :             :     }
     330                 :           0 : }
     331                 :             : 
     332                 :             : void
     333                 :           0 : ResolveItem::visit (AST::EnumItemStruct &item)
     334                 :             : {
     335                 :           0 :   auto decl = CanonicalPath::new_seg (item.get_node_id (),
     336                 :           0 :                                       item.get_identifier ().as_string ());
     337                 :           0 :   auto path = prefix.append (decl);
     338                 :           0 :   auto cpath = canonical_prefix.append (decl);
     339                 :           0 :   mappings.insert_canonical_path (item.get_node_id (), cpath);
     340                 :             : 
     341                 :           0 :   for (auto &field : item.get_struct_fields ())
     342                 :             :     {
     343                 :           0 :       if (field.get_field_type ().is_marked_for_strip ())
     344                 :           0 :         continue;
     345                 :             : 
     346                 :           0 :       ResolveType::go (field.get_field_type ());
     347                 :             :     }
     348                 :           0 : }
     349                 :             : 
     350                 :             : void
     351                 :           0 : ResolveItem::visit (AST::EnumItemDiscriminant &item)
     352                 :             : {
     353                 :           0 :   auto decl = CanonicalPath::new_seg (item.get_node_id (),
     354                 :           0 :                                       item.get_identifier ().as_string ());
     355                 :           0 :   auto path = prefix.append (decl);
     356                 :           0 :   auto cpath = canonical_prefix.append (decl);
     357                 :             : 
     358                 :           0 :   mappings.insert_canonical_path (item.get_node_id (), cpath);
     359                 :             : 
     360                 :           0 :   ResolveExpr::go (item.get_expr (), path, cpath);
     361                 :           0 : }
     362                 :             : 
     363                 :             : void
     364                 :           0 : ResolveItem::visit (AST::StructStruct &struct_decl)
     365                 :             : {
     366                 :           0 :   auto decl
     367                 :           0 :     = CanonicalPath::new_seg (struct_decl.get_node_id (),
     368                 :           0 :                               struct_decl.get_identifier ().as_string ());
     369                 :           0 :   auto path = prefix.append (decl);
     370                 :           0 :   auto cpath = canonical_prefix.append (decl);
     371                 :           0 :   mappings.insert_canonical_path (struct_decl.get_node_id (), cpath);
     372                 :             : 
     373                 :           0 :   resolve_visibility (struct_decl.get_visibility ());
     374                 :             : 
     375                 :           0 :   NodeId scope_node_id = struct_decl.get_node_id ();
     376                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     377                 :             : 
     378                 :           0 :   if (struct_decl.has_generics ())
     379                 :           0 :     ResolveGenericParams::go (struct_decl.get_generic_params (), prefix,
     380                 :             :                               canonical_prefix);
     381                 :             : 
     382                 :           0 :   if (struct_decl.has_where_clause ())
     383                 :           0 :     ResolveWhereClause::Resolve (struct_decl.get_where_clause ());
     384                 :             : 
     385                 :           0 :   for (AST::StructField &field : struct_decl.get_fields ())
     386                 :             :     {
     387                 :           0 :       if (field.get_field_type ().is_marked_for_strip ())
     388                 :           0 :         continue;
     389                 :             : 
     390                 :           0 :       resolve_visibility (field.get_visibility ());
     391                 :             : 
     392                 :           0 :       ResolveType::go (field.get_field_type ());
     393                 :             :     }
     394                 :             : 
     395                 :           0 :   resolver->get_type_scope ().pop ();
     396                 :           0 : }
     397                 :             : 
     398                 :             : void
     399                 :           0 : ResolveItem::visit (AST::Union &union_decl)
     400                 :             : {
     401                 :           0 :   auto decl
     402                 :           0 :     = CanonicalPath::new_seg (union_decl.get_node_id (),
     403                 :           0 :                               union_decl.get_identifier ().as_string ());
     404                 :           0 :   auto path = prefix.append (decl);
     405                 :           0 :   auto cpath = canonical_prefix.append (decl);
     406                 :           0 :   mappings.insert_canonical_path (union_decl.get_node_id (), cpath);
     407                 :             : 
     408                 :           0 :   resolve_visibility (union_decl.get_visibility ());
     409                 :             : 
     410                 :           0 :   NodeId scope_node_id = union_decl.get_node_id ();
     411                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     412                 :             : 
     413                 :           0 :   if (union_decl.has_generics ())
     414                 :           0 :     ResolveGenericParams::go (union_decl.get_generic_params (), prefix,
     415                 :             :                               canonical_prefix);
     416                 :             : 
     417                 :           0 :   if (union_decl.has_where_clause ())
     418                 :           0 :     ResolveWhereClause::Resolve (union_decl.get_where_clause ());
     419                 :             : 
     420                 :           0 :   for (AST::StructField &field : union_decl.get_variants ())
     421                 :             :     {
     422                 :           0 :       if (field.get_field_type ().is_marked_for_strip ())
     423                 :           0 :         continue;
     424                 :             : 
     425                 :           0 :       ResolveType::go (field.get_field_type ());
     426                 :             :     }
     427                 :             : 
     428                 :           0 :   resolver->get_type_scope ().pop ();
     429                 :           0 : }
     430                 :             : 
     431                 :             : void
     432                 :           0 : ResolveItem::visit (AST::StaticItem &var)
     433                 :             : {
     434                 :           0 :   auto decl = CanonicalPath::new_seg (var.get_node_id (),
     435                 :           0 :                                       var.get_identifier ().as_string ());
     436                 :           0 :   auto path = prefix.append (decl);
     437                 :           0 :   auto cpath = canonical_prefix.append (decl);
     438                 :           0 :   mappings.insert_canonical_path (var.get_node_id (), cpath);
     439                 :             : 
     440                 :           0 :   ResolveType::go (var.get_type ());
     441                 :           0 :   ResolveExpr::go (var.get_expr (), path, cpath);
     442                 :           0 : }
     443                 :             : 
     444                 :             : void
     445                 :           0 : ResolveItem::visit (AST::ConstantItem &constant)
     446                 :             : {
     447                 :           0 :   auto decl = CanonicalPath::new_seg (constant.get_node_id (),
     448                 :           0 :                                       constant.get_identifier ());
     449                 :           0 :   auto path = prefix.append (decl);
     450                 :           0 :   auto cpath = canonical_prefix.append (decl);
     451                 :           0 :   mappings.insert_canonical_path (constant.get_node_id (), cpath);
     452                 :             : 
     453                 :           0 :   resolve_visibility (constant.get_visibility ());
     454                 :             : 
     455                 :           0 :   ResolveType::go (constant.get_type ());
     456                 :           0 :   if (constant.has_expr ())
     457                 :           0 :     ResolveExpr::go (constant.get_expr (), path, cpath);
     458                 :           0 : }
     459                 :             : 
     460                 :             : void
     461                 :           0 : ResolveItem::visit (AST::Function &function)
     462                 :             : {
     463                 :           0 :   auto decl
     464                 :           0 :     = CanonicalPath::new_seg (function.get_node_id (),
     465                 :           0 :                               function.get_function_name ().as_string ());
     466                 :           0 :   auto path = prefix.append (decl);
     467                 :           0 :   auto cpath = canonical_prefix.append (decl);
     468                 :             : 
     469                 :           0 :   mappings.insert_canonical_path (function.get_node_id (), cpath);
     470                 :             : 
     471                 :           0 :   resolve_visibility (function.get_visibility ());
     472                 :             : 
     473                 :           0 :   NodeId scope_node_id = function.get_node_id ();
     474                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
     475                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     476                 :           0 :   resolver->get_label_scope ().push (scope_node_id);
     477                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
     478                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
     479                 :           0 :   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
     480                 :             : 
     481                 :           0 :   if (function.has_generics ())
     482                 :           0 :     ResolveGenericParams::go (function.get_generic_params (), prefix,
     483                 :             :                               canonical_prefix);
     484                 :             : 
     485                 :             :   // resolve any where clause items
     486                 :           0 :   if (function.has_where_clause ())
     487                 :           0 :     ResolveWhereClause::Resolve (function.get_where_clause ());
     488                 :             : 
     489                 :           0 :   if (function.has_return_type ())
     490                 :           0 :     ResolveType::go (function.get_return_type ());
     491                 :             : 
     492                 :           0 :   if (function.has_self_param ())
     493                 :             :     {
     494                 :             :       // self turns into (self: Self) as a function param
     495                 :           0 :       AST::Param &s_param = function.get_self_param ();
     496                 :           0 :       auto &self_param = static_cast<AST::SelfParam &> (s_param);
     497                 :             : 
     498                 :             :       // FIXME: which location should be used for Rust::Identifier `self`?
     499                 :           0 :       AST::IdentifierPattern self_pattern (
     500                 :           0 :         self_param.get_node_id (), {"self"}, self_param.get_locus (),
     501                 :           0 :         self_param.get_has_ref (), self_param.get_is_mut (),
     502                 :           0 :         std::unique_ptr<AST::Pattern> (nullptr));
     503                 :           0 :       PatternDeclaration::go (self_pattern, Rib::ItemType::Param);
     504                 :             : 
     505                 :           0 :       if (self_param.has_type ())
     506                 :             :         {
     507                 :             :           // This shouldn't happen the parser should already error for this
     508                 :           0 :           rust_assert (!self_param.get_has_ref ());
     509                 :           0 :           ResolveType::go (self_param.get_type ());
     510                 :             :         }
     511                 :             :       else
     512                 :             :         {
     513                 :             :           // here we implicitly make self have a type path of Self
     514                 :           0 :           std::vector<std::unique_ptr<AST::TypePathSegment>> segments;
     515                 :           0 :           segments.push_back (std::unique_ptr<AST::TypePathSegment> (
     516                 :           0 :             new AST::TypePathSegment ("Self", false, self_param.get_locus ())));
     517                 :             : 
     518                 :           0 :           AST::TypePath self_type_path (std::move (segments),
     519                 :           0 :                                         self_param.get_locus ());
     520                 :           0 :           ResolveType::go (self_type_path);
     521                 :           0 :         }
     522                 :           0 :     }
     523                 :             : 
     524                 :           0 :   std::vector<PatternBinding> bindings
     525                 :           0 :     = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
     526                 :             : 
     527                 :             :   // we make a new scope so the names of parameters are resolved and shadowed
     528                 :             :   // correctly
     529                 :           0 :   for (auto &p : function.get_function_params ())
     530                 :             :     {
     531                 :           0 :       if (p->is_variadic ())
     532                 :             :         {
     533                 :           0 :           auto &param = static_cast<AST::VariadicParam &> (*p);
     534                 :           0 :           if (param.has_pattern ())
     535                 :           0 :             PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
     536                 :             :                                     bindings);
     537                 :             :         }
     538                 :           0 :       else if (p->is_self ())
     539                 :             :         {
     540                 :           0 :           auto &param = static_cast<AST::SelfParam &> (*p);
     541                 :           0 :           if (param.has_type ())
     542                 :           0 :             ResolveType::go (param.get_type ());
     543                 :             :         }
     544                 :             :       else
     545                 :             :         {
     546                 :           0 :           auto &param = static_cast<AST::FunctionParam &> (*p);
     547                 :           0 :           ResolveType::go (param.get_type ());
     548                 :           0 :           PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
     549                 :             :                                   bindings);
     550                 :             :         }
     551                 :             :     }
     552                 :             : 
     553                 :             :   // resolve the function body
     554                 :           0 :   ResolveExpr::go (*function.get_definition ().value (), path, cpath);
     555                 :             : 
     556                 :           0 :   resolver->get_name_scope ().pop ();
     557                 :           0 :   resolver->get_type_scope ().pop ();
     558                 :           0 :   resolver->get_label_scope ().pop ();
     559                 :           0 : }
     560                 :             : 
     561                 :             : void
     562                 :           0 : ResolveItem::visit (AST::InherentImpl &impl_block)
     563                 :             : {
     564                 :           0 :   NodeId scope_node_id = impl_block.get_node_id ();
     565                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
     566                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     567                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
     568                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
     569                 :             : 
     570                 :           0 :   resolve_visibility (impl_block.get_visibility ());
     571                 :             : 
     572                 :           0 :   if (impl_block.has_generics ())
     573                 :           0 :     ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
     574                 :             :                               canonical_prefix);
     575                 :             : 
     576                 :             :   // resolve any where clause items
     577                 :           0 :   if (impl_block.has_where_clause ())
     578                 :           0 :     ResolveWhereClause::Resolve (impl_block.get_where_clause ());
     579                 :             : 
     580                 :             :   // FIXME this needs to be protected behind nominal type-checks see:
     581                 :             :   // rustc --explain E0118
     582                 :             :   // issue #2634
     583                 :           0 :   ResolveType::go (impl_block.get_type ());
     584                 :             : 
     585                 :             :   // Setup paths
     586                 :           0 :   CanonicalPath self_cpath = CanonicalPath::create_empty ();
     587                 :           0 :   bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (), self_cpath);
     588                 :           0 :   if (!ok)
     589                 :             :     {
     590                 :           0 :       resolver->get_name_scope ().pop ();
     591                 :           0 :       resolver->get_type_scope ().pop ();
     592                 :           0 :       resolver->get_label_scope ().pop ();
     593                 :           0 :       return;
     594                 :             :     }
     595                 :             : 
     596                 :           0 :   rust_debug ("AST::InherentImpl resolve Self: {%s}",
     597                 :             :               self_cpath.get ().c_str ());
     598                 :             : 
     599                 :           0 :   CanonicalPath impl_type = self_cpath;
     600                 :           0 :   CanonicalPath impl_type_seg
     601                 :           0 :     = CanonicalPath::inherent_impl_seg (impl_block.get_node_id (), impl_type);
     602                 :           0 :   CanonicalPath impl_prefix = prefix.append (impl_type_seg);
     603                 :             : 
     604                 :             :   // see https://godbolt.org/z/a3vMbsT6W
     605                 :           0 :   CanonicalPath cpath = CanonicalPath::create_empty ();
     606                 :           0 :   if (canonical_prefix.size () <= 1)
     607                 :             :     {
     608                 :           0 :       cpath = impl_prefix;
     609                 :             :     }
     610                 :             :   else
     611                 :             :     {
     612                 :           0 :       cpath = canonical_prefix.append (impl_type_seg);
     613                 :             :     }
     614                 :             : 
     615                 :             :   // done setup paths
     616                 :             : 
     617                 :           0 :   auto Self
     618                 :           0 :     = CanonicalPath::get_big_self (impl_block.get_type ().get_node_id ());
     619                 :             : 
     620                 :           0 :   resolver->get_type_scope ().insert (Self,
     621                 :           0 :                                       impl_block.get_type ().get_node_id (),
     622                 :           0 :                                       impl_block.get_type ().get_locus ());
     623                 :             : 
     624                 :           0 :   for (auto &impl_item : impl_block.get_impl_items ())
     625                 :             :     {
     626                 :           0 :       rust_debug (
     627                 :             :         "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
     628                 :             :         impl_prefix.get ().c_str (), cpath.get ().c_str ());
     629                 :           0 :       resolve_impl_item (*impl_item, impl_prefix, cpath);
     630                 :             :     }
     631                 :             : 
     632                 :           0 :   resolver->get_type_scope ().peek ()->clear_name (
     633                 :           0 :     Self, impl_block.get_type ().get_node_id ());
     634                 :             : 
     635                 :           0 :   resolver->get_type_scope ().pop ();
     636                 :           0 :   resolver->get_name_scope ().pop ();
     637                 :           0 : }
     638                 :             : 
     639                 :             : void
     640                 :           0 : ResolveItem::visit (AST::TraitImpl &impl_block)
     641                 :             : {
     642                 :           0 :   NodeId scope_node_id = impl_block.get_node_id ();
     643                 :             : 
     644                 :           0 :   resolve_visibility (impl_block.get_visibility ());
     645                 :             : 
     646                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
     647                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     648                 :           0 :   resolver->get_label_scope ().push (scope_node_id);
     649                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
     650                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
     651                 :           0 :   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
     652                 :             : 
     653                 :           0 :   if (impl_block.has_generics ())
     654                 :           0 :     ResolveGenericParams::go (impl_block.get_generic_params (), prefix,
     655                 :             :                               canonical_prefix);
     656                 :             : 
     657                 :             :   // resolve any where clause items
     658                 :           0 :   if (impl_block.has_where_clause ())
     659                 :           0 :     ResolveWhereClause::Resolve (impl_block.get_where_clause ());
     660                 :             : 
     661                 :             :   // CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
     662                 :           0 :   NodeId trait_resolved_node = ResolveType::go (impl_block.get_trait_path ());
     663                 :           0 :   if (trait_resolved_node == UNKNOWN_NODEID)
     664                 :             :     {
     665                 :           0 :       resolver->get_name_scope ().pop ();
     666                 :           0 :       resolver->get_type_scope ().pop ();
     667                 :           0 :       resolver->get_label_scope ().pop ();
     668                 :           0 :       return;
     669                 :             :     }
     670                 :             : 
     671                 :             :   //   CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
     672                 :           0 :   NodeId type_resolved_node = ResolveType::go (impl_block.get_type ());
     673                 :           0 :   if (type_resolved_node == UNKNOWN_NODEID)
     674                 :             :     {
     675                 :           0 :       resolver->get_name_scope ().pop ();
     676                 :           0 :       resolver->get_type_scope ().pop ();
     677                 :           0 :       resolver->get_label_scope ().pop ();
     678                 :           0 :       return;
     679                 :             :     }
     680                 :             : 
     681                 :           0 :   bool ok = true;
     682                 :             : 
     683                 :             :   // setup paths
     684                 :           0 :   CanonicalPath canonical_trait_type = CanonicalPath::create_empty ();
     685                 :             : 
     686                 :           0 :   ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path (),
     687                 :             :                                        canonical_trait_type);
     688                 :           0 :   if (!ok)
     689                 :             :     {
     690                 :           0 :       resolver->get_name_scope ().pop ();
     691                 :           0 :       resolver->get_type_scope ().pop ();
     692                 :           0 :       resolver->get_label_scope ().pop ();
     693                 :           0 :       return;
     694                 :             :     }
     695                 :             : 
     696                 :           0 :   rust_debug ("AST::TraitImpl resolve trait type: {%s}",
     697                 :             :               canonical_trait_type.get ().c_str ());
     698                 :             : 
     699                 :           0 :   CanonicalPath canonical_impl_type = CanonicalPath::create_empty ();
     700                 :           0 :   ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (),
     701                 :             :                                        canonical_impl_type);
     702                 :           0 :   if (!ok)
     703                 :             :     {
     704                 :           0 :       resolver->get_name_scope ().pop ();
     705                 :           0 :       resolver->get_type_scope ().pop ();
     706                 :           0 :       resolver->get_label_scope ().pop ();
     707                 :           0 :       return;
     708                 :             :     }
     709                 :             : 
     710                 :           0 :   rust_debug ("AST::TraitImpl resolve self: {%s}",
     711                 :             :               canonical_impl_type.get ().c_str ());
     712                 :             : 
     713                 :             :   // raw paths
     714                 :           0 :   CanonicalPath impl_type_seg = canonical_impl_type;
     715                 :           0 :   CanonicalPath trait_type_seg = canonical_trait_type;
     716                 :           0 :   CanonicalPath projection
     717                 :             :     = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
     718                 :           0 :                                                 trait_type_seg, impl_type_seg);
     719                 :           0 :   CanonicalPath impl_prefix = prefix.append (projection);
     720                 :             : 
     721                 :             :   // setup canonical-path
     722                 :           0 :   CanonicalPath canonical_projection
     723                 :             :     = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (),
     724                 :             :                                                 canonical_trait_type,
     725                 :           0 :                                                 canonical_impl_type);
     726                 :           0 :   CanonicalPath cpath = CanonicalPath::create_empty ();
     727                 :           0 :   if (canonical_prefix.size () <= 1)
     728                 :             :     {
     729                 :           0 :       cpath = canonical_projection;
     730                 :             :     }
     731                 :             :   else
     732                 :             :     {
     733                 :           0 :       cpath = canonical_prefix.append (canonical_projection);
     734                 :             :     }
     735                 :             : 
     736                 :             :   // DONE setup canonical-path
     737                 :             : 
     738                 :           0 :   auto Self
     739                 :           0 :     = CanonicalPath::get_big_self (impl_block.get_type ().get_node_id ());
     740                 :             : 
     741                 :           0 :   resolver->get_type_scope ().insert (Self,
     742                 :           0 :                                       impl_block.get_type ().get_node_id (),
     743                 :           0 :                                       impl_block.get_type ().get_locus ());
     744                 :             : 
     745                 :           0 :   for (auto &impl_item : impl_block.get_impl_items ())
     746                 :             :     {
     747                 :           0 :       rust_debug (
     748                 :             :         "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}",
     749                 :             :         impl_prefix.get ().c_str (), cpath.get ().c_str ());
     750                 :           0 :       resolve_impl_item (*impl_item, impl_prefix, cpath);
     751                 :             :     }
     752                 :             : 
     753                 :           0 :   Rib *r = resolver->get_type_scope ().peek ();
     754                 :           0 :   r->clear_name (Self, impl_block.get_type ().get_node_id ());
     755                 :             : 
     756                 :           0 :   resolver->get_name_scope ().pop ();
     757                 :           0 :   resolver->get_type_scope ().pop ();
     758                 :           0 :   resolver->get_label_scope ().pop ();
     759                 :           0 : }
     760                 :             : 
     761                 :             : void
     762                 :           0 : ResolveItem::visit (AST::Trait &trait)
     763                 :             : {
     764                 :           0 :   NodeId scope_node_id = trait.get_node_id ();
     765                 :             : 
     766                 :           0 :   resolve_visibility (trait.get_visibility ());
     767                 :             : 
     768                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
     769                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
     770                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
     771                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
     772                 :             : 
     773                 :           0 :   ResolveGenericParams::go_single (trait.get_implicit_self (), prefix,
     774                 :             :                                    canonical_prefix);
     775                 :           0 :   ResolveGenericParams::go (trait.get_generic_params (), prefix,
     776                 :             :                             canonical_prefix);
     777                 :             : 
     778                 :             :   // Self is an implicit TypeParam so lets mark it as such
     779                 :           0 :   resolver->get_type_scope ().append_reference_for_def (
     780                 :           0 :     trait.get_node_id (), trait.get_implicit_self ().get_node_id ());
     781                 :             : 
     782                 :           0 :   if (trait.has_type_param_bounds ())
     783                 :             :     {
     784                 :           0 :       for (auto &bound : trait.get_type_param_bounds ())
     785                 :             :         {
     786                 :           0 :           ResolveTypeBound::go (*bound);
     787                 :             :         }
     788                 :             :     }
     789                 :             : 
     790                 :             :   // resolve any where clause items
     791                 :           0 :   if (trait.has_where_clause ())
     792                 :           0 :     ResolveWhereClause::Resolve (trait.get_where_clause ());
     793                 :             : 
     794                 :             :   // resolve the paths
     795                 :           0 :   CanonicalPath path = CanonicalPath::create_empty ();
     796                 :           0 :   CanonicalPath cpath = CanonicalPath::create_empty ();
     797                 :             :   //
     798                 :             : 
     799                 :           0 :   for (auto &item : trait.get_trait_items ())
     800                 :             :     {
     801                 :           0 :       ResolveTraitItems::go (item.get (), path, cpath);
     802                 :             :     }
     803                 :             : 
     804                 :           0 :   resolver->get_type_scope ().pop ();
     805                 :           0 :   resolver->get_name_scope ().pop ();
     806                 :           0 : }
     807                 :             : 
     808                 :             : void
     809                 :           0 : ResolveItem::visit (AST::ExternBlock &extern_block)
     810                 :             : {
     811                 :           0 :   resolve_visibility (extern_block.get_visibility ());
     812                 :             : 
     813                 :           0 :   for (auto &item : extern_block.get_extern_items ())
     814                 :             :     {
     815                 :           0 :       resolve_extern_item (*item);
     816                 :             :     }
     817                 :           0 : }
     818                 :             : 
     819                 :             : void
     820                 :           0 : ResolveItem::resolve_impl_item (AST::AssociatedItem &item,
     821                 :             :                                 const CanonicalPath &prefix,
     822                 :             :                                 const CanonicalPath &canonical_prefix)
     823                 :             : {
     824                 :           0 :   ResolveImplItems::go (item, prefix, canonical_prefix);
     825                 :           0 : }
     826                 :             : 
     827                 :             : void
     828                 :           0 : ResolveItem::resolve_extern_item (AST::ExternalItem &item)
     829                 :             : {
     830                 :           0 :   ResolveExternItem::go (item, prefix, canonical_prefix);
     831                 :           0 : }
     832                 :             : 
     833                 :             : static void flatten_glob (const AST::UseTreeGlob &glob,
     834                 :             :                           std::vector<Import> &imports);
     835                 :             : static void flatten_rebind (const AST::UseTreeRebind &glob,
     836                 :             :                             std::vector<Import> &imports);
     837                 :             : static void flatten_list (const AST::UseTreeList &glob,
     838                 :             :                           std::vector<Import> &imports);
     839                 :             : 
     840                 :             : static void
     841                 :           2 : flatten (const AST::UseTree *tree, std::vector<Import> &imports)
     842                 :             : {
     843                 :           2 :   switch (tree->get_kind ())
     844                 :             :     {
     845                 :           0 :     case AST::UseTree::Glob:
     846                 :           0 :       {
     847                 :           0 :         auto glob = static_cast<const AST::UseTreeGlob *> (tree);
     848                 :           0 :         flatten_glob (*glob, imports);
     849                 :           0 :         break;
     850                 :             :       }
     851                 :           2 :     case AST::UseTree::Rebind:
     852                 :           2 :       {
     853                 :           2 :         auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
     854                 :           2 :         flatten_rebind (*rebind, imports);
     855                 :           2 :         break;
     856                 :             :       }
     857                 :           0 :     case AST::UseTree::List:
     858                 :           0 :       {
     859                 :           0 :         auto list = static_cast<const AST::UseTreeList *> (tree);
     860                 :           0 :         flatten_list (*list, imports);
     861                 :           0 :         break;
     862                 :             :       }
     863                 :             :       break;
     864                 :             :     }
     865                 :           2 : }
     866                 :             : 
     867                 :             : static void
     868                 :           2 : flatten_glob (const AST::UseTreeGlob &glob, std::vector<Import> &imports)
     869                 :             : {
     870                 :           2 :   if (glob.has_path ())
     871                 :           2 :     imports.emplace_back (glob.get_path (), true, std::string ());
     872                 :           2 : }
     873                 :             : 
     874                 :             : static void
     875                 :           5 : flatten_rebind (const AST::UseTreeRebind &rebind, std::vector<Import> &imports)
     876                 :             : {
     877                 :           5 :   auto path = rebind.get_path ();
     878                 :             : 
     879                 :           5 :   std::string label;
     880                 :           5 :   if (rebind.has_identifier ())
     881                 :           2 :     label = rebind.get_identifier ().as_string ();
     882                 :             :   else
     883                 :           3 :     label = path.get_final_segment ().as_string ();
     884                 :             : 
     885                 :           5 :   imports.emplace_back (path, false, label);
     886                 :           5 : }
     887                 :             : 
     888                 :             : static void
     889                 :           1 : flatten_list (const AST::UseTreeList &list, std::vector<Import> &imports)
     890                 :             : {
     891                 :           1 :   auto prefix = AST::SimplePath::create_empty ();
     892                 :           1 :   if (list.has_path ())
     893                 :           1 :     prefix = list.get_path ();
     894                 :             : 
     895                 :           3 :   for (const auto &tree : list.get_trees ())
     896                 :             :     {
     897                 :             :       // append imports to the main list, then modify them in-place
     898                 :           2 :       auto start_idx = imports.size ();
     899                 :           2 :       flatten (tree.get (), imports);
     900                 :             : 
     901                 :           4 :       for (auto import = imports.begin () + start_idx; import != imports.end ();
     902                 :           2 :            import++)
     903                 :             :         {
     904                 :             :           // avoid duplicate node ids
     905                 :           2 :           auto prefix_copy
     906                 :           2 :             = AST::SimplePath ({}, prefix.has_opening_scope_resolution (),
     907                 :           2 :                                prefix.get_locus ());
     908                 :           6 :           for (auto &seg : prefix.get_segments ())
     909                 :           8 :             prefix_copy.get_segments ().push_back (
     910                 :           8 :               AST::SimplePathSegment (seg.get_segment_name (),
     911                 :          12 :                                       seg.get_locus ()));
     912                 :             : 
     913                 :           2 :           import->add_prefix (std::move (prefix_copy));
     914                 :           2 :         }
     915                 :             :     }
     916                 :           1 : }
     917                 :             : 
     918                 :             : void
     919                 :           2 : Import::add_prefix (AST::SimplePath prefix)
     920                 :             : {
     921                 :           2 :   AST::SimplePath old_path (std::move (path));
     922                 :           2 :   path = std::move (prefix);
     923                 :           4 :   std::move (old_path.get_segments ().begin (), old_path.get_segments ().end (),
     924                 :             :              std::back_inserter (path.get_segments ()));
     925                 :           2 : }
     926                 :             : 
     927                 :             : /**
     928                 :             :  * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve.
     929                 :             :  *
     930                 :             :  * Given the following use declarations:
     931                 :             :  * ```
     932                 :             :  * use some::path::to_resolve; #1
     933                 :             :  * use some::path::to_glob::*; #2
     934                 :             :  * use some::path::{one, two}; #2
     935                 :             :  * ```
     936                 :             :  *
     937                 :             :  * In the first case, we simply want to return a vector with a single
     938                 :             :  * SimplePath:
     939                 :             :  * [some::path::to_resolve]
     940                 :             :  *
     941                 :             :  * In the second case, we want to resolve the glob's "origin path":
     942                 :             :  * [some::path::to_glob]
     943                 :             :  *
     944                 :             :  * Finally in the third case, we want to create two SimplePaths to resolve:
     945                 :             :  * [some::path::one, some::path::two]
     946                 :             :  */
     947                 :             : static std::vector<Import>
     948                 :           0 : flatten_use_dec_to_imports (const AST::UseDeclaration &use_item)
     949                 :             : {
     950                 :           0 :   auto imports = std::vector<Import> ();
     951                 :             : 
     952                 :           0 :   const auto &tree = use_item.get_tree ();
     953                 :           0 :   flatten (tree.get (), imports);
     954                 :             : 
     955                 :           0 :   return imports;
     956                 :             : }
     957                 :             : 
     958                 :             : void
     959                 :           0 : ResolveItem::visit (AST::UseDeclaration &use_item)
     960                 :             : {
     961                 :           0 :   std::vector<Import> to_resolve = flatten_use_dec_to_imports (use_item);
     962                 :             : 
     963                 :             :   // FIXME: I think this does not actually resolve glob use-decls and is going
     964                 :             :   // the wrong way about it. RFC #1560 specifies the following:
     965                 :             :   //
     966                 :             :   // > When we find a glob import, we have to record a 'back link', so that when
     967                 :             :   // a public name is added for the supplying module, we can add it for the
     968                 :             :   // importing module.
     969                 :             :   //
     970                 :             :   // Which is the opposite of what we're doing if I understand correctly?
     971                 :             : 
     972                 :           0 :   NodeId current_module = resolver->peek_current_module_scope ();
     973                 :           0 :   for (auto &import : to_resolve)
     974                 :             :     {
     975                 :           0 :       auto &path = import.get_path ();
     976                 :             : 
     977                 :           0 :       rust_debug ("resolving use-decl path: [%s]", path.as_string ().c_str ());
     978                 :           0 :       NodeId resolved_node_id = ResolvePath::go (path);
     979                 :           0 :       bool ok = resolved_node_id != UNKNOWN_NODEID;
     980                 :           0 :       if (!ok)
     981                 :           0 :         continue;
     982                 :             : 
     983                 :           0 :       if (import.is_glob ())
     984                 :           0 :         continue;
     985                 :             : 
     986                 :           0 :       auto decl = CanonicalPath::new_seg (resolved_node_id, import.get_name ());
     987                 :           0 :       mappings.insert_module_child_item (current_module, decl);
     988                 :             : 
     989                 :           0 :       resolver->get_type_scope ().insert (decl, resolved_node_id,
     990                 :             :                                           path.get_locus (),
     991                 :             :                                           Rib::ItemType::Type);
     992                 :           0 :       rust_debug ("use-decl rexporting: [%s]", decl.get ().c_str ());
     993                 :           0 :     }
     994                 :           0 : }
     995                 :             : 
     996                 :           0 : ResolveImplItems::ResolveImplItems (const CanonicalPath &prefix,
     997                 :           0 :                                     const CanonicalPath &canonical_prefix)
     998                 :           0 :   : ResolveItem (prefix, canonical_prefix)
     999                 :           0 : {}
    1000                 :             : 
    1001                 :             : void
    1002                 :           0 : ResolveImplItems::go (AST::AssociatedItem &item, const CanonicalPath &prefix,
    1003                 :             :                       const CanonicalPath &canonical_prefix)
    1004                 :             : {
    1005                 :           0 :   if (item.is_marked_for_strip ())
    1006                 :           0 :     return;
    1007                 :             : 
    1008                 :           0 :   ResolveImplItems resolver (prefix, canonical_prefix);
    1009                 :           0 :   item.accept_vis (resolver);
    1010                 :           0 : }
    1011                 :             : 
    1012                 :             : void
    1013                 :           0 : ResolveImplItems::visit (AST::TypeAlias &alias)
    1014                 :             : {
    1015                 :           0 :   ResolveItem::visit (alias);
    1016                 :             : 
    1017                 :           0 :   resolve_visibility (alias.get_visibility ());
    1018                 :             : 
    1019                 :             :   // FIXME this stops the erronious unused decls which will be fixed later on
    1020                 :           0 :   resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (),
    1021                 :             :                                                         alias.get_node_id ());
    1022                 :           0 : }
    1023                 :             : 
    1024                 :             : void
    1025                 :           0 : ResolveExternItem::go (AST::ExternalItem &item, const CanonicalPath &prefix,
    1026                 :             :                        const CanonicalPath &canonical_prefix)
    1027                 :             : {
    1028                 :           0 :   ResolveExternItem resolver (prefix, canonical_prefix);
    1029                 :           0 :   item.accept_vis (resolver);
    1030                 :           0 : }
    1031                 :             : 
    1032                 :             : void
    1033                 :           0 : ResolveExternItem::visit (AST::Function &function)
    1034                 :             : {
    1035                 :           0 :   NodeId scope_node_id = function.get_node_id ();
    1036                 :           0 :   auto decl
    1037                 :           0 :     = CanonicalPath::new_seg (function.get_node_id (),
    1038                 :           0 :                               function.get_function_name ().as_string ());
    1039                 :           0 :   auto path = prefix.append (decl);
    1040                 :           0 :   auto cpath = canonical_prefix.append (decl);
    1041                 :             : 
    1042                 :           0 :   mappings.insert_canonical_path (function.get_node_id (), cpath);
    1043                 :             : 
    1044                 :           0 :   resolve_visibility (function.get_visibility ());
    1045                 :             : 
    1046                 :           0 :   resolver->get_name_scope ().push (scope_node_id);
    1047                 :           0 :   resolver->get_type_scope ().push (scope_node_id);
    1048                 :           0 :   resolver->get_label_scope ().push (scope_node_id);
    1049                 :           0 :   resolver->push_new_name_rib (resolver->get_name_scope ().peek ());
    1050                 :           0 :   resolver->push_new_type_rib (resolver->get_type_scope ().peek ());
    1051                 :           0 :   resolver->push_new_label_rib (resolver->get_label_scope ().peek ());
    1052                 :             : 
    1053                 :             :   // resolve the generics
    1054                 :           0 :   if (function.has_generics ())
    1055                 :           0 :     ResolveGenericParams::go (function.get_generic_params (), prefix,
    1056                 :             :                               canonical_prefix);
    1057                 :             : 
    1058                 :           0 :   if (function.has_return_type ())
    1059                 :           0 :     ResolveType::go (function.get_return_type ());
    1060                 :             : 
    1061                 :             :   // we make a new scope so the names of parameters are resolved and shadowed
    1062                 :             :   // correctly
    1063                 :           0 :   for (auto &param : function.get_function_params ())
    1064                 :           0 :     if (!param->is_variadic ())
    1065                 :             :       {
    1066                 :           0 :         auto &p = static_cast<AST::FunctionParam &> (*param);
    1067                 :           0 :         ResolveType::go (p.get_type ());
    1068                 :             :       }
    1069                 :             : 
    1070                 :             :   // done
    1071                 :           0 :   resolver->get_name_scope ().pop ();
    1072                 :           0 :   resolver->get_type_scope ().pop ();
    1073                 :           0 :   resolver->get_label_scope ().pop ();
    1074                 :           0 : }
    1075                 :             : 
    1076                 :             : void
    1077                 :           0 : ResolveExternItem::visit (AST::ExternalStaticItem &item)
    1078                 :             : {
    1079                 :           0 :   resolve_visibility (item.get_visibility ());
    1080                 :             : 
    1081                 :           0 :   ResolveType::go (item.get_type ());
    1082                 :           0 : }
    1083                 :             : 
    1084                 :             : } // namespace Resolver
    1085                 :             : } // namespace Rust
    1086                 :             : 
    1087                 :             : #if CHECKING_P
    1088                 :             : 
    1089                 :             : namespace selftest {
    1090                 :             : 
    1091                 :             : static void
    1092                 :           1 : rust_flatten_nested_glob (void)
    1093                 :             : {
    1094                 :           1 :   auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
    1095                 :           1 :   auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
    1096                 :           3 :   auto foobar = Rust::AST::SimplePath ({foo, bar});
    1097                 :             : 
    1098                 :           1 :   auto glob
    1099                 :             :     = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
    1100                 :           1 :                               foobar, UNDEF_LOCATION);
    1101                 :             : 
    1102                 :           1 :   auto imports = std::vector<Rust::Resolver::Import> ();
    1103                 :           1 :   Rust::Resolver::flatten_glob (glob, imports);
    1104                 :             : 
    1105                 :           1 :   ASSERT_TRUE (!imports.empty ());
    1106                 :           1 :   ASSERT_EQ (imports.size (), 1);
    1107                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
    1108                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
    1109                 :           1 : }
    1110                 :             : 
    1111                 :             : static void
    1112                 :           1 : rust_flatten_glob (void)
    1113                 :             : {
    1114                 :           1 :   auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION);
    1115                 :             : 
    1116                 :           1 :   auto glob
    1117                 :             :     = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED,
    1118                 :           1 :                               frob, UNDEF_LOCATION);
    1119                 :             : 
    1120                 :           1 :   auto imports = std::vector<Rust::Resolver::Import> ();
    1121                 :           1 :   Rust::Resolver::flatten_glob (glob, imports);
    1122                 :             : 
    1123                 :           1 :   ASSERT_TRUE (!imports.empty ());
    1124                 :           1 :   ASSERT_EQ (imports.size (), 1);
    1125                 :           1 :   ASSERT_EQ (imports[0].get_path (), "frobulator");
    1126                 :           1 : }
    1127                 :             : 
    1128                 :             : static void
    1129                 :           1 : rust_flatten_rebind_none (void)
    1130                 :             : {
    1131                 :           1 :   auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
    1132                 :           1 :   auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
    1133                 :           3 :   auto foobar = Rust::AST::SimplePath ({foo, bar});
    1134                 :             : 
    1135                 :           1 :   auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE,
    1136                 :           1 :                                           foobar, UNDEF_LOCATION);
    1137                 :             : 
    1138                 :           1 :   auto imports = std::vector<Rust::Resolver::Import> ();
    1139                 :           1 :   Rust::Resolver::flatten_rebind (rebind, imports);
    1140                 :             : 
    1141                 :           1 :   ASSERT_TRUE (!imports.empty ());
    1142                 :           1 :   ASSERT_EQ (imports.size (), 1);
    1143                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
    1144                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
    1145                 :           1 : }
    1146                 :             : 
    1147                 :             : static void
    1148                 :           1 : rust_flatten_rebind (void)
    1149                 :             : {
    1150                 :           1 :   auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION);
    1151                 :             : 
    1152                 :           1 :   auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
    1153                 :           2 :                                           frob, UNDEF_LOCATION, {"saindoux"});
    1154                 :             : 
    1155                 :           1 :   auto imports = std::vector<Rust::Resolver::Import> ();
    1156                 :           1 :   Rust::Resolver::flatten_rebind (rebind, imports);
    1157                 :             : 
    1158                 :           1 :   ASSERT_TRUE (!imports.empty ());
    1159                 :           1 :   ASSERT_EQ (imports.size (), 1);
    1160                 :           1 :   ASSERT_EQ (imports[0].get_path (), "frobulator");
    1161                 :           1 :   ASSERT_EQ (imports[0].get_name (), "saindoux");
    1162                 :           1 : }
    1163                 :             : 
    1164                 :             : static void
    1165                 :           1 : rust_flatten_rebind_nested (void)
    1166                 :             : {
    1167                 :           1 :   auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
    1168                 :           1 :   auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
    1169                 :           1 :   auto baz = Rust::AST::SimplePathSegment ("baz", UNDEF_LOCATION);
    1170                 :             : 
    1171                 :           4 :   auto foo_bar_baz = Rust::AST::SimplePath ({foo, bar, baz});
    1172                 :             : 
    1173                 :           1 :   auto rebind
    1174                 :             :     = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER,
    1175                 :           2 :                                 foo_bar_baz, UNDEF_LOCATION, {"saindoux"});
    1176                 :             : 
    1177                 :           1 :   auto imports = std::vector<Rust::Resolver::Import> ();
    1178                 :           1 :   Rust::Resolver::flatten_rebind (rebind, imports);
    1179                 :             : 
    1180                 :           1 :   ASSERT_TRUE (!imports.empty ());
    1181                 :           1 :   ASSERT_EQ (imports.size (), 1);
    1182                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
    1183                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
    1184                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz");
    1185                 :           1 :   ASSERT_EQ (imports[0].get_name (), "saindoux");
    1186                 :           1 : }
    1187                 :             : 
    1188                 :             : static void
    1189                 :           1 : rust_flatten_list (void)
    1190                 :             : {
    1191                 :           1 :   auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION);
    1192                 :           1 :   auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION);
    1193                 :           3 :   auto foo_bar = Rust::AST::SimplePath ({foo, bar});
    1194                 :             : 
    1195                 :           1 :   auto baz = Rust::AST::SimplePath::from_str ("baz", UNDEF_LOCATION);
    1196                 :           1 :   auto bul = Rust::AST::SimplePath::from_str ("bul", UNDEF_LOCATION);
    1197                 :             : 
    1198                 :             :   // use foo::bar::{baz, bul};
    1199                 :             : 
    1200                 :           1 :   auto use0 = std::unique_ptr<Rust::AST::UseTree> (
    1201                 :             :     new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, baz,
    1202                 :           1 :                                   UNDEF_LOCATION));
    1203                 :           1 :   auto use1 = std::unique_ptr<Rust::AST::UseTree> (
    1204                 :             :     new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, bul,
    1205                 :           1 :                                   UNDEF_LOCATION));
    1206                 :             : 
    1207                 :           1 :   auto uses = std::vector<std::unique_ptr<Rust::AST::UseTree>> ();
    1208                 :           1 :   uses.emplace_back (std::move (use0));
    1209                 :           1 :   uses.emplace_back (std::move (use1));
    1210                 :             : 
    1211                 :           1 :   auto list
    1212                 :             :     = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED, foo_bar,
    1213                 :           1 :                               std::move (uses), UNDEF_LOCATION);
    1214                 :             : 
    1215                 :           1 :   auto imports = std::vector<Rust::Resolver::Import> ();
    1216                 :           1 :   Rust::Resolver::flatten_list (list, imports);
    1217                 :             : 
    1218                 :           1 :   ASSERT_TRUE (!imports.empty ());
    1219                 :           1 :   ASSERT_EQ (imports.size (), 2);
    1220                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo");
    1221                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar");
    1222                 :           1 :   ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz");
    1223                 :           1 :   ASSERT_EQ (imports[1].get_path ().get_segments ()[0].as_string (), "foo");
    1224                 :           1 :   ASSERT_EQ (imports[1].get_path ().get_segments ()[1].as_string (), "bar");
    1225                 :           1 :   ASSERT_EQ (imports[1].get_path ().get_segments ()[2].as_string (), "bul");
    1226                 :           1 : }
    1227                 :             : 
    1228                 :             : static void
    1229                 :           1 : rust_use_dec_flattening (void)
    1230                 :             : {
    1231                 :           1 :   rust_flatten_glob ();
    1232                 :           1 :   rust_flatten_nested_glob ();
    1233                 :           1 :   rust_flatten_rebind_none ();
    1234                 :           1 :   rust_flatten_rebind ();
    1235                 :           1 :   rust_flatten_rebind_nested ();
    1236                 :           1 :   rust_flatten_list ();
    1237                 :           1 : }
    1238                 :             : 
    1239                 :             : void
    1240                 :           1 : rust_simple_path_resolve_test (void)
    1241                 :             : {
    1242                 :           1 :   rust_use_dec_flattening ();
    1243                 :           1 : }
    1244                 :             : 
    1245                 :             : } // namespace selftest
    1246                 :             : 
    1247                 :             : #endif // CHECKING_P
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.