aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2025-04-02 18:21:46 +0100
committerPhilip Herron <philip.herron@embecosm.com>2025-04-03 14:53:54 +0000
commit67017c92b8cb51064243c9c76b0fafe3c80e17b2 (patch)
tree31adf8f350aa89a6f74252976e5e58057f60e005 /gcc
parent8cd24f83386f0e7c20c80f1517d8236515767f51 (diff)
downloadgcc-67017c92b8cb51064243c9c76b0fafe3c80e17b2.zip
gcc-67017c92b8cb51064243c9c76b0fafe3c80e17b2.tar.gz
gcc-67017c92b8cb51064243c9c76b0fafe3c80e17b2.tar.bz2
gccrs: Fix recusive type query and nullptr on type path
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>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc42
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.h8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc163
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc44
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h11
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc33
-rw-r--r--gcc/rust/typecheck/rust-type-util.cc37
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.cc8
-rw-r--r--gcc/rust/typecheck/rust-tyty-subst.h6
-rw-r--r--gcc/rust/typecheck/rust-tyty-variance-analysis.cc2
-rw-r--r--gcc/testsuite/rust/compile/issue-3625.rs2
13 files changed, 144 insertions, 218 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index e33a8d0..1492839 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -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));
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index 55ab86f..f231021 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -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
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index d500544..887195d 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -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);
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 18ac0dd..55dd951 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -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 (
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 74ab141..4663e45 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -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",
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 630abb0..dff54f0 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -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:
@@ -818,6 +825,14 @@ TypeResolveGenericParam::Resolve (HIR::GenericParam &param, bool apply_sized)
}
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)
{
// nothing to do
@@ -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
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index f52bd2f..91eeac7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -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
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 1e9f7d2..3deb5b7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -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 ())
diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc
index 47bf679..d3d4492 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -22,10 +22,13 @@
#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;
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index fb94c14..c3033ee 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -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;
}
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index 65d5d5a..8a43b91 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -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;
};
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
index 1aba576..38f9d52 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
@@ -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
index 0000000..91e0dc9
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-3625.rs
@@ -0,0 +1,2 @@
+type A = crate::A;
+// { dg-error "failed to resolve type path segment: .A." "" { target *-*-* } .-2 }