LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-path-probe-type.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.2 % 101 84
Test Date: 2026-10-03 16:17:38 Functions: 100.0 % 9 9
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-hir-path-probe-type.h"
      20              : #include "rust-hir-map.h"
      21              : #include "rust-hir-trait-resolve.h"
      22              : #include "rust-hir.h"
      23              : #include "rust-type-util.h"
      24              : #include "rust-tyty.h"
      25              : 
      26              : namespace Rust {
      27              : namespace Resolver {
      28              : 
      29              : TypePathProbeResult
      30          207 : TypePathProbe::Probe (TyTy::BaseType *receiver,
      31              :                       const HIR::PathIdentSegment &segment_name)
      32              : {
      33          207 :   TypePathProbe probe (receiver, segment_name);
      34          207 :   return probe.probe ();
      35          207 : }
      36              : 
      37              : TypePathProbeResult
      38          207 : TypePathProbe::probe ()
      39              : {
      40          207 :   switch (receiver->get_kind ())
      41              :     {
      42          183 :     case TyTy::TypeKind::PARAM:
      43          183 :     case TyTy::TypeKind::DYNAMIC:
      44          183 :       probe_generic ();
      45          183 :       break;
      46              : 
      47           14 :     case TyTy::TypeKind::ADT:
      48           14 :       probe_adt (static_cast<TyTy::ADTType *> (receiver));
      49           14 :       break;
      50              : 
      51           10 :     default:
      52           10 :       probe_fallback ();
      53           10 :       break;
      54              :     }
      55              : 
      56          207 :   return std::move (result);
      57              : }
      58              : 
      59              : void
      60          183 : TypePathProbe::probe_generic ()
      61              : {
      62          355 :   for (const TyTy::TypeBoundPredicate &predicate :
      63          538 :        receiver->get_specified_bounds ())
      64              :     {
      65          355 :       auto candidate = process_predicate_for_candidates (predicate);
      66          355 :       insert_candidate (std::move (candidate));
      67              :     }
      68          183 : }
      69              : 
      70              : void
      71           14 : TypePathProbe::probe_adt (TyTy::ADTType *adt)
      72              : {
      73           14 :   auto adt_item = mappings.lookup_defid (adt->get_id ());
      74           14 :   if (!adt_item.has_value ())
      75              :     {
      76            0 :       probe_fallback ();
      77            0 :       return;
      78              :     }
      79              : 
      80           14 :   DefId adt_id = adt_item.value ()->get_mappings ().get_defid ();
      81           14 :   mappings.iterate_adt_impl_items (adt_id,
      82           28 :                                    [this] (HirId id, HIR::ImplItem *item,
      83              :                                            HIR::ImplBlock *impl) -> bool {
      84           98 :                                      return process_impl_item (id, item, impl);
      85              :                                    });
      86              : }
      87              : 
      88              : void
      89           10 : TypePathProbe::probe_fallback ()
      90              : {
      91           10 :   mappings.iterate_impl_items (
      92           10 :     [&] (HirId id, HIR::ImplItem *item, HIR::ImplBlock *impl) mutable -> bool {
      93           22 :       return process_impl_item (id, item, impl);
      94              :     });
      95           10 : }
      96              : 
      97              : bool
      98          120 : TypePathProbe::process_impl_item (HirId id, HIR::ImplItem *item,
      99              :                                   HIR::ImplBlock *impl)
     100              : {
     101          120 :   auto item_name = item->get_impl_item_name ();
     102          240 :   if (search.to_string () != item_name)
     103              :     return true;
     104              : 
     105           52 :   HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
     106           52 :   TyTy::BaseType *impl_block_ty = nullptr;
     107           52 :   if (!query_type (impl_ty_id, &impl_block_ty))
     108              :     return true;
     109              : 
     110           52 :   if (!types_compatable (TyTy::TyWithLocation (receiver),
     111           52 :                          TyTy::TyWithLocation (impl_block_ty),
     112              :                          impl->get_locus (), false))
     113              :     return true;
     114              : 
     115              :   // Keep trait impl items at trait position.  In particular, do not query the
     116              :   // type of an impl associated-type alias here: projection normalization will
     117              :   // select and evaluate the concrete alias later.
     118           24 :   if (impl->has_trait_ref ())
     119              :     {
     120           24 :       process_trait_impl_item (impl);
     121           24 :       return true;
     122              :     }
     123              : 
     124            0 :   TyTy::BaseType *item_ty = nullptr;
     125            0 :   if (!query_type (id, &item_ty))
     126              :     return true;
     127              : 
     128            0 :   PathProbeCandidate::CandidateType candidate_type;
     129            0 :   switch (item->get_impl_item_type ())
     130              :     {
     131              :     case HIR::ImplItem::FUNCTION:
     132              :       candidate_type = PathProbeCandidate::IMPL_FUNC;
     133              :       break;
     134              : 
     135              :     case HIR::ImplItem::TYPE_ALIAS:
     136              :       candidate_type = PathProbeCandidate::IMPL_TYPE_ALIAS;
     137              :       break;
     138              : 
     139              :     case HIR::ImplItem::CONSTANT:
     140              :       candidate_type = PathProbeCandidate::IMPL_CONST;
     141              :       break;
     142              : 
     143              :     default:
     144              :       return true;
     145              :     }
     146              : 
     147            0 :   PathProbeCandidate::ImplItemCandidate impl_candidate{item, impl};
     148              : 
     149            0 :   insert_candidate (
     150            0 :     {candidate_type, item_ty, item->get_locus (), impl_candidate});
     151              : 
     152            0 :   return true;
     153          120 : }
     154              : 
     155              : void
     156           24 : TypePathProbe::process_trait_impl_item (HIR::ImplBlock *impl)
     157              : {
     158           24 :   HIR::TypePath &trait_path = impl->get_trait_ref ();
     159           24 :   TraitReference *trait_ref = TraitResolver::Lookup (trait_path);
     160           24 :   if (trait_ref->is_error ())
     161            0 :     trait_ref = TraitResolver::Resolve (trait_path);
     162           24 :   if (trait_ref->is_error ())
     163            0 :     return;
     164              : 
     165           24 :   TyTy::TypeBoundPredicate predicate (*trait_ref, BoundPolarity::RegularBound,
     166           24 :                                       impl->get_locus ());
     167           24 :   auto candidate = process_predicate_for_candidates (predicate);
     168           24 :   if (candidate.is_error ())
     169            0 :     return;
     170              : 
     171           24 :   rust_assert (candidate.is_trait_candidate ());
     172           24 :   candidate.item.trait.impl = impl;
     173           24 :   insert_candidate (std::move (candidate));
     174           24 : }
     175              : 
     176              : PathProbeCandidate
     177          379 : TypePathProbe::process_predicate_for_candidates (
     178              :   const TyTy::TypeBoundPredicate &predicate)
     179              : {
     180          379 :   tl::optional<TyTy::TypeBoundPredicateItem> item
     181          758 :     = predicate.lookup_associated_item (search.to_string ());
     182          379 :   if (!item.has_value ())
     183          173 :     return PathProbeCandidate::get_error ();
     184              : 
     185          206 :   const TraitReference *trait_ref = item->get_parent ()->get ();
     186          206 :   const TraitItemReference *trait_item_ref = item->get_raw_item ();
     187          206 :   PathProbeCandidate::CandidateType candidate_type;
     188          206 :   switch (trait_item_ref->get_trait_item_type ())
     189              :     {
     190              :     case TraitItemReference::TraitItemType::FN:
     191              :       candidate_type = PathProbeCandidate::CandidateType::TRAIT_FUNC;
     192              :       break;
     193              :     case TraitItemReference::TraitItemType::CONST:
     194              :       candidate_type = PathProbeCandidate::CandidateType::TRAIT_ITEM_CONST;
     195              :       break;
     196              :     case TraitItemReference::TraitItemType::TYPE:
     197              :       candidate_type = PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS;
     198              :       break;
     199              : 
     200            0 :     case TraitItemReference::TraitItemType::ERROR:
     201            0 :     default:
     202            0 :       return PathProbeCandidate::get_error ();
     203              :     }
     204              : 
     205          206 :   TyTy::BaseType *trait_item_tyty = item->get_raw_item ()->get_tyty ();
     206          206 :   if (receiver->get_kind () != TyTy::DYNAMIC)
     207          206 :     trait_item_tyty = item->get_tyty_for_receiver (receiver);
     208              : 
     209          206 :   PathProbeCandidate::TraitItemCandidate trait_item_candidate{trait_ref,
     210              :                                                               trait_item_ref,
     211          206 :                                                               nullptr};
     212          206 :   return {candidate_type, trait_item_tyty, trait_item_ref->get_locus (),
     213          206 :           trait_item_candidate};
     214          379 : }
     215              : 
     216              : void
     217          379 : TypePathProbe::insert_candidate (PathProbeCandidate candidate)
     218              : {
     219          379 :   if (candidate.is_error ())
     220              :     return;
     221              : 
     222          206 :   bool is_type
     223          206 :     = candidate.type == PathProbeCandidate::CandidateType::IMPL_TYPE_ALIAS
     224          206 :       || candidate.type == PathProbeCandidate::CandidateType::TRAIT_TYPE_ALIAS;
     225          206 :   if (is_type)
     226          206 :     result.type_candidates.insert (std::move (candidate));
     227              :   else
     228            0 :     result.non_type_matches.insert (std::move (candidate));
     229              : }
     230              : 
     231              : } // namespace Resolver
     232              : } // 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.