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