LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check-path.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.5 % 253 229
Test Date: 2026-10-03 16:17:38 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : // Copyright (C) 2020-2026 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-diagnostics.h"
      20              : #include "rust-hir-map.h"
      21              : #include "rust-hir-path.h"
      22              : #include "rust-hir-type-check-expr.h"
      23              : #include "rust-hir-type-check-type.h"
      24              : #include "rust-hir-type-check-item.h"
      25              : #include "rust-hir-trait-resolve.h"
      26              : #include "rust-rib.h"
      27              : #include "rust-substitution-mapper.h"
      28              : #include "rust-hir-path-probe-expr.h"
      29              : #include "rust-hir-path-probe-type.h"
      30              : #include "rust-type-util.h"
      31              : #include "rust-hir-type-bounds.h"
      32              : #include "rust-hir-item.h"
      33              : #include "rust-finalized-name-resolution-context.h"
      34              : 
      35              : namespace Rust {
      36              : namespace Resolver {
      37              : 
      38              : void
      39          124 : TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
      40              : {
      41          124 :   HIR::QualifiedPathType qual_path_type = expr.get_path_type ();
      42          124 :   TyTy::BaseType *root = TypeCheckType::Resolve (qual_path_type.get_type ());
      43          124 :   if (root->get_kind () == TyTy::TypeKind::ERROR)
      44              :     return;
      45              : 
      46          124 :   if (!qual_path_type.has_as_clause ())
      47              :     {
      48           42 :       NodeId root_resolved_node_id = UNKNOWN_NODEID;
      49           42 :       resolve_segments (root_resolved_node_id, expr.get_segments (), 0, root,
      50              :                         expr.get_mappings (), expr.get_locus ());
      51           42 :       return;
      52              :     }
      53              : 
      54              :   // Resolve the trait now
      55           82 :   HIR::TypePath &trait_path_ref = qual_path_type.get_trait ();
      56           82 :   TraitReference *trait_ref = TraitResolver::Resolve (trait_path_ref);
      57           82 :   if (trait_ref->is_error ())
      58              :     return;
      59              : 
      60              :   // does this type actually implement this type-bound?
      61           82 :   if (!TypeBoundsProbe::is_bound_satisfied_for_type (root, trait_ref))
      62              :     return;
      63              : 
      64              :   // then we need to look at the next segment to create perform the correct
      65              :   // projection type
      66           80 :   if (expr.get_segments ().empty ())
      67              :     return;
      68              : 
      69              :   // get the predicate for the bound
      70           80 :   auto specified_bound
      71           80 :     = get_predicate_from_bound (trait_path_ref, qual_path_type.get_type ());
      72           80 :   if (specified_bound.is_error ())
      73              :     return;
      74              : 
      75              :   // inherit the bound
      76           80 :   root->inherit_bound (specified_bound);
      77              : 
      78              :   // lookup the associated item from the specified bound
      79           80 :   HIR::PathExprSegment &item_seg = expr.get_segments ().at (0);
      80           80 :   HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment ();
      81           80 :   tl::optional<TyTy::TypeBoundPredicateItem> item
      82           80 :     = specified_bound.lookup_associated_item (item_seg_identifier.to_string ());
      83           80 :   if (!item.has_value ())
      84              :     {
      85            0 :       rust_error_at (item_seg.get_locus (), "unknown associated item");
      86            0 :       return;
      87              :     }
      88              : 
      89              :   // we try to look for the real impl item if possible
      90           80 :   HIR::ImplItem *impl_item = nullptr;
      91              : 
      92              :   // lookup the associated impl trait for this if we can (it might be generic)
      93           80 :   AssociatedImplTrait *associated_impl_trait
      94           80 :     = lookup_associated_impl_block (specified_bound, root);
      95           80 :   if (associated_impl_trait != nullptr)
      96              :     {
      97           22 :       for (auto &i :
      98           75 :            associated_impl_trait->get_impl_block ()->get_impl_items ())
      99              :         {
     100           38 :           bool found = i->get_impl_item_name ().compare (
     101           38 :                          item_seg_identifier.to_string ())
     102           38 :                        == 0;
     103           38 :           if (found)
     104              :             {
     105           16 :               impl_item = i.get ();
     106           16 :               break;
     107              :             }
     108              :         }
     109              :     }
     110              : 
     111          117 :   NodeId root_resolved_node_id = UNKNOWN_NODEID;
     112           53 :   if (impl_item == nullptr)
     113              :     {
     114              :       // this may be valid as there could be a default trait implementation here
     115              :       // and we dont need to worry if the trait item is actually implemented or
     116              :       // not because this will have already been validated as part of the trait
     117              :       // impl block
     118           64 :       infered = item->get_tyty_for_receiver (root);
     119           64 :       root_resolved_node_id
     120           64 :         = item->get_raw_item ()->get_mappings ().get_nodeid ();
     121              :     }
     122              :   else
     123              :     {
     124           16 :       HirId impl_item_id = impl_item->get_impl_mappings ().get_hirid ();
     125           16 :       bool ok = query_type (impl_item_id, &infered);
     126           16 :       if (!ok)
     127              :         {
     128              :           // FIXME
     129              :           // I think query_type should error if required here anyway
     130              :           return;
     131              :         }
     132              : 
     133           16 :       root_resolved_node_id = impl_item->get_impl_mappings ().get_nodeid ();
     134              :     }
     135              : 
     136              :   // turbo-fish segment path::<ty>
     137           80 :   if (item_seg.has_generic_args ())
     138              :     {
     139            0 :       if (!infered->has_substitutions_defined ())
     140              :         {
     141            0 :           rust_error_at (item_seg.get_locus (),
     142              :                          "substitutions not supported for %s",
     143            0 :                          infered->as_string ().c_str ());
     144            0 :           infered = new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
     145            0 :           return;
     146              :         }
     147            0 :       std::vector<TyTy::Region> regions;
     148              : 
     149            0 :       infered = SubstMapper::Resolve (infered, expr.get_locus (),
     150            0 :                                       &item_seg.get_generic_args (),
     151            0 :                                       context->regions_from_generic_args (
     152            0 :                                         item_seg.get_generic_args ()));
     153            0 :     }
     154              : 
     155              :   // continue on as a path-in-expression
     156           80 :   bool fully_resolved = expr.get_segments ().size () <= 1;
     157           80 :   if (fully_resolved)
     158              :     {
     159           80 :       auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     160              : 
     161           80 :       nr_ctx.map_usage (Resolver2_0::Usage (expr.get_mappings ().get_nodeid ()),
     162           80 :                         Resolver2_0::Definition (root_resolved_node_id),
     163              :                         Resolver2_0::Namespace::Values);
     164           80 :       return;
     165              :     }
     166              : 
     167            0 :   resolve_segments (root_resolved_node_id, expr.get_segments (), 1, infered,
     168              :                     expr.get_mappings (), expr.get_locus ());
     169          204 : }
     170              : 
     171              : void
     172        54659 : TypeCheckExpr::visit (HIR::PathInExpression &expr)
     173              : {
     174        54659 :   NodeId resolved_node_id = UNKNOWN_NODEID;
     175        54659 :   if (expr.is_lang_item ())
     176              :     {
     177          178 :       auto lookup
     178          178 :         = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ());
     179          178 :       auto hir_id = mappings.lookup_node_to_hir (lookup);
     180              : 
     181              :       // We can type resolve the path in expression easily as it is a lang
     182              :       // item path, but we still need to setup the various generics and
     183              :       // substitutions
     184              : 
     185              :       // FIXME: We probably need to check *if* the type needs substitutions
     186              :       // or not
     187          178 :       if (LangItem::IsEnumVariant (expr.get_lang_item ()))
     188              :         {
     189          122 :           std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
     190          122 :             = mappings.lookup_hir_enumitem (*hir_id);
     191          244 :           bool enum_item_ok = enum_item_lookup.first != nullptr
     192          122 :                               && enum_item_lookup.second != nullptr;
     193            0 :           rust_assert (enum_item_ok);
     194              : 
     195          122 :           HirId variant_id
     196          122 :             = enum_item_lookup.second->get_mappings ().get_hirid ();
     197              : 
     198          122 :           HIR::EnumItem *enum_item = enum_item_lookup.second;
     199          122 :           resolved_node_id = enum_item->get_mappings ().get_nodeid ();
     200              : 
     201              :           // insert the id of the variant we are resolved to
     202          122 :           context->insert_variant_definition (expr.get_mappings ().get_hirid (),
     203              :                                               variant_id);
     204              : 
     205          122 :           query_type (variant_id, &infered);
     206          122 :           infered = SubstMapper::InferSubst (infered, expr.get_locus ());
     207              :         }
     208              :       else
     209              :         {
     210           56 :           TyTy::BaseType *resolved = nullptr;
     211           56 :           auto trait_item = mappings.lookup_hir_trait_item (*hir_id);
     212           56 :           if (trait_item.has_value ())
     213              :             {
     214           49 :               HIR::Trait *trait = mappings.lookup_trait_item_mapping (*hir_id);
     215           49 :               rust_assert (trait != nullptr);
     216              : 
     217           49 :               TraitReference *trait_ref = TraitResolver::Resolve (*trait);
     218           49 :               if (trait_ref->is_error ())
     219            0 :                 return;
     220              : 
     221           49 :               TraitItemReference *trait_item_ref = nullptr;
     222           49 :               bool ok = trait_ref->lookup_hir_trait_item (**trait_item,
     223              :                                                           &trait_item_ref);
     224           49 :               rust_assert (ok);
     225           49 :               resolved = trait_item_ref->get_tyty ();
     226              :             }
     227            7 :           else if (!query_type (*hir_id, &resolved))
     228              :             return;
     229              : 
     230           56 :           if (resolved == nullptr
     231           56 :               || resolved->get_kind () == TyTy::TypeKind::ERROR)
     232              :             return;
     233              : 
     234           56 :           infered = SubstMapper::InferSubst (resolved, expr.get_locus ());
     235              :         }
     236              : 
     237              :       // FIXME: also we probably need to insert resolved types in the name
     238              :       // resolver here
     239              :     }
     240              :   else
     241              :     {
     242        54481 :       size_t offset = -1;
     243        54481 :       TyTy::BaseType *tyseg
     244        54481 :         = resolve_root_path (expr, &offset, &resolved_node_id);
     245        54481 :       if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
     246        52968 :         return;
     247              : 
     248        54465 :       bool fully_resolved = offset == expr.get_segments ().size ();
     249        54465 :       if (fully_resolved)
     250              :         {
     251        52952 :           infered = tyseg;
     252        52952 :           return;
     253              :         }
     254              : 
     255         1513 :       resolve_segments (resolved_node_id, expr.get_segments (), offset, tyseg,
     256              :                         expr.get_mappings (), expr.get_locus ());
     257              :     }
     258              : }
     259              : 
     260              : TyTy::BaseType *
     261        54481 : TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
     262              :                                   NodeId *root_resolved_node_id)
     263              : {
     264        54481 :   TyTy::BaseType *root_tyty = nullptr;
     265        54481 :   *offset = 0;
     266       117941 :   for (size_t i = 0; i < expr.get_num_segments (); i++)
     267              :     {
     268        64985 :       HIR::PathExprSegment &seg = expr.get_segments ().at (i);
     269              : 
     270        64985 :       bool have_more_segments = (expr.get_num_segments () - 1 != i);
     271        64985 :       bool is_root = *offset == 0;
     272        64985 :       NodeId ast_node_id = seg.get_mappings ().get_nodeid ();
     273              : 
     274        64985 :       auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     275              : 
     276              :       // lookup the reference_node_id
     277        64985 :       NodeId ref_node_id;
     278        64985 :       if (auto res = nr_ctx.lookup (ast_node_id, Resolver2_0::Namespace::Types,
     279        64985 :                                     Resolver2_0::Namespace::Values))
     280              :         {
     281        63469 :           ref_node_id = res->id;
     282              :         }
     283              :       else
     284              :         {
     285         1516 :           if (root_tyty != nullptr && *offset > 0)
     286              :             {
     287              :               // then we can let the impl path probe take over now
     288         1516 :               return root_tyty;
     289              :             }
     290              : 
     291            2 :           rust_error_at (seg.get_locus (),
     292              :                          "failed to type resolve root segment");
     293            2 :           return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
     294              :         }
     295              : 
     296              :       // node back to HIR
     297        63469 :       tl::optional<HirId> hid = mappings.lookup_node_to_hir (ref_node_id);
     298        63469 :       if (!hid.has_value ())
     299              :         {
     300            0 :           rust_error_at (seg.get_locus (), "456 reverse lookup failure");
     301            0 :           rust_debug_loc (seg.get_locus (),
     302              :                           "failure with [%s] mappings [%s] ref_node_id [%u]",
     303              :                           seg.to_string ().c_str (),
     304              :                           seg.get_mappings ().as_string ().c_str (),
     305              :                           ref_node_id);
     306              : 
     307            0 :           return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
     308              :         }
     309        63469 :       auto ref = hid.value ();
     310              : 
     311        63469 :       auto seg_is_module = mappings.lookup_module (ref).has_value ();
     312        63469 :       auto seg_is_crate = mappings.is_local_hirid_crate (ref);
     313        63469 :       auto seg_is_pattern = mappings.lookup_hir_pattern (ref).has_value ();
     314        63469 :       auto seg_is_self = is_root && !have_more_segments
     315       109519 :                          && seg.get_segment ().to_string () == "self";
     316        63469 :       if (seg_is_module || seg_is_crate)
     317              :         {
     318              :           // A::B::C::this_is_a_module::D::E::F
     319              :           //          ^^^^^^^^^^^^^^^^
     320              :           //          Currently handling this.
     321         4760 :           if (have_more_segments)
     322              :             {
     323         4759 :               (*offset)++;
     324         4759 :               continue;
     325              :             }
     326              : 
     327              :           // In the case of :
     328              :           // A::B::C::this_is_a_module
     329              :           //          ^^^^^^^^^^^^^^^^
     330              :           // This is an error, we are not expecting a module.
     331            1 :           rust_error_at (seg.get_locus (), "expected value");
     332            1 :           return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
     333              :         }
     334              : 
     335        58709 :       TyTy::BaseType *lookup = nullptr;
     336        58709 :       if (!query_type (ref, &lookup))
     337              :         {
     338            4 :           if (is_root || root_tyty == nullptr)
     339              :             {
     340            8 :               rust_error_at (expr.get_locus (), ErrorCode::E0425,
     341              :                              "cannot find value %qs in this scope",
     342            8 :                              expr.as_simple_path ().as_string ().c_str ());
     343              : 
     344            4 :               return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
     345              :             }
     346              :           return root_tyty;
     347              :         }
     348              : 
     349              :       // is it an enum item?
     350        58705 :       std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
     351        58705 :         = mappings.lookup_hir_enumitem (ref);
     352       121783 :       bool is_enum_item = enum_item_lookup.first != nullptr
     353        58705 :                           && enum_item_lookup.second != nullptr;
     354         4373 :       if (is_enum_item)
     355              :         {
     356         4373 :           HirId expr_id = expr.get_mappings ().get_hirid ();
     357         4373 :           HirId variant_id
     358         4373 :             = enum_item_lookup.second->get_mappings ().get_hirid ();
     359         4373 :           context->insert_variant_definition (expr_id, variant_id);
     360              :         }
     361              : 
     362              :       // if we have a previous segment type
     363        58705 :       if (root_tyty != nullptr)
     364              :         {
     365              :           // if this next segment needs substitution we must apply the
     366              :           // previous type arguments
     367              :           //
     368              :           // such as: GenericStruct::<_>::new(123, 456)
     369         4231 :           if (lookup->needs_generic_substitutions ())
     370              :             {
     371         1803 :               if (!root_tyty->needs_generic_substitutions ())
     372              :                 {
     373         1803 :                   auto used_args_in_prev_segment
     374         1803 :                     = GetUsedSubstArgs::From (root_tyty);
     375         1803 :                   lookup
     376         1803 :                     = SubstMapperInternal::Resolve (lookup,
     377              :                                                     used_args_in_prev_segment);
     378         1803 :                 }
     379              :             }
     380              :         }
     381              : 
     382              :       // turbo-fish segment path::<ty>
     383        58705 :       if (seg.has_generic_args ())
     384              :         {
     385          965 :           lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
     386          965 :                                          &seg.get_generic_args (),
     387          965 :                                          context->regions_from_generic_args (
     388          965 :                                            seg.get_generic_args ()));
     389          965 :           if (lookup->get_kind () == TyTy::TypeKind::ERROR)
     390            4 :             return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
     391              :         }
     392        57740 :       else if (lookup->needs_generic_substitutions () && !seg_is_pattern
     393        57740 :                && !seg_is_self)
     394              :         {
     395         6085 :           lookup = SubstMapper::InferSubst (lookup, expr.get_locus ());
     396              :         }
     397              : 
     398        58701 :       *root_resolved_node_id = ref_node_id;
     399        58701 :       *offset = *offset + 1;
     400        58701 :       root_tyty = lookup;
     401              :     }
     402              : 
     403              :   return root_tyty;
     404              : }
     405              : 
     406              : void
     407         1555 : TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
     408              :                                  std::vector<HIR::PathExprSegment> &segments,
     409              :                                  size_t offset, TyTy::BaseType *tyseg,
     410              :                                  const Analysis::NodeMapping &expr_mappings,
     411              :                                  location_t expr_locus)
     412              : {
     413         1555 :   NodeId resolved_node_id = root_resolved_node_id;
     414         1555 :   TyTy::BaseType *prev_segment = tyseg;
     415         1555 :   bool receiver_is_generic = prev_segment->get_kind () == TyTy::TypeKind::PARAM;
     416         1555 :   bool receiver_is_dyn = prev_segment->get_kind () == TyTy::TypeKind::DYNAMIC;
     417              : 
     418         4661 :   for (size_t i = offset; i < segments.size (); i++)
     419              :     {
     420         1555 :       bool last_seg = i == segments.size () - 1;
     421         1555 :       HIR::PathExprSegment &seg = segments.at (i);
     422              : 
     423         1555 :       std::set<PathProbeCandidate> candidates;
     424         1555 :       if (last_seg)
     425         1555 :         candidates = PathProbeExpr::Probe (tyseg, seg.get_segment ());
     426              :       else
     427              :         {
     428            0 :           auto type_candidates
     429            0 :             = TypePathProbe::Probe (tyseg, seg.get_segment ());
     430            0 :           candidates = type_candidates.type_candidates;
     431            0 :         }
     432              : 
     433         1555 :       if (candidates.size () == 0)
     434              :         {
     435            2 :           rust_error_at (seg.get_locus (),
     436              :                          "failed to resolve path segment using an impl Probe");
     437            2 :           return;
     438              :         }
     439              : 
     440         1553 :       if (candidates.size () > 1)
     441              :         {
     442            1 :           ReportMultipleCandidateError::Report (candidates, seg.get_segment (),
     443              :                                                 seg.get_locus ());
     444            1 :           return;
     445              :         }
     446              : 
     447         1552 :       auto &candidate = *candidates.begin ();
     448         1552 :       prev_segment = tyseg;
     449         1552 :       tyseg = candidate.ty;
     450              : 
     451         1552 :       HIR::ImplBlock *associated_impl_block = nullptr;
     452         1552 :       if (candidate.is_enum_candidate ())
     453              :         {
     454            1 :           const TyTy::VariantDef *variant = candidate.item.enum_field.variant;
     455              : 
     456            1 :           HirId variant_id = variant->get_id ();
     457            1 :           std::pair<HIR::Enum *, HIR::EnumItem *> enum_item_lookup
     458            1 :             = mappings.lookup_hir_enumitem (variant_id);
     459            2 :           bool enum_item_ok = enum_item_lookup.first != nullptr
     460            1 :                               && enum_item_lookup.second != nullptr;
     461            0 :           rust_assert (enum_item_ok);
     462              : 
     463            1 :           HIR::EnumItem *enum_item = enum_item_lookup.second;
     464            1 :           resolved_node_id = enum_item->get_mappings ().get_nodeid ();
     465              : 
     466              :           // insert the id of the variant we are resolved to
     467            1 :           context->insert_variant_definition (expr_mappings.get_hirid (),
     468              :                                               variant_id);
     469              :         }
     470         1551 :       else if (candidate.is_impl_candidate ())
     471              :         {
     472          999 :           resolved_node_id
     473          999 :             = candidate.item.impl.impl_item->get_impl_mappings ().get_nodeid ();
     474              : 
     475          999 :           associated_impl_block = candidate.item.impl.parent;
     476              :         }
     477              :       else
     478              :         {
     479          552 :           resolved_node_id
     480          552 :             = candidate.item.trait.item_ref->get_mappings ().get_nodeid ();
     481              : 
     482              :           // lookup the associated-impl-trait
     483          552 :           HIR::ImplBlock *impl = candidate.item.trait.impl;
     484          552 :           if (impl != nullptr)
     485              :             {
     486              :               // get the associated impl block
     487              :               associated_impl_block = impl;
     488              :             }
     489              :         }
     490              : 
     491         1552 :       if (associated_impl_block != nullptr && !receiver_is_dyn)
     492              :         {
     493              :           // unify the segments receiver against the impls self so
     494              :           // infer vars on either side get pinned
     495         1043 :           auto mappings = TyTy::SubstitutionArgumentMappings::error ();
     496         1043 :           TyTy::BaseType *impl_block_ty
     497         1043 :             = TypeCheckItem::ResolveImplBlockSelfWithInference (
     498              :               *associated_impl_block, seg.get_locus (), &mappings);
     499              : 
     500         1043 :           if (!mappings.is_error ())
     501          192 :             tyseg = SubstMapperInternal::Resolve (tyseg, mappings);
     502              : 
     503         2086 :           prev_segment = unify_site (seg.get_mappings ().get_hirid (),
     504         1043 :                                      TyTy::TyWithLocation (prev_segment),
     505         1043 :                                      TyTy::TyWithLocation (impl_block_ty),
     506              :                                      seg.get_locus ());
     507         1043 :           if (prev_segment->get_kind () == TyTy::TypeKind::ERROR)
     508            1 :             return;
     509         1043 :         }
     510              : 
     511         1551 :       if (seg.has_generic_args ())
     512              :         {
     513           46 :           rust_debug_loc (seg.get_locus (), "applying segment generics: %s",
     514              :                           tyseg->as_string ().c_str ());
     515           46 :           tyseg
     516           46 :             = SubstMapper::Resolve (tyseg, expr_locus, &seg.get_generic_args (),
     517           46 :                                     context->regions_from_generic_args (
     518           46 :                                       seg.get_generic_args ()));
     519           46 :           if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
     520              :             return;
     521              :         }
     522         1505 :       else if (tyseg->needs_generic_substitutions () && !receiver_is_generic)
     523              :         {
     524          420 :           location_t locus = seg.get_locus ();
     525          420 :           tyseg = SubstMapper::InferSubst (tyseg, locus);
     526          420 :           if (tyseg->get_kind () == TyTy::TypeKind::ERROR)
     527              :             return;
     528              :         }
     529         1555 :     }
     530              : 
     531         1551 :   rust_assert (resolved_node_id != UNKNOWN_NODEID);
     532              : 
     533         1551 :   auto &nr_ctx = Resolver2_0::FinalizedNameResolutionContext::get ();
     534              : 
     535         1551 :   nr_ctx.map_usage (Resolver2_0::Usage (expr_mappings.get_nodeid ()),
     536         1551 :                     Resolver2_0::Definition (resolved_node_id),
     537              :                     Resolver2_0::Namespace::Values);
     538              : 
     539         1551 :   infered = tyseg;
     540              : }
     541              : 
     542              : } // namespace Resolver
     543              : } // namespace Rust
        

Generated by: LCOV version 2.4-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.