public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] borrowck: extract regions from types using VA
@ 2024-05-07 16:30 Thomas Schwinge
0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2024-05-07 16:30 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:a019aa9fbde5ab752044fb7efe276aa0dde8646d
commit a019aa9fbde5ab752044fb7efe276aa0dde8646d
Author: Jakub Dupak <dev@jakubdupak.com>
Date: Tue Feb 27 21:31:07 2024 +0100
borrowck: extract regions from types using VA
Biggybag on variance analysis to extract regions of fields from ADT
regions.
gcc/rust/ChangeLog:
* typecheck/rust-tyty-variance-analysis-private.h (class FieldVisitorCtx):
Region extraction.
* typecheck/rust-tyty-variance-analysis.cc (query_field_regions): Region extraction.
(FieldVisitorCtx::collect_regions): Region extraction.
(FieldVisitorCtx::add_constraints_from_ty): Region extraction.
(FieldVisitorCtx::add_constraints_from_region): Region
extraction.
(FieldVisitorCtx::add_constrints_from_param): Region extraction.
* typecheck/rust-tyty-variance-analysis.h (query_field_regions):
Region extraction.
Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
Diff:
---
.../rust-tyty-variance-analysis-private.h | 41 ++++++++++
gcc/rust/typecheck/rust-tyty-variance-analysis.cc | 87 +++++++++++++++++++++-
gcc/rust/typecheck/rust-tyty-variance-analysis.h | 31 ++++----
3 files changed, 140 insertions(+), 19 deletions(-)
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
index ab8c039238eb..41a0d6f582fd 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis-private.h
@@ -201,6 +201,13 @@ public: // Module internal API
std::vector<Variance> query_generic_variance (const ADTType &type);
+ std::vector<size_t> query_field_regions (const ADTType *parent,
+ size_t variant_index,
+ size_t field_index,
+ const FreeRegions &parent_regions);
+
+ std::vector<Region> query_type_regions (BaseType *base);
+
public: // Data used by visitors.
// This whole class is private, therfore members can be public.
@@ -296,6 +303,40 @@ private:
std::vector<Region> regions;
};
+/** Extracts regions of a field from regions of parent ADT. */
+class FieldVisitorCtx : public VarianceVisitorCtx<Variance>
+{
+public:
+ using Visitor = VisitorBase<Variance>;
+
+ std::vector<size_t> collect_regions (BaseType &ty);
+
+ FieldVisitorCtx (GenericTyPerCrateCtx &ctx, const SubstitutionRef &subst,
+ const FreeRegions &parent_regions)
+ : ctx (ctx), subst (subst), parent_regions (parent_regions)
+ {}
+
+ void add_constraints_from_ty (BaseType *ty, Variance variance) override;
+ void add_constraints_from_region (const Region ®ion,
+ Variance variance) override;
+ void add_constraints_from_generic_args (HirId ref, SubstitutionRef &subst,
+ Variance variance,
+ bool invariant_args) override{};
+ void add_constrints_from_param (ParamType ¶m, Variance variance) override;
+
+ Variance contra (Variance variance) override
+ {
+ return Variance::transform (variance, Variance::contravariant ());
+ }
+
+private:
+ GenericTyPerCrateCtx &ctx;
+ const SubstitutionRef &subst;
+ std::vector<size_t> regions;
+ FreeRegions parent_regions;
+ std::vector<size_t> type_param_ranges;
+};
+
} // namespace VarianceAnalysis
} // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
index 5a21d69651b0..d7116f5eb807 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc
@@ -49,8 +49,16 @@ CrateCtx::query_type_variances (BaseType *type)
std::vector<Region>
CrateCtx::query_type_regions (BaseType *type)
{
- TyVisitorCtx ctx (*private_ctx);
- return ctx.collect_regions (*type);
+ return private_ctx->query_type_regions (type);
+}
+
+std::vector<size_t>
+CrateCtx::query_field_regions (const ADTType *parent, size_t variant_index,
+ size_t field_index,
+ const FreeRegions &parent_regions)
+{
+ return private_ctx->query_field_regions (parent, variant_index, field_index,
+ parent_regions);
}
Variance
@@ -324,6 +332,29 @@ GenericTyPerCrateCtx::query_generic_variance (const ADTType &type)
return result;
}
+std::vector<size_t>
+GenericTyPerCrateCtx::query_field_regions (const ADTType *parent,
+ size_t variant_index,
+ size_t field_index,
+ const FreeRegions &parent_regions)
+{
+ auto orig = lookup_type (parent->get_orig_ref ());
+ FieldVisitorCtx ctx (*this, *parent->as<const SubstitutionRef> (),
+ parent_regions);
+ return ctx.collect_regions (*orig->as<const ADTType> ()
+ ->get_variants ()
+ .at (variant_index)
+ ->get_fields ()
+ .at (field_index)
+ ->get_field_type ());
+}
+std::vector<Region>
+GenericTyPerCrateCtx::query_type_regions (BaseType *type)
+{
+ TyVisitorCtx ctx (*this);
+ return ctx.collect_regions (*type);
+}
+
SolutionIndex
GenericTyVisitorCtx::lookup_or_add_type (HirId hir_id)
{
@@ -506,6 +537,58 @@ TyVisitorCtx::add_constraints_from_generic_args (HirId ref,
}
}
+std::vector<size_t>
+FieldVisitorCtx::collect_regions (BaseType &ty)
+{
+ // Segment the regions into ranges for each type parameter. Type parameter
+ // at index i contains regions from type_param_ranges[i] to
+ // type_param_ranges[i+1] (exclusive).;
+ type_param_ranges.push_back (subst.get_num_lifetime_params ());
+
+ for (size_t i = 0; i < subst.get_num_type_params (); i++)
+ {
+ auto arg = subst.get_arg_at (i);
+ rust_assert (arg.has_value ());
+ type_param_ranges.push_back (
+ ctx.query_type_regions (arg.value ().get_tyty ()).size ());
+ }
+
+ add_constraints_from_ty (&ty, Variance::covariant ());
+ return regions;
+}
+
+void
+FieldVisitorCtx::add_constraints_from_ty (BaseType *ty, Variance variance)
+{
+ Visitor visitor (*this, variance);
+ ty->accept_vis (visitor);
+}
+
+void
+FieldVisitorCtx::add_constraints_from_region (const Region ®ion,
+ Variance variance)
+{
+ if (region.is_early_bound ())
+ {
+ regions.push_back (parent_regions[region.get_index ()]);
+ }
+ else if (region.is_late_bound ())
+ {
+ rust_debug ("Ignoring late bound region");
+ }
+}
+
+void
+FieldVisitorCtx::add_constrints_from_param (ParamType ¶m, Variance variance)
+{
+ size_t param_i = subst.get_used_arguments ().find_symbol (param).value ();
+ for (size_t i = type_param_ranges[param_i];
+ i < type_param_ranges[param_i + 1]; i++)
+ {
+ regions.push_back (parent_regions[i]);
+ }
+}
+
Variance
TyVisitorCtx::contra (Variance variance)
{
diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.h b/gcc/rust/typecheck/rust-tyty-variance-analysis.h
index a1defd62e54a..27e8d8b3ea03 100644
--- a/gcc/rust/typecheck/rust-tyty-variance-analysis.h
+++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.h
@@ -3,6 +3,8 @@
#include "rust-tyty.h"
+#include <rust-bir-free-region.h>
+
namespace Rust {
namespace TyTy {
namespace VarianceAnalysis {
@@ -31,11 +33,19 @@ public:
/** Get regions mentioned in a type. */
std::vector<Region> query_type_regions (BaseType *type);
+ std::vector<size_t> query_field_regions (const ADTType *parent,
+ size_t variant_index,
+ size_t field_index,
+ const FreeRegions &parent_regions);
private:
std::unique_ptr<GenericTyPerCrateCtx> private_ctx;
};
+std::vector<size_t>
+query_field_regions (const ADTType *parent, size_t variant_index,
+ size_t field_index, const FreeRegions &parent_regions);
+
/** Variance semilattice */
class Variance
{
@@ -55,22 +65,10 @@ class Variance
public:
constexpr Variance () : kind (TOP) {}
- WARN_UNUSED_RESULT constexpr bool is_bivariant () const
- {
- return kind == BIVARIANT;
- }
- WARN_UNUSED_RESULT constexpr bool is_covariant () const
- {
- return kind == COVARIANT;
- }
- WARN_UNUSED_RESULT constexpr bool is_contravariant () const
- {
- return kind == CONTRAVARIANT;
- }
- WARN_UNUSED_RESULT constexpr bool is_invariant () const
- {
- return kind == INVARIANT;
- }
+ constexpr bool is_bivariant () const { return kind == BIVARIANT; }
+ constexpr bool is_covariant () const { return kind == COVARIANT; }
+ constexpr bool is_contravariant () const { return kind == CONTRAVARIANT; }
+ constexpr bool is_invariant () const { return kind == INVARIANT; }
static constexpr Variance bivariant () { return {BIVARIANT}; }
static constexpr Variance covariant () { return {COVARIANT}; }
@@ -97,7 +95,6 @@ public:
{
return lhs.kind == rhs.kind;
}
-
constexpr friend bool operator!= (const Variance &lhs, const Variance &rhs)
{
return !(lhs == rhs);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2024-05-07 16:30 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-07 16:30 [gcc/devel/rust/master] borrowck: extract regions from types using VA Thomas Schwinge
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).