LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check-base.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.5 % 398 376
Test Date: 2026-04-20 14:57:17 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-type-check-base.h"
      20              : #include "rust-compile-base.h"
      21              : #include "rust-hir-item.h"
      22              : #include "rust-hir-type-check-expr.h"
      23              : #include "rust-hir-type-check-type.h"
      24              : #include "rust-hir-trait-resolve.h"
      25              : #include "rust-type-util.h"
      26              : #include "rust-attribute-values.h"
      27              : #include "rust-tyty.h"
      28              : #include "tree.h"
      29              : 
      30              : namespace Rust {
      31              : namespace Resolver {
      32              : 
      33      2773345 : TypeCheckBase::TypeCheckBase ()
      34      2773345 :   : mappings (Analysis::Mappings::get ()), context (TypeCheckContext::get ())
      35      2773345 : {}
      36              : 
      37              : void
      38           43 : TypeCheckBase::ResolveGenericParams (
      39              :   const HIR::Item::ItemKind item_kind, location_t item_locus,
      40              :   const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
      41              :   std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
      42              :   ABI abi)
      43              : {
      44           43 :   TypeCheckBase ctx;
      45           43 :   ctx.resolve_generic_params (item_kind, item_locus, generic_params,
      46              :                               substitutions, is_foreign, abi);
      47           43 : }
      48              : 
      49              : static void
      50        11531 : walk_types_to_constrain (std::set<HirId> &constrained_symbols,
      51              :                          const TyTy::SubstitutionArgumentMappings &constraints)
      52              : {
      53        18380 :   for (const auto &c : constraints.get_mappings ())
      54              :     {
      55         6849 :       auto arg = c.get_tyty ();
      56         6849 :       if (arg != nullptr)
      57              :         {
      58         6849 :           const auto p = arg->get_root ();
      59         6849 :           constrained_symbols.insert (p->get_ref ());
      60         6849 :           constrained_symbols.insert (p->get_ty_ref ());
      61              : 
      62         6849 :           if (p->has_substitutions_defined ())
      63              :             {
      64          245 :               walk_types_to_constrain (constrained_symbols,
      65              :                                        p->get_subst_argument_mappings ());
      66              :             }
      67              :         }
      68              :     }
      69        11531 : }
      70              : 
      71              : static void
      72         5643 : walk_type_to_constrain (std::set<HirId> &constrained_symbols, TyTy::BaseType &r)
      73              : {
      74         6124 :   switch (r.get_kind ())
      75              :     {
      76          164 :     case TyTy::TypeKind::POINTER:
      77          164 :       {
      78          164 :         auto &p = static_cast<TyTy::PointerType &> (r);
      79          164 :         walk_type_to_constrain (constrained_symbols, *p.get_base ());
      80              :       }
      81          164 :       break;
      82          189 :     case TyTy::TypeKind::REF:
      83          189 :       {
      84          189 :         auto &ref = static_cast<TyTy::ReferenceType &> (r);
      85          189 :         walk_type_to_constrain (constrained_symbols, *ref.get_base ());
      86              :       }
      87          189 :       break;
      88            1 :     case TyTy::TypeKind::ARRAY:
      89            1 :       {
      90            1 :         auto &arr = static_cast<TyTy::ArrayType &> (r);
      91            1 :         walk_type_to_constrain (constrained_symbols, *arr.get_element_type ());
      92              :       }
      93            1 :       break;
      94            0 :     case TyTy::TypeKind::FNDEF:
      95            0 :       {
      96            0 :         auto &fn = static_cast<TyTy::FnType &> (r);
      97            0 :         for (auto &param : fn.get_params ())
      98            0 :           walk_type_to_constrain (constrained_symbols, *param.get_type ());
      99            0 :         walk_type_to_constrain (constrained_symbols, *fn.get_return_type ());
     100              :       }
     101            0 :       break;
     102          515 :     case TyTy::TypeKind::PARAM:
     103          515 :       {
     104          515 :         auto &param = static_cast<TyTy::ParamType &> (r);
     105          515 :         constrained_symbols.insert (param.get_ty_ref ());
     106              :       }
     107          515 :       break;
     108          116 :     case TyTy::SLICE:
     109          116 :       {
     110          116 :         auto &slice = static_cast<TyTy::SliceType &> (r);
     111          116 :         walk_type_to_constrain (constrained_symbols,
     112          116 :                                 *slice.get_element_type ());
     113              :       }
     114          116 :       break;
     115           11 :     case TyTy::FNPTR:
     116           11 :       {
     117           11 :         auto &ptr = static_cast<TyTy::FnPtr &> (r);
     118           11 :         for (auto &param : ptr.get_params ())
     119            0 :           walk_type_to_constrain (constrained_symbols, *param.get_tyty ());
     120           11 :         walk_type_to_constrain (constrained_symbols, *ptr.get_return_type ());
     121              :       }
     122           11 :       break;
     123            3 :     case TyTy::TUPLE:
     124            3 :       {
     125            3 :         auto &tuple = static_cast<TyTy::TupleType &> (r);
     126            3 :         for (auto &ty : tuple.get_fields ())
     127            0 :           walk_type_to_constrain (constrained_symbols, *ty.get_tyty ());
     128              :       }
     129              :       break;
     130           10 :     case TyTy::DYNAMIC:
     131           10 :       {
     132           10 :         auto &dyn = static_cast<TyTy::DynamicObjectType &> (r);
     133           10 :         constrained_symbols.insert (dyn.get_ty_ref ());
     134              :       }
     135           10 :       break;
     136            0 :     case TyTy::CLOSURE:
     137            0 :       {
     138            0 :         auto &clos = static_cast<TyTy::ClosureType &> (r);
     139            0 :         walk_type_to_constrain (constrained_symbols, clos.get_parameters ());
     140            0 :         walk_type_to_constrain (constrained_symbols, *clos.get_return_type ());
     141              :       }
     142            0 :       break;
     143              :     default:
     144              :       break;
     145              :     }
     146         5643 : }
     147              : 
     148              : bool
     149        41266 : TypeCheckBase::check_for_unconstrained (
     150              :   const std::vector<TyTy::SubstitutionParamMapping> &params_to_constrain,
     151              :   const TyTy::SubstitutionArgumentMappings &constraint_a,
     152              :   const TyTy::SubstitutionArgumentMappings &constraint_b,
     153              :   TyTy::BaseType *reference)
     154              : {
     155        41266 :   bool check_result = false;
     156        41266 :   bool check_completed
     157        41266 :     = context->have_checked_for_unconstrained (reference->get_ref (),
     158              :                                                &check_result);
     159        41266 :   if (check_completed)
     160        35623 :     return check_result;
     161              : 
     162         5643 :   std::set<HirId> symbols_to_constrain;
     163         5643 :   std::map<HirId, location_t> symbol_to_location;
     164         6638 :   for (const auto &p : params_to_constrain)
     165              :     {
     166          995 :       HirId ref = p.get_param_ty ()->get_ref ();
     167          995 :       symbols_to_constrain.insert (ref);
     168          995 :       symbol_to_location.insert ({ref, p.get_param_locus ()});
     169              :     }
     170              : 
     171              :   // set up the set of constrained symbols
     172        11286 :   std::set<HirId> constrained_symbols;
     173         5643 :   walk_types_to_constrain (constrained_symbols, constraint_a);
     174         5643 :   walk_types_to_constrain (constrained_symbols, constraint_b);
     175         5643 :   walk_type_to_constrain (constrained_symbols, *reference);
     176              : 
     177              :   // check for unconstrained
     178         5643 :   bool unconstrained = false;
     179         6638 :   for (auto &sym : symbols_to_constrain)
     180              :     {
     181          995 :       bool used = constrained_symbols.find (sym) != constrained_symbols.end ();
     182          995 :       if (!used)
     183              :         {
     184            4 :           location_t locus = symbol_to_location.at (sym);
     185            4 :           rust_error_at (locus, "unconstrained type parameter");
     186            4 :           unconstrained = true;
     187              :         }
     188              :     }
     189              : 
     190         5643 :   context->insert_unconstrained_check_marker (reference->get_ref (),
     191              :                                               unconstrained);
     192              : 
     193         5643 :   return unconstrained;
     194         5643 : }
     195              : 
     196              : TyTy::BaseType *
     197        20725 : TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
     198              :                                 HIR::Literal &literal, location_t locus)
     199              : {
     200        20725 :   TyTy::BaseType *infered = nullptr;
     201        20725 :   switch (literal.get_lit_type ())
     202              :     {
     203        16083 :     case HIR::Literal::LitType::INT:
     204        16083 :       {
     205        16083 :         bool ok = false;
     206              : 
     207        16083 :         switch (literal.get_type_hint ())
     208              :           {
     209           92 :           case CORETYPE_I8:
     210           92 :             ok = context->lookup_builtin ("i8", &infered);
     211           92 :             break;
     212           86 :           case CORETYPE_I16:
     213           86 :             ok = context->lookup_builtin ("i16", &infered);
     214           86 :             break;
     215          247 :           case CORETYPE_I32:
     216          247 :             ok = context->lookup_builtin ("i32", &infered);
     217          247 :             break;
     218           84 :           case CORETYPE_I64:
     219           84 :             ok = context->lookup_builtin ("i64", &infered);
     220           84 :             break;
     221           14 :           case CORETYPE_I128:
     222           14 :             ok = context->lookup_builtin ("i128", &infered);
     223           14 :             break;
     224              : 
     225          134 :           case CORETYPE_U8:
     226          134 :             ok = context->lookup_builtin ("u8", &infered);
     227          134 :             break;
     228          131 :           case CORETYPE_U16:
     229          131 :             ok = context->lookup_builtin ("u16", &infered);
     230          131 :             break;
     231          216 :           case CORETYPE_U32:
     232          216 :             ok = context->lookup_builtin ("u32", &infered);
     233          216 :             break;
     234          120 :           case CORETYPE_U64:
     235          120 :             ok = context->lookup_builtin ("u64", &infered);
     236          120 :             break;
     237           17 :           case CORETYPE_U128:
     238           17 :             ok = context->lookup_builtin ("u128", &infered);
     239           17 :             break;
     240              : 
     241          466 :           case CORETYPE_F32:
     242          466 :             literal.set_lit_type (HIR::Literal::LitType::FLOAT);
     243          466 :             ok = context->lookup_builtin ("f32", &infered);
     244          466 :             break;
     245          205 :           case CORETYPE_F64:
     246          205 :             literal.set_lit_type (HIR::Literal::LitType::FLOAT);
     247          205 :             ok = context->lookup_builtin ("f64", &infered);
     248          205 :             break;
     249              : 
     250            3 :           case CORETYPE_ISIZE:
     251            3 :             ok = context->lookup_builtin ("isize", &infered);
     252            3 :             break;
     253              : 
     254           34 :           case CORETYPE_USIZE:
     255           34 :             ok = context->lookup_builtin ("usize", &infered);
     256           34 :             break;
     257              : 
     258        14234 :           default:
     259        14234 :             ok = true;
     260        14234 :             infered
     261        14234 :               = new TyTy::InferType (expr_mappings.get_hirid (),
     262              :                                      TyTy::InferType::InferTypeKind::INTEGRAL,
     263              :                                      TyTy::InferType::TypeHint::Default (),
     264        14234 :                                      locus);
     265        14234 :             break;
     266              :           }
     267        16083 :         rust_assert (ok);
     268              :       }
     269              :       break;
     270              : 
     271          331 :     case HIR::Literal::LitType::FLOAT:
     272          331 :       {
     273          331 :         bool ok = false;
     274              : 
     275          331 :         switch (literal.get_type_hint ())
     276              :           {
     277           30 :           case CORETYPE_F32:
     278           30 :             ok = context->lookup_builtin ("f32", &infered);
     279           30 :             break;
     280           16 :           case CORETYPE_F64:
     281           16 :             ok = context->lookup_builtin ("f64", &infered);
     282           16 :             break;
     283              : 
     284          285 :           default:
     285          285 :             ok = true;
     286          285 :             infered
     287          285 :               = new TyTy::InferType (expr_mappings.get_hirid (),
     288              :                                      TyTy::InferType::InferTypeKind::FLOAT,
     289              :                                      TyTy::InferType::TypeHint::Default (),
     290          285 :                                      locus);
     291          285 :             break;
     292              :           }
     293          331 :         rust_assert (ok);
     294              :       }
     295              :       break;
     296              : 
     297         1303 :     case HIR::Literal::LitType::BOOL:
     298         1303 :       {
     299         1303 :         auto ok = context->lookup_builtin ("bool", &infered);
     300         1303 :         rust_assert (ok);
     301              :       }
     302              :       break;
     303              : 
     304          186 :     case HIR::Literal::LitType::CHAR:
     305          186 :       {
     306          186 :         auto ok = context->lookup_builtin ("char", &infered);
     307          186 :         rust_assert (ok);
     308              :       }
     309              :       break;
     310              : 
     311          408 :     case HIR::Literal::LitType::BYTE:
     312          408 :       {
     313          408 :         auto ok = context->lookup_builtin ("u8", &infered);
     314          408 :         rust_assert (ok);
     315              :       }
     316              :       break;
     317              : 
     318         2379 :     case HIR::Literal::LitType::STRING:
     319         2379 :       {
     320         2379 :         TyTy::BaseType *base = nullptr;
     321         2379 :         auto ok = context->lookup_builtin ("str", &base);
     322         2379 :         rust_assert (ok);
     323              : 
     324         4758 :         infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
     325         2379 :                                            TyTy::TyVar (base->get_ref ()),
     326              :                                            Mutability::Imm,
     327         4758 :                                            TyTy::Region::make_static ());
     328              :       }
     329         2379 :       break;
     330              : 
     331           35 :     case HIR::Literal::LitType::BYTE_STRING:
     332           35 :       {
     333              :         /* This is an arraytype of u8 reference (&[u8;size]). It isn't in
     334              :            UTF-8, but really just a byte array. Code to construct the array
     335              :            reference copied from ArrayElemsValues and ArrayType. */
     336           35 :         TyTy::BaseType *u8;
     337           35 :         auto ok = context->lookup_builtin ("u8", &u8);
     338           35 :         rust_assert (ok);
     339              : 
     340           35 :         auto crate_num = mappings.get_current_crate ();
     341           35 :         Analysis::NodeMapping capacity_mapping (crate_num, UNKNOWN_NODEID,
     342           35 :                                                 mappings.get_next_hir_id (
     343              :                                                   crate_num),
     344           35 :                                                 UNKNOWN_LOCAL_DEFID);
     345              : 
     346              :         /* Capacity is the size of the string (number of chars).
     347              :            It is a constant, but for fold it to get a tree.  */
     348           35 :         std::string capacity_str
     349           35 :           = std::to_string (literal.as_string ().size ());
     350           35 :         HIR::LiteralExpr *literal_capacity
     351              :           = new HIR::LiteralExpr (capacity_mapping, capacity_str,
     352              :                                   HIR::Literal::LitType::INT,
     353           70 :                                   PrimitiveCoreType::CORETYPE_USIZE, locus, {});
     354              : 
     355              :         // mark the type for this implicit node
     356           35 :         TyTy::BaseType *expected_ty = nullptr;
     357           35 :         ok = context->lookup_builtin ("usize", &expected_ty);
     358           35 :         rust_assert (ok);
     359           35 :         context->insert_type (capacity_mapping, expected_ty);
     360              : 
     361           35 :         Analysis::NodeMapping array_mapping (crate_num, UNKNOWN_NODEID,
     362           35 :                                              mappings.get_next_hir_id (
     363              :                                                crate_num),
     364           35 :                                              UNKNOWN_LOCAL_DEFID);
     365              : 
     366           35 :         auto ctx = Compile::Context::get ();
     367           35 :         tree capacity = Compile::HIRCompileBase::query_compile_const_expr (
     368              :           ctx, expected_ty, *literal_capacity);
     369              : 
     370           35 :         HirId capacity_expr_id = literal_capacity->get_mappings ().get_hirid ();
     371           35 :         auto capacity_expr
     372              :           = new TyTy::ConstValueType (capacity, expected_ty, capacity_expr_id,
     373           35 :                                       capacity_expr_id);
     374           35 :         context->insert_type (literal_capacity->get_mappings (),
     375           35 :                               capacity_expr->as_base_type ());
     376              : 
     377           35 :         TyTy::ArrayType *array = new TyTy::ArrayType (
     378              :           array_mapping.get_hirid (), locus,
     379           35 :           TyTy::TyVar (capacity_expr->as_base_type ()->get_ty_ref ()),
     380           70 :           TyTy::TyVar (u8->get_ref ()));
     381           35 :         context->insert_type (array_mapping, array);
     382              : 
     383           70 :         infered = new TyTy::ReferenceType (expr_mappings.get_hirid (),
     384           35 :                                            TyTy::TyVar (array->get_ref ()),
     385              :                                            Mutability::Imm,
     386           70 :                                            TyTy::Region::make_static ());
     387           35 :       }
     388           35 :       break;
     389              : 
     390            0 :     default:
     391            0 :       rust_unreachable ();
     392        20725 :       break;
     393              :     }
     394              : 
     395        20725 :   return infered;
     396              : }
     397              : 
     398              : TyTy::ADTType::ReprOptions
     399         2983 : TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
     400              : {
     401         2983 :   TyTy::ADTType::ReprOptions repr;
     402         2983 :   repr.pack = 0;
     403         2983 :   repr.align = 0;
     404              : 
     405              :   // Default repr for enums is isize, but we now check for other repr in the
     406              :   // attributes.
     407         2983 :   bool ok = context->lookup_builtin ("isize", &repr.repr);
     408         2983 :   rust_assert (ok);
     409              : 
     410         3396 :   for (const auto &attr : attrs)
     411              :     {
     412          440 :       bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
     413          440 :       if (is_repr && !attr.has_attr_input ())
     414              :         {
     415            1 :           rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
     416            1 :           continue;
     417              :         }
     418              : 
     419          439 :       if (is_repr)
     420              :         {
     421           29 :           const AST::AttrInput &input = attr.get_attr_input ();
     422           29 :           bool is_token_tree = input.get_attr_input_type ()
     423           29 :                                == AST::AttrInput::AttrInputType::TOKEN_TREE;
     424           29 :           bool is_meta_item = input.get_attr_input_type ()
     425           29 :                               == AST::AttrInput::AttrInputType::META_ITEM;
     426           29 :           if (!is_token_tree && !is_meta_item)
     427              :             {
     428            1 :               rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
     429            2 :               continue;
     430              :             }
     431              : 
     432           28 :           const AST::AttrInputMetaItemContainer *meta_items = nullptr;
     433           28 :           if (is_token_tree)
     434              :             {
     435           27 :               const auto &option
     436              :                 = static_cast<const AST::DelimTokenTree &> (input);
     437           27 :               meta_items = option.parse_to_meta_item ();
     438              :             }
     439              :           else
     440              :             { // is_meta_item is true
     441            1 :               const auto &option
     442              :                 = static_cast<const AST::AttrInputMetaItemContainer &> (input);
     443            1 :               meta_items = new AST::AttrInputMetaItemContainer (option);
     444              :             }
     445              : 
     446           28 :           if (meta_items == nullptr)
     447              :             {
     448            0 :               rust_error_at (attr.get_locus (), "malformed %qs attribute",
     449              :                              "repr");
     450            0 :               continue;
     451              :             }
     452              : 
     453           28 :           auto &items = meta_items->get_items ();
     454           28 :           if (items.size () == 0)
     455              :             {
     456              :               // nothing to do with this its empty
     457            1 :               delete meta_items;
     458            1 :               continue;
     459              :             }
     460              : 
     461           27 :           const std::string inline_option = items.at (0)->as_string ();
     462              : 
     463              :           // TODO: it would probably be better to make the MetaItems more aware
     464              :           // of constructs with nesting like #[repr(packed(2))] rather than
     465              :           // manually parsing the string "packed(2)" here.
     466              : 
     467           27 :           size_t oparen = inline_option.find ('(', 0);
     468           27 :           bool is_pack = false;
     469           27 :           bool is_align = false;
     470           27 :           bool is_c = false;
     471           27 :           bool is_integer = false;
     472           27 :           unsigned char value = 1;
     473              : 
     474           27 :           if (oparen == std::string::npos)
     475              :             {
     476           21 :               is_pack = inline_option.compare ("packed") == 0;
     477           21 :               is_align = inline_option.compare ("align") == 0;
     478           21 :               is_c = inline_option.compare ("C") == 0;
     479           21 :               is_integer = (inline_option.compare ("isize") == 0
     480           21 :                             || inline_option.compare ("i8") == 0
     481           21 :                             || inline_option.compare ("i16") == 0
     482           21 :                             || inline_option.compare ("i32") == 0
     483           19 :                             || inline_option.compare ("i64") == 0
     484           19 :                             || inline_option.compare ("i128") == 0
     485           19 :                             || inline_option.compare ("usize") == 0
     486           19 :                             || inline_option.compare ("u8") == 0
     487           19 :                             || inline_option.compare ("u16") == 0
     488           19 :                             || inline_option.compare ("u32") == 0
     489           19 :                             || inline_option.compare ("u64") == 0
     490           40 :                             || inline_option.compare ("u128") == 0);
     491              :             }
     492              : 
     493              :           else
     494              :             {
     495            6 :               std::string rep = inline_option.substr (0, oparen);
     496            6 :               is_pack = rep.compare ("packed") == 0;
     497            6 :               is_align = rep.compare ("align") == 0;
     498              : 
     499            6 :               size_t cparen = inline_option.find (')', oparen);
     500            6 :               if (cparen == std::string::npos)
     501              :                 {
     502            0 :                   rust_error_at (locus, "malformed attribute");
     503              :                 }
     504              : 
     505            6 :               std::string value_str = inline_option.substr (oparen, cparen);
     506            6 :               value = strtoul (value_str.c_str () + 1, NULL, 10);
     507            6 :             }
     508              : 
     509           27 :           if (is_pack)
     510              :             {
     511            4 :               repr.repr_kind = TyTy::ADTType::ReprKind::PACKED;
     512            4 :               repr.pack = value;
     513              :             }
     514           23 :           else if (is_align)
     515              :             {
     516            4 :               repr.repr_kind = TyTy::ADTType::ReprKind::ALIGN;
     517            4 :               repr.align = value;
     518              :             }
     519           19 :           else if (is_c)
     520              :             {
     521           15 :               repr.repr_kind = TyTy::ADTType::ReprKind::C;
     522              :             }
     523            4 :           else if (is_integer)
     524              :             {
     525            2 :               repr.repr_kind = TyTy::ADTType::ReprKind::INT;
     526            4 :               bool ok = context->lookup_builtin (inline_option, &repr.repr);
     527            2 :               if (!ok)
     528              :                 {
     529            0 :                   rust_error_at (attr.get_locus (), "Invalid repr type");
     530              :                 }
     531              :             }
     532              : 
     533           27 :           delete meta_items;
     534              : 
     535              :           // Multiple repr options must be specified with e.g. #[repr(C,
     536              :           // packed(2))].
     537           27 :           break;
     538           27 :         }
     539              :     }
     540              : 
     541         2983 :   return repr;
     542              : }
     543              : 
     544              : void
     545         8735 : TypeCheckBase::resolve_generic_params (
     546              :   const HIR::Item::ItemKind item_kind, location_t item_locus,
     547              :   const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
     548              :   std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
     549              :   ABI abi)
     550              : {
     551        18466 :   for (auto &generic_param : generic_params)
     552              :     {
     553         9731 :       switch (generic_param->get_kind ())
     554              :         {
     555          887 :         case HIR::GenericParam::GenericKind::LIFETIME:
     556          887 :           {
     557          887 :             auto lifetime_param
     558          887 :               = static_cast<HIR::LifetimeParam &> (*generic_param);
     559          887 :             auto lifetime = lifetime_param.get_lifetime ();
     560          887 :             context->get_lifetime_resolver ().insert_mapping (
     561              :               context->intern_lifetime (lifetime));
     562          887 :           }
     563          887 :           break;
     564              : 
     565          128 :         case HIR::GenericParam::GenericKind::CONST:
     566          128 :           {
     567          128 :             if (is_foreign && abi != Rust::ABI::INTRINSIC)
     568              :               {
     569            0 :                 rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
     570              :                                "foreign items may not have const parameters");
     571              :               }
     572              : 
     573          128 :             auto &param
     574          128 :               = static_cast<HIR::ConstGenericParam &> (*generic_param);
     575          128 :             auto specified_type = TypeCheckType::Resolve (param.get_type ());
     576              : 
     577          128 :             if (param.has_default_expression ())
     578              :               {
     579           13 :                 switch (item_kind)
     580              :                   {
     581              :                   case HIR::Item::ItemKind::Struct:
     582              :                   case HIR::Item::ItemKind::Enum:
     583              :                   case HIR::Item::ItemKind::TypeAlias:
     584              :                   case HIR::Item::ItemKind::Trait:
     585              :                   case HIR::Item::ItemKind::Union:
     586              :                     break;
     587              : 
     588            2 :                   default:
     589            2 :                     {
     590            2 :                       rich_location r (line_table, item_locus);
     591            2 :                       r.add_fixit_remove (param.get_locus ());
     592            2 :                       rust_error_at (
     593              :                         r,
     594              :                         "default values for const generic parameters are not "
     595              :                         "allowed here");
     596            2 :                     }
     597            2 :                     break;
     598              :                   }
     599              : 
     600           13 :                 auto expr_type
     601           13 :                   = TypeCheckExpr::Resolve (param.get_default_expression ());
     602              : 
     603           26 :                 coercion_site (param.get_mappings ().get_hirid (),
     604           13 :                                TyTy::TyWithLocation (specified_type),
     605              :                                TyTy::TyWithLocation (
     606              :                                  expr_type,
     607           13 :                                  param.get_default_expression ().get_locus ()),
     608              :                                param.get_locus ());
     609              : 
     610              :                 // fold the default value
     611           13 :                 auto ctx = Compile::Context::get ();
     612           13 :                 auto &expr = param.get_default_expression ();
     613           13 :                 tree default_value
     614           13 :                   = Compile::HIRCompileBase::query_compile_const_expr (
     615              :                     ctx, specified_type, expr);
     616              : 
     617           13 :                 auto default_const_decl
     618              :                   = new TyTy::ConstValueType (default_value, specified_type,
     619           13 :                                               expr.get_mappings ().get_hirid (),
     620           13 :                                               expr.get_mappings ().get_hirid (),
     621           13 :                                               {});
     622              : 
     623           13 :                 context->insert_type (expr.get_mappings (), default_const_decl);
     624              :               }
     625              : 
     626          128 :             TyTy::BaseGeneric *const_decl
     627          256 :               = new TyTy::ConstParamType (param.get_name (), param.get_locus (),
     628              :                                           specified_type,
     629          128 :                                           param.get_mappings ().get_hirid (),
     630          256 :                                           param.get_mappings ().get_hirid (),
     631          256 :                                           {});
     632              : 
     633          128 :             context->insert_type (generic_param->get_mappings (), const_decl);
     634          128 :             TyTy::SubstitutionParamMapping p (*generic_param, const_decl);
     635          128 :             substitutions.push_back (p);
     636              :           }
     637          128 :           break;
     638              : 
     639         8716 :         case HIR::GenericParam::GenericKind::TYPE:
     640         8716 :           {
     641         8716 :             if (is_foreign && abi != Rust::ABI::INTRINSIC)
     642              :               {
     643            1 :                 rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
     644              :                                "foreign items may not have type parameters");
     645              :               }
     646              : 
     647         8716 :             auto param_type = TypeResolveGenericParam::Resolve (
     648         8716 :               *generic_param, false /*resolve_trait_bounds*/);
     649         8716 :             context->insert_type (generic_param->get_mappings (), param_type);
     650              : 
     651         8716 :             TyTy::SubstitutionParamMapping p (*generic_param, param_type);
     652         8716 :             substitutions.push_back (p);
     653              :           }
     654         8716 :           break;
     655              :         }
     656              :     }
     657              : 
     658              :   // now walk them to setup any specified type param bounds
     659        17665 :   for (auto &subst : substitutions)
     660              :     {
     661         8931 :       auto &generic = subst.get_generic_param ();
     662         8931 :       if (generic.get_kind () != HIR::GenericParam::GenericKind::TYPE)
     663          128 :         continue;
     664              : 
     665         8803 :       auto &type_param = static_cast<HIR::TypeParam &> (generic);
     666         8803 :       auto bpty = subst.get_param_ty ();
     667         8803 :       rust_assert (bpty->get_kind () == TyTy::TypeKind::PARAM);
     668         8803 :       auto pty = static_cast<TyTy::ParamType *> (bpty);
     669              : 
     670         8803 :       TypeResolveGenericParam::ApplyAnyTraitBounds (type_param, pty);
     671              :     }
     672         8734 : }
     673              : 
     674              : TyTy::TypeBoundPredicate
     675         9444 : TypeCheckBase::get_marker_predicate (LangItem::Kind item_type, location_t locus)
     676              : {
     677         9444 :   DefId item_id = mappings.get_lang_item (item_type, locus);
     678         9443 :   HIR::Item *item = mappings.lookup_defid (item_id).value ();
     679         9443 :   rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
     680              : 
     681         9443 :   HIR::Trait &trait = *static_cast<HIR::Trait *> (item);
     682         9443 :   TraitReference *ref = TraitResolver::Resolve (trait);
     683         9443 :   rust_assert (ref != nullptr);
     684              : 
     685         9443 :   return TyTy::TypeBoundPredicate (*ref, BoundPolarity::RegularBound, locus);
     686              : }
     687              : 
     688              : } // namespace Resolver
     689              : } // 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.