]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix recusive type query and nullptr on type path
authorPhilip Herron <herron.philip@googlemail.com>
Wed, 2 Apr 2025 17:21:46 +0000 (18:21 +0100)
committerPhilip Herron <philip.herron@embecosm.com>
Thu, 3 Apr 2025 14:53:54 +0000 (14:53 +0000)
This was a small fix to sort out the segfault to check for nullptr on the
TypePath cases for query type. But when this happened opened up a few bugs
that were hidden under the carpet namely: compile/issue-2905-{1,2}.rs which
has a recursive type query which needs to ne handled but now and error
message is being output for the type path. This happens because we start
resolving a generic struct:

  struct Wierd<T>(A<(T,)>);

So the child field A is also generic and the generic argument of the tuple
of T needs to be applied to this generic field. This causes a chunk of
code to do bounds checking to ensure the bounds are ok, this is also
something that probably might change as generic types will have the bounds
secified anyway but thats besides the case right now. So once this bounds
checking occurs we endup looking at the impl block for Wierd<i32> which is
also grand but we still havent finished resolving the parent type of Wierd
which is recusive. But the query type system needs to check for that.

The other issue was: compile/issue-3022.rs which is a resolution issue:

  impl<T: Foo<U>, U> Foo<U> for Bar<T, U>

The bound of Foo<T> is added to T before U is resolved but this was hidden
before the new error message was added. So now we have a generic
arguements handler being used correctly all over the code base apart from
1 last case for Traits but we will deal with that later. This handles the
case by setting up the type parameters upfront then sorting out their
bounds.

Fixes Rust-GCC#3625

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-resolve.cc (TraitResolver::resolve_trait): new argument
* typecheck/rust-hir-type-check-base.cc (TypeCheckBase::TypeCheckBase): new helper
* typecheck/rust-hir-type-check-base.h: new helper prototype
* typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
remove comment out code
* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_root_path): check for null
* typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): likewise
(TypeResolveGenericParam::Resolve): new args
(TypeResolveGenericParam::ApplyAnyTraitBounds): new helper
(TypeResolveGenericParam::apply_trait_bounds): new field
(TypeResolveGenericParam::visit): update
* typecheck/rust-hir-type-check-type.h: new args
* typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): reuse helper
* typecheck/rust-type-util.cc (query_type): check for recursive query
* typecheck/rust-tyty-subst.cc (SubstitutionParamMapping::SubstitutionParamMapping):
remove const
(SubstitutionParamMapping::get_generic_param): likewise
* typecheck/rust-tyty-subst.h: likewise
* typecheck/rust-tyty-variance-analysis.cc (GenericTyVisitorCtx::process_type): likewise

gcc/testsuite/ChangeLog:

* rust/compile/issue-3625.rs: New test.

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
13 files changed:
gcc/rust/typecheck/rust-hir-trait-resolve.cc
gcc/rust/typecheck/rust-hir-type-check-base.cc
gcc/rust/typecheck/rust-hir-type-check-base.h
gcc/rust/typecheck/rust-hir-type-check-implitem.cc
gcc/rust/typecheck/rust-hir-type-check-path.cc
gcc/rust/typecheck/rust-hir-type-check-type.cc
gcc/rust/typecheck/rust-hir-type-check-type.h
gcc/rust/typecheck/rust-hir-type-check.cc
gcc/rust/typecheck/rust-type-util.cc
gcc/rust/typecheck/rust-tyty-subst.cc
gcc/rust/typecheck/rust-tyty-subst.h
gcc/rust/typecheck/rust-tyty-variance-analysis.cc
gcc/testsuite/rust/compile/issue-3625.rs [new file with mode: 0644]

index e33a8d0788fa22c1f572b63aaf15747128d878bd..1492839ce9d39fdbff1d154f706c2b5a03978e6c 100644 (file)
@@ -234,7 +234,9 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference)
            // The one exception is the implicit Self type of a trait
            bool apply_sized = !is_self;
            auto param_type
-             = TypeResolveGenericParam::Resolve (*generic_param, apply_sized);
+             = TypeResolveGenericParam::Resolve (*generic_param, true,
+                                                 apply_sized);
+
            context->insert_type (generic_param->get_mappings (), param_type);
            substitutions.push_back (
              TyTy::SubstitutionParamMapping (typaram, param_type));
index 55ab86f4105b3a899b9c2cd3d0b42f3146da8483..f2310216424cd905365236791d850ecfb204ef0b 100644 (file)
@@ -31,6 +31,16 @@ TypeCheckBase::TypeCheckBase ()
     context (TypeCheckContext::get ())
 {}
 
+void
+TypeCheckBase::ResolveGenericParams (
+  const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+  std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+  ABI abi)
+{
+  TypeCheckBase ctx;
+  ctx.resolve_generic_params (generic_params, substitutions, is_foreign, abi);
+}
+
 static void
 walk_types_to_constrain (std::set<HirId> &constrained_symbols,
                         const TyTy::SubstitutionArgumentMappings &constraints)
@@ -387,7 +397,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus)
 void
 TypeCheckBase::resolve_generic_params (
   const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
-  std::vector<TyTy::SubstitutionParamMapping> &substitutions)
+  std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+  ABI abi)
 {
   for (auto &generic_param : generic_params)
     {
@@ -400,10 +411,15 @@ TypeCheckBase::resolve_generic_params (
            context->get_lifetime_resolver ().insert_mapping (
              context->intern_lifetime (lifetime));
          }
-
          break;
 
          case HIR::GenericParam::GenericKind::CONST: {
+           if (is_foreign && abi != Rust::ABI::INTRINSIC)
+             {
+               rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+                              "foreign items may not have const parameters");
+             }
+
            auto &param
              = static_cast<HIR::ConstGenericParam &> (*generic_param);
            auto specified_type = TypeCheckType::Resolve (param.get_type ());
@@ -427,15 +443,31 @@ TypeCheckBase::resolve_generic_params (
          break;
 
          case HIR::GenericParam::GenericKind::TYPE: {
-           auto param_type = TypeResolveGenericParam::Resolve (*generic_param);
+           if (is_foreign && abi != Rust::ABI::INTRINSIC)
+             {
+               rust_error_at (generic_param->get_locus (), ErrorCode::E0044,
+                              "foreign items may not have type parameters");
+             }
+
+           auto param_type = TypeResolveGenericParam::Resolve (
+             *generic_param, false /*resolve_trait_bounds*/);
            context->insert_type (generic_param->get_mappings (), param_type);
 
-           substitutions.push_back (TyTy::SubstitutionParamMapping (
-             static_cast<HIR::TypeParam &> (*generic_param), param_type));
+           auto &param = static_cast<HIR::TypeParam &> (*generic_param);
+           TyTy::SubstitutionParamMapping p (param, param_type);
+           substitutions.push_back (p);
          }
          break;
        }
     }
+
+  // now walk them to setup any specified type param bounds
+  for (auto &subst : substitutions)
+    {
+      auto pty = subst.get_param_ty ();
+      TypeResolveGenericParam::ApplyAnyTraitBounds (subst.get_generic_param (),
+                                                   pty);
+    }
 }
 
 TyTy::TypeBoundPredicate
index d5005447b6fab9be098c9b34f5329fb01002512f..887195d8161872a2fc45c56f49e87b65e75b4b14 100644 (file)
@@ -32,6 +32,11 @@ class TypeCheckBase
 public:
   virtual ~TypeCheckBase () {}
 
+  static void ResolveGenericParams (
+    const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
+    std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign,
+    ABI abi);
+
 protected:
   TypeCheckBase ();
 
@@ -57,7 +62,8 @@ protected:
 
   void resolve_generic_params (
     const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params,
-    std::vector<TyTy::SubstitutionParamMapping> &substitutions);
+    std::vector<TyTy::SubstitutionParamMapping> &substitutions,
+    bool is_foreign = false, ABI abi = ABI::RUST);
 
   TyTy::TypeBoundPredicate get_marker_predicate (LangItem::Kind item_type,
                                                 location_t locus);
index 18ac0dd5c2d9404c45d9d909908166a5fadc07cb..55dd9514127c74148f7009b438d485ff8f4af386 100644 (file)
@@ -73,44 +73,8 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (function.has_generics ())
     {
-      for (auto &generic_param : function.get_generic_params ())
-       {
-         switch (generic_param.get ()->get_kind ())
-           {
-           case HIR::GenericParam::GenericKind::LIFETIME:
-             context->intern_and_insert_lifetime (
-               static_cast<HIR::LifetimeParam &> (*generic_param)
-                 .get_lifetime ());
-             // TODO: handle bounds
-             break;
-           case HIR::GenericParam::GenericKind::CONST:
-             // FIXME: Skipping Lifetime and Const completely until better
-             // handling.
-             if (parent.get_abi () != Rust::ABI::INTRINSIC)
-               {
-                 rust_error_at (function.get_locus (), ErrorCode::E0044,
-                                "foreign items may not have const parameters");
-               }
-             break;
-
-             case HIR::GenericParam::GenericKind::TYPE: {
-               if (parent.get_abi () != Rust::ABI::INTRINSIC)
-                 {
-                   rust_error_at (
-                     function.get_locus (), ErrorCode::E0044,
-                     "foreign items may not have type parameters");
-                 }
-               auto param_type
-                 = TypeResolveGenericParam::Resolve (*generic_param);
-               context->insert_type (generic_param->get_mappings (),
-                                     param_type);
-
-               substitutions.push_back (TyTy::SubstitutionParamMapping (
-                 static_cast<HIR::TypeParam &> (*generic_param), param_type));
-             }
-             break;
-           }
-       }
+      resolve_generic_params (function.get_generic_params (), substitutions,
+                             true /*is_foreign*/, parent.get_abi ());
     }
 
   TyTy::RegionConstraints region_constraints;
@@ -200,128 +164,7 @@ void
 TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type)
 {
   rust_sorry_at (type.get_locus (), "extern types are not supported yet");
-  //  auto binder_pin = context->push_clean_lifetime_resolver ();
-
-  //  std::vector<TyTy::SubstitutionParamMapping> substitutions;
-  //  if (function.has_generics ())
-  //    {
-  //      for (auto &generic_param : function.get_generic_params ())
-  // {
-  //   switch (generic_param.get ()->get_kind ())
-  //     {
-  //     case HIR::GenericParam::GenericKind::LIFETIME:
-  //       context->intern_and_insert_lifetime (
-  //   static_cast<HIR::LifetimeParam &> (*generic_param)
-  //     .get_lifetime ());
-  //       // TODO: handle bounds
-  //       break;
-  //     case HIR::GenericParam::GenericKind::CONST:
-  //       // FIXME: Skipping Lifetime and Const completely until better
-  //       // handling.
-  //       break;
-
-  //       case HIR::GenericParam::GenericKind::TYPE: {
-  //   auto param_type
-  //     = TypeResolveGenericParam::Resolve (generic_param.get ());
-  //   context->insert_type (generic_param->get_mappings (),
-  //                         param_type);
-
-  //   substitutions.push_back (TyTy::SubstitutionParamMapping (
-  //     static_cast<HIR::TypeParam &> (*generic_param), param_type));
-  //       }
-  //       break;
-  //     }
-  // }
-  //    }
-
-  //  TyTy::RegionConstraints region_constraints;
-  //  if (function.has_where_clause ())
-  //    {
-  //      for (auto &where_clause_item : function.get_where_clause ().get_items
-  //      ())
-  // {
-  //   ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
-  //                              region_constraints);
-  // }
-  //    }
-
-  //  TyTy::BaseType *ret_type = nullptr;
-  //  if (!function.has_return_type ())
-  //    ret_type
-  //      = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid
-  //      ());
-  //  else
-  //    {
-  //      auto resolved
-  // = TypeCheckType::Resolve (function.get_return_type ().get ());
-  //      if (resolved == nullptr)
-  // {
-  //   rust_error_at (function.get_locus (),
-  //            "failed to resolve return type");
-  //   return;
-  // }
-
-  //      ret_type = resolved->clone ();
-  //      ret_type->set_ref (
-  // function.get_return_type ()->get_mappings ().get_hirid ());
-  //    }
-
-  //  std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params;
-  //  for (auto &param : function.get_function_params ())
-  //    {
-  //      // get the name as well required for later on
-  //      auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ());
-
-  //      // these are implicit mappings and not used
-  //      auto crate_num = mappings->get_current_crate ();
-  //      Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id
-  //      (),
-  //                        mappings->get_next_hir_id (crate_num),
-  //                        UNKNOWN_LOCAL_DEFID);
-
-  //      HIR::IdentifierPattern *param_pattern
-  // = new HIR::IdentifierPattern (mapping, param.get_param_name (),
-  //                         UNDEF_LOCATION, false, Mutability::Imm,
-  //                         std::unique_ptr<HIR::Pattern> (nullptr));
-
-  //      params.push_back (
-  // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern,
-  //                                        param_tyty));
-
-  //      context->insert_type (param.get_mappings (), param_tyty);
-
-  //      // FIXME do we need error checking for patterns here?
-  //      // see https://github.com/Rust-GCC/gccrs/issues/995
-  //    }
-
-  //  uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG;
-  //  if (function.is_variadic ())
-  //    {
-  //      flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG;
-  //      if (parent.get_abi () != Rust::ABI::C)
-  // {
-  //   rust_error_at (
-  //     function.get_locus (), ErrorCode::E0045,
-  //     "C-variadic function must have C or cdecl calling convention");
-  // }
-  //    }
-
-  //  RustIdent ident{
-  //    CanonicalPath::new_seg (function.get_mappings ().get_nodeid (),
-  //               function.get_item_name ().as_string ()),
-  //    function.get_locus ()};
-
-  //  auto fnType = new TyTy::FnType (
-  //    function.get_mappings ().get_hirid (),
-  //    function.get_mappings ().get_defid (),
-  //    function.get_item_name ().as_string (), ident, flags, parent.get_abi (),
-  //    std::move (params), ret_type, std::move (substitutions),
-  //    TyTy::SubstitutionArgumentMappings::empty (
-  //      context->get_lifetime_resolver ().get_num_bound_regions ()),
-  //    region_constraints);
-
-  //  context->insert_type (function.get_mappings (), fnType);
-  //  resolved = fnType;
+  // TODO
 }
 
 TypeCheckImplItem::TypeCheckImplItem (
index 74ab1414e5840c8d8ab2a4565f50dce152791c74..4663e45beb71b6d754d51535430922410f6651fe 100644 (file)
@@ -336,7 +336,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
       TyTy::BaseType *lookup = nullptr;
       if (!query_type (ref, &lookup))
        {
-         if (is_root)
+         if (is_root || root_tyty == nullptr)
            {
              rust_error_at (expr.get_locus (), ErrorCode::E0425,
                             "cannot find value %qs in this scope",
index 630abb0d90e0bac5b8d87f761ca73fe79b665a2c..dff54f0f5772284719832960826c9e2fc58c1248 100644 (file)
@@ -417,8 +417,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
       TyTy::BaseType *lookup = nullptr;
       if (!query_type (ref, &lookup))
        {
-         if (is_root)
-           return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+         if (is_root || root_tyty == nullptr)
+           {
+             rust_error_at (seg->get_locus (),
+                            "failed to resolve type path segment: %qs",
+                            seg->as_string ().c_str ());
+             return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
+           }
 
          return root_tyty;
        }
@@ -573,6 +578,7 @@ TypeCheckType::resolve_segments (
                                        ignore_mandatory_trait_items);
              if (candidates.size () == 0)
                {
+                 prev_segment->debug ();
                  rust_error_at (
                    seg->get_locus (),
                    "failed to resolve path segment using an impl Probe");
@@ -797,9 +803,10 @@ TypeCheckType::visit (HIR::ImplTraitType &type)
 }
 
 TyTy::ParamType *
-TypeResolveGenericParam::Resolve (HIR::GenericParam &param, bool apply_sized)
+TypeResolveGenericParam::Resolve (HIR::GenericParam &param,
+                                 bool resolve_trait_bounds, bool apply_sized)
 {
-  TypeResolveGenericParam resolver (apply_sized);
+  TypeResolveGenericParam resolver (apply_sized, resolve_trait_bounds);
   switch (param.get_kind ())
     {
     case HIR::GenericParam::GenericKind::TYPE:
@@ -817,6 +824,14 @@ TypeResolveGenericParam::Resolve (HIR::GenericParam &param, bool apply_sized)
   return resolver.resolved;
 }
 
+void
+TypeResolveGenericParam::ApplyAnyTraitBounds (HIR::TypeParam &param,
+                                             TyTy::ParamType *pty)
+{
+  TypeResolveGenericParam resolver (true, true);
+  resolver.apply_trait_bounds (param, pty);
+}
+
 void
 TypeResolveGenericParam::visit (HIR::LifetimeParam &param)
 {
@@ -835,6 +850,19 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
   if (param.has_type ())
     TypeCheckType::Resolve (param.get_type ());
 
+  resolved
+    = new TyTy::ParamType (param.get_type_representation ().as_string (),
+                          param.get_locus (),
+                          param.get_mappings ().get_hirid (), param, {});
+
+  if (resolve_trait_bounds)
+    apply_trait_bounds (param, resolved);
+}
+
+void
+TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam &param,
+                                            TyTy::ParamType *pty)
+{
   std::unique_ptr<HIR::Type> implicit_self_bound = nullptr;
   if (param.has_type_param_bounds ())
     {
@@ -865,8 +893,6 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
   //
   // We can only do this when we are not resolving the implicit Self for Sized
   // itself
-  rust_debug_loc (param.get_locus (), "apply_sized: %s",
-                 apply_sized ? "true" : "false");
   if (apply_sized)
     {
       TyTy::TypeBoundPredicate sized_predicate
@@ -941,10 +967,8 @@ TypeResolveGenericParam::visit (HIR::TypeParam &param)
        }
     }
 
-  resolved = new TyTy::ParamType (param.get_type_representation ().as_string (),
-                                 param.get_locus (),
-                                 param.get_mappings ().get_hirid (), param,
-                                 specified_bounds);
+  // inherit them
+  pty->inherit_bounds (specified_bounds);
 }
 
 void
index f52bd2f2c1f0e738167061251497e08fb6ff7df0..91eeac7e894ce49bdae4957613bef42ebec6397b 100644 (file)
@@ -91,20 +91,27 @@ class TypeResolveGenericParam : public TypeCheckBase
 {
 public:
   static TyTy::ParamType *Resolve (HIR::GenericParam &param,
+                                  bool resolve_trait_bounds = true,
                                   bool apply_sized = true);
 
+  static void ApplyAnyTraitBounds (HIR::TypeParam &param, TyTy::ParamType *pty);
+
 protected:
   void visit (HIR::TypeParam &param);
   void visit (HIR::LifetimeParam &param);
   void visit (HIR::ConstGenericParam &param);
 
+  void apply_trait_bounds (HIR::TypeParam &param, TyTy::ParamType *pty);
+
 private:
-  TypeResolveGenericParam (bool apply_sized)
-    : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized)
+  TypeResolveGenericParam (bool apply_sized, bool resolve_trait_bounds)
+    : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized),
+      resolve_trait_bounds (resolve_trait_bounds)
   {}
 
   TyTy::ParamType *resolved;
   bool apply_sized;
+  bool resolve_trait_bounds;
 };
 
 class ResolveWhereClauseItem : public TypeCheckBase
index 1e9f7d2f00dd3607cbdc04ae9cf9c1c895efef86..3deb5b7ea496a7f6b3543b13392a068ba3d4be54 100644 (file)
@@ -165,36 +165,9 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
   HIR::TraitFunctionDecl &function = fn.get_decl ();
   if (function.has_generics ())
     {
-      for (auto &generic_param : function.get_generic_params ())
-       {
-         switch (generic_param.get ()->get_kind ())
-           {
-             case HIR::GenericParam::GenericKind::LIFETIME: {
-               auto lifetime_param
-                 = static_cast<HIR::LifetimeParam &> (*generic_param);
-
-               context->intern_and_insert_lifetime (
-                 lifetime_param.get_lifetime ());
-               // TODO: Handle lifetime bounds
-             }
-             break;
-           case HIR::GenericParam::GenericKind::CONST:
-             // FIXME: Skipping Lifetime and Const completely until better
-             // handling.
-             break;
-
-             case HIR::GenericParam::GenericKind::TYPE: {
-               auto param_type
-                 = TypeResolveGenericParam::Resolve (*generic_param);
-               context->insert_type (generic_param->get_mappings (),
-                                     param_type);
-
-               substitutions.push_back (TyTy::SubstitutionParamMapping (
-                 static_cast<HIR::TypeParam &> (*generic_param), param_type));
-             }
-             break;
-           }
-       }
+      TypeCheckBase::ResolveGenericParams (function.get_generic_params (),
+                                          substitutions, false /*is_foreign*/,
+                                          ABI::RUST);
     }
 
   if (function.has_where_clause ())
index 47bf67943640dc5dfc5a43247d344ffb7664ab0f..d3d4492424f7f5716bf6b2fce67d4ecc4266132c 100644 (file)
 #include "rust-hir-type-check-implitem.h"
 #include "rust-hir-type-check-item.h"
 #include "rust-hir-type-check.h"
+#include "rust-hir-type-check-type.h"
 #include "rust-casts.h"
 #include "rust-unify.h"
 #include "rust-coercion.h"
 #include "rust-hir-type-bounds.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "options.h"
 
 namespace Rust {
 namespace Resolver {
@@ -34,6 +37,7 @@ bool
 query_type (HirId reference, TyTy::BaseType **result)
 {
   auto &mappings = Analysis::Mappings::get ();
+  auto &resolver = *Resolver::get ();
   TypeCheckContext *context = TypeCheckContext::get ();
 
   if (context->query_in_progress (reference))
@@ -91,6 +95,39 @@ query_type (HirId reference, TyTy::BaseType **result)
       HIR::ImplBlock *impl = impl_block_by_type.value ();
       rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to",
                      reference);
+
+      // this could be recursive to the root type
+      if (impl->has_type ())
+       {
+         HIR::Type &ty = impl->get_type ();
+         NodeId ref_node_id = UNKNOWN_NODEID;
+         NodeId ast_node_id = ty.get_mappings ().get_nodeid ();
+
+         if (flag_name_resolution_2_0)
+           {
+             auto &nr_ctx = Resolver2_0::ImmutableNameResolutionContext::get ()
+                              .resolver ();
+
+             // assign the ref_node_id if we've found something
+             nr_ctx.lookup (ast_node_id)
+               .map (
+                 [&ref_node_id] (NodeId resolved) { ref_node_id = resolved; });
+           }
+         else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id))
+           resolver.lookup_resolved_type (ast_node_id, &ref_node_id);
+
+         if (ref_node_id != UNKNOWN_NODEID)
+           {
+             tl::optional<HirId> hid
+               = mappings.lookup_node_to_hir (ref_node_id);
+             if (hid.has_value () && context->query_in_progress (hid.value ()))
+               {
+                 context->query_completed (reference);
+                 return false;
+               }
+           }
+       }
+
       *result = TypeCheckItem::ResolveImplBlockSelf (*impl);
       context->query_completed (reference);
       return true;
index fb94c14c15603be0890a856715175f72436ed76e..c3033eed5f7d16ef255e9c71141e1466fa5d8392 100644 (file)
@@ -28,8 +28,8 @@
 namespace Rust {
 namespace TyTy {
 
-SubstitutionParamMapping::SubstitutionParamMapping (
-  const HIR::TypeParam &generic, ParamType *param)
+SubstitutionParamMapping::SubstitutionParamMapping (HIR::TypeParam &generic,
+                                                   ParamType *param)
   : generic (generic), param (param)
 {}
 
@@ -66,8 +66,8 @@ SubstitutionParamMapping::get_param_ty () const
   return param;
 }
 
-const HIR::TypeParam &
-SubstitutionParamMapping::get_generic_param () const
+HIR::TypeParam &
+SubstitutionParamMapping::get_generic_param ()
 {
   return generic;
 }
index 65d5d5a8ff16827692e85b598ce5671540478041..8a43b917a54f6a724e1bc3f6b6e298330d2eb19a 100644 (file)
@@ -44,7 +44,7 @@ class SubstitutionArgumentMappings;
 class SubstitutionParamMapping
 {
 public:
-  SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param);
+  SubstitutionParamMapping (HIR::TypeParam &generic, ParamType *param);
 
   SubstitutionParamMapping (const SubstitutionParamMapping &other);
 
@@ -59,7 +59,7 @@ public:
 
   const ParamType *get_param_ty () const;
 
-  const HIR::TypeParam &get_generic_param () const;
+  HIR::TypeParam &get_generic_param ();
 
   // this is used for the backend to override the HirId ref of the param to
   // what the concrete type is for the rest of the context
@@ -76,7 +76,7 @@ public:
   bool need_substitution () const;
 
 private:
-  const HIR::TypeParam &generic;
+  HIR::TypeParam &generic;
   ParamType *param;
 };
 
index 1aba57631a2975281b8c98d5dfdc6954f9a1a7e5..38f9d526e045a26c5110a5f4ddfd7d2064a94025 100644 (file)
@@ -238,7 +238,7 @@ GenericTyVisitorCtx::process_type (ADTType &ty)
   first_lifetime = lookup_or_add_type (ty.get_orig_ref ());
   first_type = first_lifetime + ty.get_used_arguments ().get_regions ().size ();
 
-  for (const auto &param : ty.get_substs ())
+  for (auto &param : ty.get_substs ())
     param_names.push_back (
       param.get_generic_param ().get_type_representation ().as_string ());
 
diff --git a/gcc/testsuite/rust/compile/issue-3625.rs b/gcc/testsuite/rust/compile/issue-3625.rs
new file mode 100644 (file)
index 0000000..91e0dc9
--- /dev/null
@@ -0,0 +1,2 @@
+type A = crate::A;
+// { dg-error "failed to resolve type path segment: .A." "" { target *-*-* } .-2 }