diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-09-30 15:02:32 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-30 15:02:32 +0000 |
commit | 8ff035ddc55079161d24941785114aa0f5056260 (patch) | |
tree | 0589da7b5ad57afa7743056e05a94404ad9364ce /gcc | |
parent | 9b1ba11b0b2f873b85dfc7643fe778e974e874b8 (diff) | |
parent | d1069815fa6238712f51a23dfd43d2ae6cd7c5e8 (diff) | |
download | gcc-8ff035ddc55079161d24941785114aa0f5056260.zip gcc-8ff035ddc55079161d24941785114aa0f5056260.tar.gz gcc-8ff035ddc55079161d24941785114aa0f5056260.tar.bz2 |
Merge #1551
1551: Add catch for recusive type queries r=philberty a=philberty
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
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-base.cc | 10 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check.h | 12 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-bounds.cc | 5 |
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)) |