]> 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)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 8 Apr 2025 08:17:12 +0000 (10:17 +0200)
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 a236fd78d7b162e41a9d6891b15aecb7044240c9..e78c19263dc18b0bb6aba313549d64cb35b59962 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 d3d688217348f96b66740eb678b61675c00111ec..beee91e79444d5efd40e1e1bde4c2b86fde4b779 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 8a1bf6f4cb35668b996509771ae85d1f8b6d2030..580082a6adfb76726d1f58963a2277f7b42ed7a8 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 a5ae54bf4930da9f863fc0ac4ddd02b95c054c38..29864b0c8e6d66163824ee8db30d98ca3e6fb43a 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 1fe39aaeb649ebe7d0e07f21ed431d37f922f272..5662da5310e5efd0bdc5db887bac4f30739af688 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 54f50ec41f18942d857594bc3b7bb60767fb0b58..6919093b0f5f36aac810ccaa19e4e2e1e4c4a005 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 fc272e639a3f6c209e28081d7cd21d375cc48a5e..cc991b66eb89d34e5f32df00278980a984a80681 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 a198ad3d66da945fe7302af0654cccec09bb1fe6..49c19055300d841e072ae4cba4817a69ab8ecd3e 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 4abfbae36655790fad0968e72276ad2722963535..c6c5b4bb55fa5db0aad2967148ec989801b7c2c7 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 95f18b9d29fc3d4a9a12c406387713606113aa94..bdb6474aeeb466ac6a163958c9fa6deab59e47be 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 3f0b912fa7b0fc0cda04cbe885ed0984efa25796..e6ed1fc42d670adcad2dee6608d473771f790c44 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 }