LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-coercion.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 90.8 % 238 216
Test Date: 2026-02-28 14:20:25 Functions: 91.7 % 12 11
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-coercion.h"
      20              : #include "rust-type-util.h"
      21              : 
      22              : namespace Rust {
      23              : namespace Resolver {
      24              : 
      25              : TypeCoercionRules::CoercionResult
      26        40104 : TypeCoercionRules::Coerce (TyTy::BaseType *receiver, TyTy::BaseType *expected,
      27              :                            location_t locus, bool allow_autoderef,
      28              :                            bool is_cast_site)
      29              : {
      30        40104 :   TypeCoercionRules resolver (expected, locus, true, allow_autoderef, false,
      31        40104 :                               is_cast_site);
      32        40104 :   bool ok = resolver.do_coercion (receiver);
      33        80151 :   return ok ? resolver.try_result : CoercionResult::get_error ();
      34        40104 : }
      35              : 
      36              : TypeCoercionRules::CoercionResult
      37        34886 : TypeCoercionRules::TryCoerce (TyTy::BaseType *receiver,
      38              :                               TyTy::BaseType *expected, location_t locus,
      39              :                               bool allow_autoderef, bool is_cast_site)
      40              : {
      41        34886 :   TypeCoercionRules resolver (expected, locus, false, allow_autoderef, true,
      42        34886 :                               is_cast_site);
      43        34886 :   bool ok = resolver.do_coercion (receiver);
      44        44301 :   return ok ? resolver.try_result : CoercionResult::get_error ();
      45        34886 : }
      46              : 
      47        74990 : TypeCoercionRules::TypeCoercionRules (TyTy::BaseType *expected,
      48              :                                       location_t locus, bool emit_errors,
      49              :                                       bool allow_autoderef, bool try_flag,
      50        74990 :                                       bool is_cast_site)
      51       224970 :   : AutoderefCycle (!allow_autoderef), mappings (Analysis::Mappings::get ()),
      52        74990 :     context (TypeCheckContext::get ()), expected (expected), locus (locus),
      53        74990 :     try_result (CoercionResult::get_error ()), emit_errors (emit_errors),
      54        74990 :     try_flag (try_flag), is_cast_site (is_cast_site)
      55        74990 : {}
      56              : 
      57              : bool
      58        74990 : TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
      59              : {
      60              :   // FIXME this is not finished and might be super simplified
      61              :   // see:
      62              :   // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
      63              : 
      64        74990 :   if (receiver->get_kind () == TyTy::TypeKind::NEVER)
      65              :     {
      66          434 :       try_result = coerce_never (receiver);
      67          434 :       return true;
      68              :     }
      69              : 
      70              :   // unsize
      71        74556 :   tl::expected<CoercionResult, CoerceUnsizedError> unsize_coercion
      72        74556 :     = coerce_unsized (receiver, expected);
      73        74556 :   if (unsize_coercion)
      74              :     {
      75          133 :       try_result = unsize_coercion.value ();
      76          133 :       return true;
      77              :     }
      78        74423 :   else if (unsize_coercion.error () == CoerceUnsizedError::Unsafe)
      79              :     {
      80              :       // location_t lhs = mappings.lookup_location (receiver->get_ref ());
      81              :       // location_t rhs = mappings.lookup_location (expected->get_ref ());
      82              :       // object_unsafe_error (locus, lhs, rhs);
      83              :       return false;
      84              :     }
      85              : 
      86              :   // pointers
      87        74250 :   switch (expected->get_kind ())
      88              :     {
      89         7515 :     case TyTy::TypeKind::POINTER:
      90         7515 :       {
      91         7515 :         auto *ptr = expected->as<TyTy::PointerType> ();
      92         7515 :         try_result = coerce_unsafe_ptr (receiver, ptr, ptr->mutability ());
      93         7515 :         return !try_result.is_error ();
      94              :       }
      95              : 
      96        23020 :     case TyTy::TypeKind::REF:
      97        23020 :       {
      98        23020 :         auto *ptr = expected->as<TyTy::ReferenceType> ();
      99        23020 :         try_result
     100        23020 :           = coerce_borrowed_pointer (receiver, ptr, ptr->mutability ());
     101        23020 :         return !try_result.is_error ();
     102              :       }
     103        43715 :       break;
     104              : 
     105        43715 :     default:
     106        43715 :       break;
     107              :     }
     108              : 
     109              :   // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L210
     110        43715 :   switch (receiver->get_kind ())
     111              :     {
     112        43715 :     default:
     113        43715 :       {
     114        43715 :         rust_debug (
     115              :           "do_coercion default unify and infer expected: %s receiver %s",
     116              :           receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
     117        43715 :         TyTy::BaseType *result
     118        43715 :           = unify_site_and (receiver->get_ref (),
     119        43715 :                             TyTy::TyWithLocation (expected),
     120        43715 :                             TyTy::TyWithLocation (receiver),
     121              :                             locus /*unify_locus*/, false /*emit_errors*/,
     122        43715 :                             !try_flag /*commit_if_ok*/, try_flag /*infer*/,
     123        43715 :                             try_flag /*cleanup on error*/);
     124        43715 :         if (result->get_kind () != TyTy::TypeKind::ERROR)
     125              :           {
     126        33723 :             try_result = CoercionResult{{}, result};
     127        33723 :             return true;
     128              :           }
     129              :       }
     130         9992 :       break;
     131              :     }
     132              : 
     133         9992 :   return !try_result.is_error ();
     134        74556 : }
     135              : 
     136              : TypeCoercionRules::CoercionResult
     137          434 : TypeCoercionRules::coerce_never (TyTy::BaseType *receiver)
     138              : {
     139              :   // handle never
     140              :   // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
     141              : 
     142              :   // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
     143              :   // type variable, we want `?T` to fallback to `!` if not
     144              :   // otherwise constrained. An example where this arises:
     145              :   //
     146              :   //     let _: Option<?T> = Some({ return; });
     147              :   //
     148              :   // here, we would coerce from `!` to `?T`.
     149          434 :   if (expected->has_substitutions_defined () && !expected->is_concrete ())
     150              :     {
     151            1 :       location_t locus = mappings.lookup_location (receiver->get_ref ());
     152            1 :       TyTy::TyVar implicit_var = TyTy::TyVar::get_implicit_infer_var (locus);
     153            1 :       return CoercionResult{{}, implicit_var.get_tyty ()};
     154              :     }
     155              : 
     156          433 :   bool expected_is_infer_var = expected->get_kind () == TyTy::TypeKind::INFER;
     157          433 :   bool expected_is_general_infer_var
     158              :     = expected_is_infer_var
     159          433 :       && (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
     160          433 :           == TyTy::InferType::InferTypeKind::GENERAL);
     161              : 
     162              :   // FIXME this 'expected_is_general_infer_var' case needs to eventually
     163              :   // should go away see: compile/never_type_err1.rs
     164              :   //
     165              :   // I think we need inference obligations to say that yes we have a
     166              :   // general inference variable but we add the oligation to the expected
     167              :   // type that it could default to '!'
     168          433 :   if (expected_is_general_infer_var)
     169            1 :     return CoercionResult{{}, receiver};
     170              :   else
     171          432 :     return CoercionResult{{}, expected->clone ()};
     172              : }
     173              : 
     174              : TypeCoercionRules::CoercionResult
     175         7515 : TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
     176              :                                       TyTy::PointerType *expected,
     177              :                                       Mutability to_mutbl)
     178              : {
     179         7515 :   rust_debug ("coerce_unsafe_ptr(receiver={%s}, expected={%s})",
     180              :               receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
     181              : 
     182         7515 :   Mutability from_mutbl = Mutability::Imm;
     183         7515 :   TyTy::BaseType *element = nullptr;
     184         7515 :   switch (receiver->get_kind ())
     185              :     {
     186         4004 :     case TyTy::TypeKind::REF:
     187         4004 :       {
     188         4004 :         TyTy::ReferenceType *ref
     189              :           = static_cast<TyTy::ReferenceType *> (receiver);
     190         4004 :         from_mutbl = ref->mutability ();
     191         4004 :         element = ref->get_base ();
     192              :       }
     193         4004 :       break;
     194              : 
     195         3371 :     case TyTy::TypeKind::POINTER:
     196         3371 :       {
     197         3371 :         TyTy::PointerType *ref = static_cast<TyTy::PointerType *> (receiver);
     198         3371 :         from_mutbl = ref->mutability ();
     199         3371 :         element = ref->get_base ();
     200              :       }
     201         3371 :       break;
     202              : 
     203          140 :     default:
     204          140 :       {
     205          140 :         if (types_compatable (TyTy::TyWithLocation (receiver),
     206          140 :                               TyTy::TyWithLocation (expected), UNKNOWN_LOCATION,
     207              :                               false))
     208            0 :           return CoercionResult{{}, expected->clone ()};
     209              : 
     210          140 :         return CoercionResult::get_error ();
     211              :       }
     212              :     }
     213              : 
     214         7375 :   bool receiver_is_non_ptr = receiver->get_kind () != TyTy::TypeKind::POINTER;
     215         7375 :   if (autoderef_flag && receiver_is_non_ptr)
     216              :     {
     217              :       // it is unsafe to autoderef to raw pointers
     218           14 :       return CoercionResult::get_error ();
     219              :     }
     220              : 
     221         7361 :   if (!coerceable_mutability (from_mutbl, to_mutbl))
     222              :     {
     223            0 :       location_t lhs = mappings.lookup_location (receiver->get_ref ());
     224            0 :       location_t rhs = mappings.lookup_location (expected->get_ref ());
     225            0 :       mismatched_mutability_error (locus, lhs, rhs);
     226            0 :       return TypeCoercionRules::CoercionResult::get_error ();
     227              :     }
     228              : 
     229         7361 :   TyTy::PointerType *coerced_mutability
     230              :     = new TyTy::PointerType (receiver->get_ref (),
     231         7361 :                              TyTy::TyVar (element->get_ref ()), to_mutbl);
     232              : 
     233         7361 :   rust_debug ("coerce_unsafe_ptr unify-site");
     234              : 
     235              :   // this is a really annoying case rust allows casts of any ptr to another ptr
     236              :   // types
     237              :   //
     238              :   //  *?   vs *i32  - simple coercion valid
     239              :   //  *?   vs *T    - simple coercion valid
     240              :   //  *i32 vs *i32  - simple coercion valid
     241              :   //  *i32 vs *u8   - simple coercion not valid but allowed in cast site
     242              :   //  *T   vs *u8   - not valid but is allowed in cast site
     243              : 
     244         7361 :   TyTy::BaseType *result
     245         7361 :     = unify_site_and (receiver->get_ref (), TyTy::TyWithLocation (expected),
     246         7361 :                       TyTy::TyWithLocation (coerced_mutability),
     247              :                       locus /*unify_locus*/, !try_flag /*emit_errors*/,
     248         7361 :                       !try_flag /*commit_if_ok*/,
     249         2181 :                       try_flag && !is_cast_site /*infer*/,
     250         7361 :                       try_flag /*cleanup on error*/);
     251         7361 :   bool unsafe_ptr_coerceion_ok = result->get_kind () != TyTy::TypeKind::ERROR;
     252         7361 :   if (unsafe_ptr_coerceion_ok)
     253         7298 :     return CoercionResult{{}, result};
     254              : 
     255           63 :   return TypeCoercionRules::CoercionResult::get_error ();
     256              : }
     257              : 
     258              : /// Reborrows `&mut A` to `&mut B` and `&(mut) A` to `&B`.
     259              : /// To match `A` with `B`, autoderef will be performed,
     260              : /// calling `deref`/`deref_mut` where necessary.
     261              : TypeCoercionRules::CoercionResult
     262        23020 : TypeCoercionRules::coerce_borrowed_pointer (TyTy::BaseType *receiver,
     263              :                                             TyTy::ReferenceType *expected,
     264              :                                             Mutability to_mutbl)
     265              : {
     266        23020 :   rust_debug ("coerce_borrowed_pointer(a={%s}, b={%s})",
     267              :               receiver->debug_str ().c_str (), expected->debug_str ().c_str ());
     268              : 
     269        23020 :   Mutability from_mutbl = Mutability::Imm;
     270        23020 :   switch (receiver->get_kind ())
     271              :     {
     272        10727 :     case TyTy::TypeKind::REF:
     273        10727 :       {
     274        10727 :         from_mutbl = receiver->as<TyTy::ReferenceType> ()->mutability ();
     275              :       }
     276        10727 :       break;
     277        12293 :     default:
     278        12293 :       {
     279        12293 :         rust_debug ("coerce_borrowed_pointer -- unify");
     280        12293 :         TyTy::BaseType *result
     281        12293 :           = unify_site_and (receiver->get_ref (),
     282        12293 :                             TyTy::TyWithLocation (receiver),
     283        12293 :                             TyTy::TyWithLocation (expected), locus,
     284        12293 :                             false /*emit_errors*/, !try_flag /*commit_if_ok*/,
     285              :                             try_flag /* infer */,
     286        12293 :                             try_flag /*cleanup_on_failure*/);
     287        12293 :         bool default_coerceion_ok
     288        12293 :           = result->get_kind () != TyTy::TypeKind::ERROR;
     289        12293 :         if (default_coerceion_ok)
     290           21 :           return CoercionResult{{}, result};
     291              : 
     292        12272 :         return TypeCoercionRules::CoercionResult::get_error ();
     293              :       }
     294              :     }
     295              : 
     296        10727 :   if (!coerceable_mutability (from_mutbl, to_mutbl))
     297              :     {
     298            0 :       location_t lhs = mappings.lookup_location (receiver->get_ref ());
     299            0 :       location_t rhs = mappings.lookup_location (expected->get_ref ());
     300            0 :       mismatched_mutability_error (locus, lhs, rhs);
     301            0 :       return TypeCoercionRules::CoercionResult::get_error ();
     302              :     }
     303              : 
     304        10727 :   rust_debug ("coerce_borrowed_pointer -- autoderef cycle");
     305        10727 :   AutoderefCycle::cycle (receiver);
     306        18580 :   rust_debug ("coerce_borrowed_pointer -- result: [%s] with adjustments: [%zu]",
     307              :               try_result.is_error () ? "failed" : "matched",
     308              :               try_result.adjustments.size ());
     309              : 
     310        10727 :   return try_result;
     311              : }
     312              : 
     313              : // &[T; n] or &mut [T; n] -> &[T]
     314              : // or &mut [T; n] -> &mut [T]
     315              : // or &Concrete -> &Trait, etc.
     316              : tl::expected<TypeCoercionRules::CoercionResult,
     317              :              TypeCoercionRules::CoerceUnsizedError>
     318        74556 : TypeCoercionRules::coerce_unsized (TyTy::BaseType *source,
     319              :                                    TyTy::BaseType *target)
     320              : {
     321        74556 :   rust_debug ("coerce_unsized(source={%s}, target={%s})",
     322              :               source->debug_str ().c_str (), target->debug_str ().c_str ());
     323              : 
     324        74556 :   bool source_is_ref = source->get_kind () == TyTy::TypeKind::REF;
     325        74556 :   bool target_is_ref = target->get_kind () == TyTy::TypeKind::REF;
     326        74556 :   bool target_is_ptr = target->get_kind () == TyTy::TypeKind::POINTER;
     327              : 
     328        74556 :   bool needs_reborrow = false;
     329        74556 :   TyTy::BaseType *ty_a = source;
     330        74556 :   TyTy::BaseType *ty_b = target;
     331        74556 :   Mutability expected_mutability = Mutability::Imm;
     332        74556 :   if (source_is_ref && target_is_ref)
     333              :     {
     334        11033 :       TyTy::ReferenceType *source_ref
     335              :         = static_cast<TyTy::ReferenceType *> (source);
     336        11033 :       TyTy::ReferenceType *target_ref
     337              :         = static_cast<TyTy::ReferenceType *> (target);
     338              : 
     339        11033 :       Mutability from_mutbl = source_ref->mutability ();
     340        11033 :       Mutability to_mutbl = target_ref->mutability ();
     341        11033 :       if (!coerceable_mutability (from_mutbl, to_mutbl))
     342              :         {
     343          172 :           location_t lhs = mappings.lookup_location (source->get_ref ());
     344          172 :           location_t rhs = mappings.lookup_location (target->get_ref ());
     345          172 :           mismatched_mutability_error (locus, lhs, rhs);
     346          172 :           return tl::unexpected<CoerceUnsizedError> (
     347          172 :             CoerceUnsizedError::Unsafe);
     348              :         }
     349              : 
     350        10861 :       ty_a = source_ref->get_base ();
     351        10861 :       ty_b = target_ref->get_base ();
     352        10861 :       needs_reborrow = true;
     353        10861 :       expected_mutability = to_mutbl;
     354              : 
     355        10861 :       adjustments.emplace_back (Adjustment::AdjustmentType::INDIRECTION,
     356              :                                 source_ref, ty_a);
     357              :     }
     358        63523 :   else if (source_is_ref && target_is_ptr)
     359              :     {
     360         4004 :       TyTy::ReferenceType *source_ref
     361              :         = static_cast<TyTy::ReferenceType *> (source);
     362         4004 :       TyTy::PointerType *target_ref = static_cast<TyTy::PointerType *> (target);
     363              : 
     364         4004 :       Mutability from_mutbl = source_ref->mutability ();
     365         4004 :       Mutability to_mutbl = target_ref->mutability ();
     366         4004 :       if (!coerceable_mutability (from_mutbl, to_mutbl))
     367              :         {
     368            0 :           location_t lhs = mappings.lookup_location (source->get_ref ());
     369            0 :           location_t rhs = mappings.lookup_location (target->get_ref ());
     370            0 :           mismatched_mutability_error (locus, lhs, rhs);
     371            0 :           return tl::unexpected<CoerceUnsizedError> (
     372            0 :             CoerceUnsizedError::Unsafe);
     373              :         }
     374              : 
     375         4004 :       ty_a = source_ref->get_base ();
     376         4004 :       ty_b = target_ref->get_base ();
     377         4004 :       needs_reborrow = true;
     378         4004 :       expected_mutability = to_mutbl;
     379              : 
     380         4004 :       adjustments.emplace_back (Adjustment::AdjustmentType::INDIRECTION,
     381              :                                 source_ref, ty_a);
     382              :     }
     383              : 
     384              :   // FIXME
     385              :   // there is a bunch of code to ensure something is coerce able to a dyn trait
     386              :   // we need to support but we need to support a few more lang items for that
     387              :   // see:
     388              :   // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L582
     389              : 
     390        74384 :   const auto a = ty_a;
     391        74384 :   const auto b = ty_b;
     392              : 
     393        74384 :   bool expect_dyn = b->get_kind () == TyTy::TypeKind::DYNAMIC;
     394        74384 :   bool need_unsize = a->get_kind () != TyTy::TypeKind::DYNAMIC;
     395              : 
     396        74384 :   if (expect_dyn && need_unsize)
     397              :     {
     398          134 :       bool bounds_compatible = b->bounds_compatible (*a, locus, false);
     399          134 :       if (!bounds_compatible)
     400            1 :         return tl::unexpected<CoerceUnsizedError> (CoerceUnsizedError::Unsafe);
     401              : 
     402              :       // return the unsize coercion
     403          133 :       TyTy::BaseType *result = b->clone ();
     404              :       // result->set_ref (a->get_ref ());
     405              : 
     406              :       // append a dyn coercion adjustment
     407          133 :       adjustments.emplace_back (Adjustment::UNSIZE, a, result);
     408              : 
     409              :       // reborrow if needed
     410          133 :       if (needs_reborrow)
     411              :         {
     412          133 :           TyTy::ReferenceType *reborrow
     413              :             = new TyTy::ReferenceType (source->get_ref (),
     414          133 :                                        TyTy::TyVar (result->get_ref ()),
     415          266 :                                        expected_mutability);
     416              : 
     417          266 :           Adjustment::AdjustmentType borrow_type
     418          133 :             = expected_mutability == Mutability::Imm ? Adjustment::IMM_REF
     419              :                                                      : Adjustment::MUT_REF;
     420          133 :           adjustments.emplace_back (borrow_type, result, reborrow);
     421          133 :           result = reborrow;
     422              :         }
     423              : 
     424          133 :       return CoercionResult{adjustments, result};
     425              :     }
     426              : 
     427        74250 :   adjustments.clear ();
     428        74250 :   return tl::unexpected<CoerceUnsizedError> (CoerceUnsizedError::Regular);
     429              : }
     430              : 
     431              : bool
     432        17043 : TypeCoercionRules::select (TyTy::BaseType &autoderefed)
     433              : {
     434        17043 :   rust_debug ("TypeCoercionRules::select autoderefed={%s} can_eq expected={%s}",
     435              :               autoderefed.debug_str ().c_str (),
     436              :               expected->debug_str ().c_str ());
     437              : 
     438        17043 :   TyTy::BaseType *result
     439        17043 :     = unify_site_and (autoderefed.get_ref (), TyTy::TyWithLocation (expected),
     440        17043 :                       TyTy::TyWithLocation (&autoderefed),
     441              :                       UNDEF_LOCATION /* locus */, false /*emit_errors*/,
     442        17043 :                       !try_flag /*commit_if_ok*/, try_flag /*infer*/,
     443        17043 :                       try_flag /*cleanup*/);
     444        17043 :   bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
     445        17043 :   if (!ok)
     446              :     return false;
     447              : 
     448         7853 :   try_result = CoercionResult{adjustments, result};
     449         7853 :   return true;
     450              : }
     451              : 
     452              : /// Coercing a mutable reference to an immutable works, while
     453              : /// coercing `&T` to `&mut T` should be forbidden.
     454              : bool
     455        33125 : TypeCoercionRules::coerceable_mutability (Mutability from_mutbl,
     456              :                                           Mutability to_mutbl)
     457              : {
     458        33125 :   return to_mutbl == Mutability::Imm || (from_mutbl == to_mutbl);
     459              : }
     460              : 
     461              : void
     462          172 : TypeCoercionRules::mismatched_mutability_error (location_t expr_locus,
     463              :                                                 location_t lhs, location_t rhs)
     464              : {
     465          172 :   if (!emit_errors)
     466          171 :     return;
     467              : 
     468            1 :   rich_location r (line_table, expr_locus);
     469            1 :   r.add_range (lhs);
     470            1 :   r.add_range (rhs);
     471            1 :   rust_error_at (r, "mismatched mutability");
     472            1 : }
     473              : 
     474              : void
     475            0 : TypeCoercionRules::object_unsafe_error (location_t expr_locus, location_t lhs,
     476              :                                         location_t rhs)
     477              : {
     478            0 :   if (!emit_errors)
     479            0 :     return;
     480              : 
     481            0 :   rich_location r (line_table, expr_locus);
     482            0 :   r.add_range (lhs);
     483            0 :   r.add_range (rhs);
     484            0 :   rust_error_at (r, "unsafe unsize coercion");
     485            0 : }
     486              : 
     487              : } // namespace Resolver
     488              : } // 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.