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