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