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: 93.1 % 393 366
Test Date: 2026-02-28 14:20:25 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      2758761 : TypeCheckBase::TypeCheckBase ()
      34      2758761 :   : mappings (Analysis::Mappings::get ()), context (TypeCheckContext::get ())
      35      2758761 : {}
      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        11525 : walk_types_to_constrain (std::set<HirId> &constrained_symbols,
      51              :                          const TyTy::SubstitutionArgumentMappings &constraints)
      52              : {
      53        18372 :   for (const auto &c : constraints.get_mappings ())
      54              :     {
      55         6847 :       auto arg = c.get_tyty ();
      56         6847 :       if (arg != nullptr)
      57              :         {
      58         6847 :           const auto p = arg->get_root ();
      59         6847 :           constrained_symbols.insert (p->get_ref ());
      60         6847 :           constrained_symbols.insert (p->get_ty_ref ());
      61              : 
      62         6847 :           if (p->has_substitutions_defined ())
      63              :             {
      64          245 :               walk_types_to_constrain (constrained_symbols,
      65              :                                        p->get_subst_argument_mappings ());
      66              :             }
      67              :         }
      68              :     }
      69        11525 : }
      70              : 
      71              : static void
      72         5640 : walk_type_to_constrain (std::set<HirId> &constrained_symbols, TyTy::BaseType &r)
      73              : {
      74         6120 :   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            0 :     case TyTy::TypeKind::ARRAY:
      89            0 :       {
      90            0 :         auto &arr = static_cast<TyTy::ArrayType &> (r);
      91            0 :         walk_type_to_constrain (constrained_symbols, *arr.get_element_type ());
      92              :       }
      93            0 :       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            2 :     case TyTy::TUPLE:
     124            2 :       {
     125            2 :         auto &tuple = static_cast<TyTy::TupleType &> (r);
     126            2 :         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         5640 : }
     147              : 
     148              : bool
     149        41263 : 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        41263 :   bool check_result = false;
     156        41263 :   bool check_completed
     157        41263 :     = context->have_checked_for_unconstrained (reference->get_ref (),
     158              :                                                &check_result);
     159        41263 :   if (check_completed)
     160        35623 :     return check_result;
     161              : 
     162         5640 :   std::set<HirId> symbols_to_constrain;
     163         5640 :   std::map<HirId, location_t> symbol_to_location;
     164         6633 :   for (const auto &p : params_to_constrain)
     165              :     {
     166          993 :       HirId ref = p.get_param_ty ()->get_ref ();
     167          993 :       symbols_to_constrain.insert (ref);
     168          993 :       symbol_to_location.insert ({ref, p.get_param_locus ()});
     169              :     }
     170              : 
     171              :   // set up the set of constrained symbols
     172        11280 :   std::set<HirId> constrained_symbols;
     173         5640 :   walk_types_to_constrain (constrained_symbols, constraint_a);
     174         5640 :   walk_types_to_constrain (constrained_symbols, constraint_b);
     175         5640 :   walk_type_to_constrain (constrained_symbols, *reference);
     176              : 
     177              :   // check for unconstrained
     178         5640 :   bool unconstrained = false;
     179         6633 :   for (auto &sym : symbols_to_constrain)
     180              :     {
     181          993 :       bool used = constrained_symbols.find (sym) != constrained_symbols.end ();
     182          993 :       if (!used)
     183              :         {
     184            3 :           location_t locus = symbol_to_location.at (sym);
     185            3 :           rust_error_at (locus, "unconstrained type parameter");
     186            3 :           unconstrained = true;
     187              :         }
     188              :     }
     189              : 
     190         5640 :   context->insert_unconstrained_check_marker (reference->get_ref (),
     191              :                                               unconstrained);
     192              : 
     193         5640 :   return unconstrained;
     194         5640 : }
     195              : 
     196              : TyTy::BaseType *
     197        18978 : TypeCheckBase::resolve_literal (const Analysis::NodeMapping &expr_mappings,
     198              :                                 HIR::Literal &literal, location_t locus)
     199              : {
     200        18978 :   TyTy::BaseType *infered = nullptr;
     201        18978 :   switch (literal.get_lit_type ())
     202              :     {
     203        14343 :     case HIR::Literal::LitType::INT:
     204        14343 :       {
     205        14343 :         bool ok = false;
     206              : 
     207        14343 :         switch (literal.get_type_hint ())
     208              :           {
     209           22 :           case CORETYPE_I8:
     210           22 :             ok = context->lookup_builtin ("i8", &infered);
     211           22 :             break;
     212           14 :           case CORETYPE_I16:
     213           14 :             ok = context->lookup_builtin ("i16", &infered);
     214           14 :             break;
     215          175 :           case CORETYPE_I32:
     216          175 :             ok = context->lookup_builtin ("i32", &infered);
     217          175 :             break;
     218           14 :           case CORETYPE_I64:
     219           14 :             ok = context->lookup_builtin ("i64", &infered);
     220           14 :             break;
     221           14 :           case CORETYPE_I128:
     222           14 :             ok = context->lookup_builtin ("i128", &infered);
     223           14 :             break;
     224              : 
     225           29 :           case CORETYPE_U8:
     226           29 :             ok = context->lookup_builtin ("u8", &infered);
     227           29 :             break;
     228           24 :           case CORETYPE_U16:
     229           24 :             ok = context->lookup_builtin ("u16", &infered);
     230           24 :             break;
     231          109 :           case CORETYPE_U32:
     232          109 :             ok = context->lookup_builtin ("u32", &infered);
     233          109 :             break;
     234           15 :           case CORETYPE_U64:
     235           15 :             ok = context->lookup_builtin ("u64", &infered);
     236           15 :             break;
     237           14 :           case CORETYPE_U128:
     238           14 :             ok = context->lookup_builtin ("u128", &infered);
     239           14 :             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        13205 :           default:
     259        13205 :             ok = true;
     260        13205 :             infered
     261        13205 :               = new TyTy::InferType (expr_mappings.get_hirid (),
     262              :                                      TyTy::InferType::InferTypeKind::INTEGRAL,
     263              :                                      TyTy::InferType::TypeHint::Default (),
     264        13205 :                                      locus);
     265        13205 :             break;
     266              :           }
     267        14343 :         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         1296 :     case HIR::Literal::LitType::BOOL:
     298         1296 :       {
     299         1296 :         auto ok = context->lookup_builtin ("bool", &infered);
     300         1296 :         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        18978 :       break;
     393              :     }
     394              : 
     395        18978 :   return infered;
     396              : }
     397              : 
     398              : TyTy::ADTType::ReprOptions
     399         2970 : TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
     400              : {
     401         2970 :   TyTy::ADTType::ReprOptions repr;
     402         2970 :   repr.pack = 0;
     403         2970 :   repr.align = 0;
     404              : 
     405              :   // Default repr for enums is isize, but we now check for other repr in the
     406              :   // attributes.
     407         2970 :   bool ok = context->lookup_builtin ("isize", &repr.repr);
     408         2970 :   rust_assert (ok);
     409              : 
     410         3390 :   for (const auto &attr : attrs)
     411              :     {
     412          446 :       bool is_repr = attr.get_path ().as_string () == Values::Attributes::REPR;
     413          446 :       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          445 :       if (is_repr)
     420              :         {
     421           28 :           const AST::AttrInput &input = attr.get_attr_input ();
     422           28 :           bool is_token_tree = input.get_attr_input_type ()
     423           28 :                                == AST::AttrInput::AttrInputType::TOKEN_TREE;
     424           28 :           if (!is_token_tree)
     425              :             {
     426            1 :               rust_error_at (attr.get_locus (), "malformed %<repr%> attribute");
     427            2 :               continue;
     428              :             }
     429           27 :           const auto &option = static_cast<const AST::DelimTokenTree &> (input);
     430           27 :           AST::AttrInputMetaItemContainer *meta_items
     431           27 :             = option.parse_to_meta_item ();
     432              : 
     433           27 :           if (meta_items == nullptr)
     434              :             {
     435            0 :               rust_error_at (attr.get_locus (), "malformed %qs attribute",
     436              :                              "repr");
     437            0 :               continue;
     438              :             }
     439              : 
     440           27 :           auto &items = meta_items->get_items ();
     441           27 :           if (items.size () == 0)
     442              :             {
     443              :               // nothing to do with this its empty
     444            1 :               delete meta_items;
     445            1 :               continue;
     446              :             }
     447              : 
     448           26 :           const std::string inline_option = items.at (0)->as_string ();
     449              : 
     450              :           // TODO: it would probably be better to make the MetaItems more aware
     451              :           // of constructs with nesting like #[repr(packed(2))] rather than
     452              :           // manually parsing the string "packed(2)" here.
     453              : 
     454           26 :           size_t oparen = inline_option.find ('(', 0);
     455           26 :           bool is_pack = false;
     456           26 :           bool is_align = false;
     457           26 :           bool is_c = false;
     458           26 :           bool is_integer = false;
     459           26 :           unsigned char value = 1;
     460              : 
     461           26 :           if (oparen == std::string::npos)
     462              :             {
     463           20 :               is_pack = inline_option.compare ("packed") == 0;
     464           20 :               is_align = inline_option.compare ("align") == 0;
     465           20 :               is_c = inline_option.compare ("C") == 0;
     466           20 :               is_integer = (inline_option.compare ("isize") == 0
     467           20 :                             || inline_option.compare ("i8") == 0
     468           20 :                             || inline_option.compare ("i16") == 0
     469           20 :                             || inline_option.compare ("i32") == 0
     470           19 :                             || inline_option.compare ("i64") == 0
     471           19 :                             || inline_option.compare ("i128") == 0
     472           19 :                             || inline_option.compare ("usize") == 0
     473           19 :                             || inline_option.compare ("u8") == 0
     474           19 :                             || inline_option.compare ("u16") == 0
     475           19 :                             || inline_option.compare ("u32") == 0
     476           19 :                             || inline_option.compare ("u64") == 0
     477           39 :                             || inline_option.compare ("u128") == 0);
     478              :             }
     479              : 
     480              :           else
     481              :             {
     482            6 :               std::string rep = inline_option.substr (0, oparen);
     483            6 :               is_pack = rep.compare ("packed") == 0;
     484            6 :               is_align = rep.compare ("align") == 0;
     485              : 
     486            6 :               size_t cparen = inline_option.find (')', oparen);
     487            6 :               if (cparen == std::string::npos)
     488              :                 {
     489            0 :                   rust_error_at (locus, "malformed attribute");
     490              :                 }
     491              : 
     492            6 :               std::string value_str = inline_option.substr (oparen, cparen);
     493            6 :               value = strtoul (value_str.c_str () + 1, NULL, 10);
     494            6 :             }
     495              : 
     496           26 :           if (is_pack)
     497              :             {
     498            4 :               repr.repr_kind = TyTy::ADTType::ReprKind::PACKED;
     499            4 :               repr.pack = value;
     500              :             }
     501           22 :           else if (is_align)
     502              :             {
     503            4 :               repr.repr_kind = TyTy::ADTType::ReprKind::ALIGN;
     504            4 :               repr.align = value;
     505              :             }
     506           18 :           else if (is_c)
     507              :             {
     508           15 :               repr.repr_kind = TyTy::ADTType::ReprKind::C;
     509              :             }
     510            3 :           else if (is_integer)
     511              :             {
     512            1 :               repr.repr_kind = TyTy::ADTType::ReprKind::INT;
     513            2 :               bool ok = context->lookup_builtin (inline_option, &repr.repr);
     514            1 :               if (!ok)
     515              :                 {
     516            0 :                   rust_error_at (attr.get_locus (), "Invalid repr type");
     517              :                 }
     518              :             }
     519              : 
     520           26 :           delete meta_items;
     521              : 
     522              :           // Multiple repr options must be specified with e.g. #[repr(C,
     523              :           // packed(2))].
     524           26 :           break;
     525           26 :         }
     526              :     }
     527              : 
     528         2970 :   return repr;
     529              : }
     530              : 
     531              : void
     532         8586 : TypeCheckBase::resolve_generic_params (
     533              :   const HIR::Item::ItemKind item_kind, location_t item_locus,
     534              :   const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
     535              :   std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
     536              :   ABI abi)
     537              : {
     538        18168 :   for (auto &generic_param : generic_params)
     539              :     {
     540         9582 :       switch (generic_param->get_kind ())
     541              :         {
     542          887 :         case HIR::GenericParam::GenericKind::LIFETIME:
     543          887 :           {
     544          887 :             auto lifetime_param
     545          887 :               = static_cast<HIR::LifetimeParam &> (*generic_param);
     546          887 :             auto lifetime = lifetime_param.get_lifetime ();
     547          887 :             context->get_lifetime_resolver ().insert_mapping (
     548              :               context->intern_lifetime (lifetime));
     549          887 :           }
     550          887 :           break;
     551              : 
     552          125 :         case HIR::GenericParam::GenericKind::CONST:
     553          125 :           {
     554          125 :             if (is_foreign && abi != Rust::ABI::INTRINSIC)
     555              :               {
     556            0 :                 rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
     557              :                                "foreign items may not have const parameters");
     558              :               }
     559              : 
     560          125 :             auto &param
     561          125 :               = static_cast<HIR::ConstGenericParam &> (*generic_param);
     562          125 :             auto specified_type = TypeCheckType::Resolve (param.get_type ());
     563              : 
     564          125 :             if (param.has_default_expression ())
     565              :               {
     566           13 :                 switch (item_kind)
     567              :                   {
     568              :                   case HIR::Item::ItemKind::Struct:
     569              :                   case HIR::Item::ItemKind::Enum:
     570              :                   case HIR::Item::ItemKind::TypeAlias:
     571              :                   case HIR::Item::ItemKind::Trait:
     572              :                   case HIR::Item::ItemKind::Union:
     573              :                     break;
     574              : 
     575            2 :                   default:
     576            2 :                     {
     577            2 :                       rich_location r (line_table, item_locus);
     578            2 :                       r.add_fixit_remove (param.get_locus ());
     579            2 :                       rust_error_at (
     580              :                         r,
     581              :                         "default values for const generic parameters are not "
     582              :                         "allowed here");
     583            2 :                     }
     584            2 :                     break;
     585              :                   }
     586              : 
     587           13 :                 auto expr_type
     588           13 :                   = TypeCheckExpr::Resolve (param.get_default_expression ());
     589              : 
     590           26 :                 coercion_site (param.get_mappings ().get_hirid (),
     591           13 :                                TyTy::TyWithLocation (specified_type),
     592              :                                TyTy::TyWithLocation (
     593              :                                  expr_type,
     594           13 :                                  param.get_default_expression ().get_locus ()),
     595              :                                param.get_locus ());
     596              : 
     597              :                 // fold the default value
     598           13 :                 auto ctx = Compile::Context::get ();
     599           13 :                 auto &expr = param.get_default_expression ();
     600           13 :                 tree default_value
     601           13 :                   = Compile::HIRCompileBase::query_compile_const_expr (
     602              :                     ctx, specified_type, expr);
     603              : 
     604           13 :                 auto default_const_decl
     605              :                   = new TyTy::ConstValueType (default_value, specified_type,
     606           13 :                                               expr.get_mappings ().get_hirid (),
     607           13 :                                               expr.get_mappings ().get_hirid (),
     608           13 :                                               {});
     609              : 
     610           13 :                 context->insert_type (expr.get_mappings (), default_const_decl);
     611              :               }
     612              : 
     613          125 :             TyTy::BaseGeneric *const_decl
     614          250 :               = new TyTy::ConstParamType (param.get_name (), param.get_locus (),
     615              :                                           specified_type,
     616          125 :                                           param.get_mappings ().get_hirid (),
     617          250 :                                           param.get_mappings ().get_hirid (),
     618          250 :                                           {});
     619              : 
     620          125 :             context->insert_type (generic_param->get_mappings (), const_decl);
     621          125 :             TyTy::SubstitutionParamMapping p (*generic_param, const_decl);
     622          125 :             substitutions.push_back (p);
     623              :           }
     624          125 :           break;
     625              : 
     626         8570 :         case HIR::GenericParam::GenericKind::TYPE:
     627         8570 :           {
     628         8570 :             if (is_foreign && abi != Rust::ABI::INTRINSIC)
     629              :               {
     630            1 :                 rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
     631              :                                "foreign items may not have type parameters");
     632              :               }
     633              : 
     634         8570 :             auto param_type = TypeResolveGenericParam::Resolve (
     635         8570 :               *generic_param, false /*resolve_trait_bounds*/);
     636         8570 :             context->insert_type (generic_param->get_mappings (), param_type);
     637              : 
     638         8570 :             TyTy::SubstitutionParamMapping p (*generic_param, param_type);
     639         8570 :             substitutions.push_back (p);
     640              :           }
     641         8570 :           break;
     642              :         }
     643              :     }
     644              : 
     645              :   // now walk them to setup any specified type param bounds
     646        17367 :   for (auto &subst : substitutions)
     647              :     {
     648         8782 :       auto &generic = subst.get_generic_param ();
     649         8782 :       if (generic.get_kind () != HIR::GenericParam::GenericKind::TYPE)
     650          125 :         continue;
     651              : 
     652         8657 :       auto &type_param = static_cast<HIR::TypeParam &> (generic);
     653         8657 :       auto bpty = subst.get_param_ty ();
     654         8657 :       rust_assert (bpty->get_kind () == TyTy::TypeKind::PARAM);
     655         8657 :       auto pty = static_cast<TyTy::ParamType *> (bpty);
     656              : 
     657         8657 :       TypeResolveGenericParam::ApplyAnyTraitBounds (type_param, pty);
     658              :     }
     659         8585 : }
     660              : 
     661              : TyTy::TypeBoundPredicate
     662         9298 : TypeCheckBase::get_marker_predicate (LangItem::Kind item_type, location_t locus)
     663              : {
     664         9298 :   DefId item_id = mappings.get_lang_item (item_type, locus);
     665         9297 :   HIR::Item *item = mappings.lookup_defid (item_id).value ();
     666         9297 :   rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
     667              : 
     668         9297 :   HIR::Trait &trait = *static_cast<HIR::Trait *> (item);
     669         9297 :   TraitReference *ref = TraitResolver::Resolve (trait);
     670         9297 :   rust_assert (ref != nullptr);
     671              : 
     672         9297 :   return TyTy::TypeBoundPredicate (*ref, BoundPolarity::RegularBound, locus);
     673              : }
     674              : 
     675              : } // namespace Resolver
     676              : } // 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.