aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-09-30 13:41:09 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-09-30 13:41:09 +0100
commitd1069815fa6238712f51a23dfd43d2ae6cd7c5e8 (patch)
tree0589da7b5ad57afa7743056e05a94404ad9364ce /gcc
parent9b1ba11b0b2f873b85dfc7643fe778e974e874b8 (diff)
downloadgcc-d1069815fa6238712f51a23dfd43d2ae6cd7c5e8.zip
gcc-d1069815fa6238712f51a23dfd43d2ae6cd7c5e8.tar.gz
gcc-d1069815fa6238712f51a23dfd43d2ae6cd7c5e8.tar.bz2
Add catch for recusive type queries
When we have a type query where by generic substitution occurs we can hit the case where we need to Probe the bounds of the substited item to determine whether the the bounds are compatible this can cause us to end up querying the same type recursively. Fixes #1550
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-base.cc10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h12
-rw-r--r--gcc/rust/typecheck/rust-tyty-bounds.cc5
3 files changed, 25 insertions, 2 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc
index bd6a2fb..8107ef5 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc
@@ -495,14 +495,20 @@ TypeCheckBase::resolve_generic_params (
bool
TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
{
+ if (context->query_in_progress (reference))
+ return false;
+
if (context->lookup_type (reference, result))
return true;
+ context->insert_query (reference);
+
HIR::Item *item = mappings->lookup_hir_item (reference);
if (item != nullptr)
{
rust_debug_loc (item->get_locus (), "resolved item {%u} to", reference);
*result = TypeCheckItem::Resolve (*item);
+ context->query_completed (reference);
return true;
}
@@ -520,6 +526,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
reference);
*result = TypeCheckItem::ResolveImplItem (*impl_block, *impl_item);
+ context->query_completed (reference);
return true;
}
@@ -530,6 +537,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
if (found_impl_block_type)
{
*result = TypeCheckItem::ResolveImplBlockSelf (*impl_block_by_type);
+ context->query_completed (reference);
return true;
}
@@ -544,6 +552,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
rust_assert (block != nullptr);
*result = TypeCheckTopLevelExternItem::Resolve (extern_item, *block);
+ context->query_completed (reference);
return true;
}
@@ -551,6 +560,7 @@ TypeCheckBase::query_type (HirId reference, TyTy::BaseType **result)
Location possible_locus = mappings->lookup_location (reference);
rust_debug_loc (possible_locus, "query system failed to resolve: [%u]",
reference);
+ context->query_completed (reference);
return false;
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index c17db71..f85585b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -372,6 +372,15 @@ public:
return true;
}
+ void insert_query (HirId id) { querys_in_progress.insert (id); }
+
+ void query_completed (HirId id) { querys_in_progress.erase (id); }
+
+ bool query_in_progress (HirId id) const
+ {
+ return querys_in_progress.find (id) != querys_in_progress.end ();
+ }
+
private:
TypeCheckContext ();
@@ -406,6 +415,9 @@ private:
// predicates
std::map<HirId, TyTy::TypeBoundPredicate> predicates;
+
+ // query context lookups
+ std::set<HirId> querys_in_progress;
};
class TypeResolution
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index ec4a11f..d7647b7 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -34,8 +34,9 @@ TypeBoundsProbe::scan ()
if (!impl->has_trait_ref ())
return true;
- TyTy::BaseType *impl_type = TypeCheckItem::ResolveImplBlockSelf (*impl);
- if (impl_type->get_kind () == TyTy::TypeKind::ERROR)
+ HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
+ TyTy::BaseType *impl_type = nullptr;
+ if (!query_type (impl_ty_id, &impl_type))
return true;
if (!receiver->can_eq (impl_type, false))