diff mbox series

[COMMITTED,07/25] gccrs: TyTy: Store region constraints

Message ID 20240207114419.1100894-8-arthur.cohen@embecosm.com
State New
Headers show
Series [COMMITTED,01/25] gccrs: Parse normal functions with `self` parameter correctly | expand

Commit Message

Arthur Cohen Feb. 7, 2024, 11:43 a.m. UTC
From: Jakub Dupak <dev@jakubdupak.com>

gcc/rust/ChangeLog:

	* typecheck/rust-hir-type-check-implitem.cc (TypeCheckTopLevelExternItem::visit):
	Add region constraints.
	(TypeCheckImplItem::visit): Add region constraints.
	* typecheck/rust-hir-type-check-implitem.h: Add region constraints.
	* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::ResolveImplBlockSelf):
	Add region constraints.
	(TypeCheckItem::visit): Add region constraints.
	(TypeCheckItem::resolve_impl_item): Add region constraints.
	(TypeCheckItem::resolve_impl_block_substitutions): Add region constraints.
	* typecheck/rust-hir-type-check-item.h: Add region constraints.
	* typecheck/rust-hir-type-check-type.cc (ResolveWhereClauseItem::Resolve):
	Add region constraints.
	(ResolveWhereClauseItem::visit): Add region constraints.
	* typecheck/rust-hir-type-check-type.h (class ResolveWhereClauseItem):
	Add region constraints.
	* typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn):
	Add region constraints.
	* typecheck/rust-tyty-bounds.cc (TypeBoundPredicate::TypeBoundPredicate):
	Add region constraints.
	* typecheck/rust-tyty-subst.cc (SubstitutionRef::get_region_constraints):
	Add region constraints.
	* typecheck/rust-tyty-subst.h (class BaseType): Add region constraints.
	(struct RegionConstraints): Add region constraints.
	* typecheck/rust-tyty.cc (BaseType::monomorphized_clone): Add region constraints.
	(ADTType::clone): Add region constraints.
	(FnType::clone): Add region constraints.
	(ProjectionType::clone): Add region constraints.
	* typecheck/rust-tyty.h: Add region constraints.

Signed-off-by: Jakub Dupak <dev@jakubdupak.com>
---
 .../typecheck/rust-hir-type-check-implitem.cc | 24 ++++++--
 .../typecheck/rust-hir-type-check-implitem.h  |  1 +
 .../typecheck/rust-hir-type-check-item.cc     | 58 +++++++++++++------
 gcc/rust/typecheck/rust-hir-type-check-item.h |  3 +-
 .../typecheck/rust-hir-type-check-type.cc     | 11 +++-
 gcc/rust/typecheck/rust-hir-type-check-type.h | 10 +++-
 gcc/rust/typecheck/rust-hir-type-check.cc     | 11 +++-
 gcc/rust/typecheck/rust-tyty-bounds.cc        |  8 +--
 gcc/rust/typecheck/rust-tyty-subst.cc         | 11 +++-
 gcc/rust/typecheck/rust-tyty-subst.h          | 17 +++++-
 gcc/rust/typecheck/rust-tyty.cc               | 23 +++++---
 gcc/rust/typecheck/rust-tyty.h                | 27 ++++++---
 12 files changed, 151 insertions(+), 53 deletions(-)

Comments

Arthur Cohen Feb. 7, 2024, 2:46 p.m. UTC | #1
On 2/7/24 16:26, Bernhard Reutner-Fischer wrote:
> On Wed,  7 Feb 2024 12:43:53 +0100
> arthur.cohen@embecosm.com wrote:
> 
>> diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
>> index 067465ec77a..4d178440775 100644
>> --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
>> +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
>> @@ -97,6 +97,7 @@ private:
>>     HIR::ImplBlock *parent;
>>     TyTy::BaseType *self;
>>     std::vector<TyTy::SubstitutionParamMapping> substitutions;
>> +  TyTy::RegionConstraints region_costraints;
>>   };
> 
> /region_costraint/s/cos/cons/;# or delete since it seems unused ATM?
> 
> thanks

Thanks!

We're merging this in our development branch at the moment and it will 
be upstreamed soon. I'd rather keep the field for now as one of our 
contributor is working on this and splitting commits as much as possible 
to make reviewing easier.

Kindly,

Arthur
Bernhard Reutner-Fischer Feb. 7, 2024, 3:26 p.m. UTC | #2
On Wed,  7 Feb 2024 12:43:53 +0100
arthur.cohen@embecosm.com wrote:

> diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
> index 067465ec77a..4d178440775 100644
> --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
> +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
> @@ -97,6 +97,7 @@ private:
>    HIR::ImplBlock *parent;
>    TyTy::BaseType *self;
>    std::vector<TyTy::SubstitutionParamMapping> substitutions;
> +  TyTy::RegionConstraints region_costraints;
>  };

/region_costraint/s/cos/cons/;# or delete since it seems unused ATM?

thanks
diff mbox series

Patch

diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
index 0ca59dea899..6b4141a4270 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc
@@ -96,6 +96,16 @@  TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
 	}
     }
 
+  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
@@ -166,7 +176,8 @@  TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function)
     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 ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (function.get_mappings (), fnType);
   resolved = fnType;
@@ -206,9 +217,11 @@  TypeCheckImplItem::visit (HIR::Function &function)
   if (function.has_generics ())
     resolve_generic_params (function.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : function.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+				       region_constraints);
     }
 
   TyTy::BaseType *ret_type = nullptr;
@@ -334,7 +347,8 @@  TypeCheckImplItem::visit (HIR::Function &function)
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     ABI::RUST, std::move (params), ret_type, std::move (substitutions),
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (function.get_mappings (), fnType);
   result = fnType;
@@ -389,9 +403,11 @@  TypeCheckImplItem::visit (HIR::TypeAlias &alias)
 
   context->insert_type (alias.get_mappings (), actual_type);
   result = actual_type;
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : alias.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item.get ());
+      ResolveWhereClauseItem::Resolve (*where_clause_item.get (),
+				       region_constraints);
     }
 }
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index 067465ec77a..4d178440775 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -97,6 +97,7 @@  private:
   HIR::ImplBlock *parent;
   TyTy::BaseType *self;
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
+  TyTy::RegionConstraints region_costraints;
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index eb2698ead28..16b4906a356 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -63,12 +63,15 @@  TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
   TypeCheckItem resolver;
 
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
+  auto result
     = resolver.resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
     {
       return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     }
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
 
   return resolver.resolve_impl_block_self (impl_block);
 }
@@ -81,12 +84,14 @@  TypeCheckItem::ResolveImplBlockSelfWithInference (
   TypeCheckItem resolver;
 
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
-    = resolver.resolve_impl_block_substitutions (impl, failed_flag);
+  auto result = resolver.resolve_impl_block_substitutions (impl, failed_flag);
   if (failed_flag)
     {
       return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
     }
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
 
   // now that we have the param mappings we need to query the self type
   TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
@@ -140,9 +145,10 @@  TypeCheckItem::visit (HIR::TypeAlias &alias)
 
   context->insert_type (alias.get_mappings (), actual_type);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : alias.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
   infered = actual_type;
 }
@@ -156,9 +162,10 @@  TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
   if (struct_decl.has_generics ())
     resolve_generic_params (struct_decl.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -203,7 +210,8 @@  TypeCheckItem::visit (HIR::TupleStruct &struct_decl)
     TyTy::ADTType::ADTKind::TUPLE_STRUCT, std::move (variants),
     std::move (substitutions), repr,
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
@@ -218,9 +226,10 @@  TypeCheckItem::visit (HIR::StructStruct &struct_decl)
   if (struct_decl.has_generics ())
     resolve_generic_params (struct_decl.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : struct_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -263,7 +272,8 @@  TypeCheckItem::visit (HIR::StructStruct &struct_decl)
     TyTy::ADTType::ADTKind::STRUCT_STRUCT, std::move (variants),
     std::move (substitutions), repr,
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (struct_decl.get_mappings (), type);
   infered = type;
@@ -316,9 +326,10 @@  TypeCheckItem::visit (HIR::Union &union_decl)
   if (union_decl.has_generics ())
     resolve_generic_params (union_decl.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : union_decl.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   std::vector<TyTy::StructFieldType *> fields;
@@ -401,13 +412,15 @@  TypeCheckItem::visit (HIR::ImplBlock &impl_block)
   auto binder_pin = context->push_clean_lifetime_resolver (true);
 
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
-    = resolve_impl_block_substitutions (impl_block, failed_flag);
+  auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
     {
       infered = new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
       return;
     }
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
 
   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
 
@@ -427,13 +440,16 @@  TypeCheckItem::resolve_impl_item (HIR::ImplBlock &impl_block,
 				  HIR::ImplItem &item)
 {
   bool failed_flag = false;
-  std::vector<TyTy::SubstitutionParamMapping> substitutions
-    = resolve_impl_block_substitutions (impl_block, failed_flag);
+  auto result = resolve_impl_block_substitutions (impl_block, failed_flag);
   if (failed_flag)
     {
       return new TyTy::ErrorType (impl_block.get_mappings ().get_hirid ());
     }
 
+  std::vector<TyTy::SubstitutionParamMapping> substitutions
+    = std::move (result.first);
+  TyTy::RegionConstraints region_constraints = std::move (result.second);
+
   TyTy::BaseType *self = resolve_impl_block_self (impl_block);
 
   return TypeCheckImplItem::Resolve (&impl_block, &item, self, substitutions);
@@ -445,11 +461,13 @@  TypeCheckItem::visit (HIR::Function &function)
   auto lifetime_pin = context->push_clean_lifetime_resolver ();
   std::vector<TyTy::SubstitutionParamMapping> substitutions;
   if (function.has_generics ())
-    resolve_generic_params (function.get_generic_params (), substitutions);
+    resolve_generic_params (function.get_generic_params (),
+			    substitutions); // TODO resolve constraints
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : function.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   TyTy::BaseType *ret_type = nullptr;
@@ -498,7 +516,8 @@  TypeCheckItem::visit (HIR::Function &function)
     TyTy::FnType::FNTYPE_DEFAULT_FLAGS, ABI::RUST, std::move (params), ret_type,
     std::move (substitutions),
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
 
   context->insert_type (function.get_mappings (), fn_type);
 
@@ -558,7 +577,7 @@  TypeCheckItem::visit (HIR::ExternBlock &extern_block)
     }
 }
 
-std::vector<TyTy::SubstitutionParamMapping>
+std::pair<std::vector<TyTy::SubstitutionParamMapping>, TyTy::RegionConstraints>
 TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
 						 bool &failure_flag)
 {
@@ -566,9 +585,10 @@  TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
   if (impl_block.has_generics ())
     resolve_generic_params (impl_block.get_generic_params (), substitutions);
 
+  TyTy::RegionConstraints region_constraints;
   for (auto &where_clause_item : impl_block.get_where_clause ().get_items ())
     {
-      ResolveWhereClauseItem::Resolve (*where_clause_item);
+      ResolveWhereClauseItem::Resolve (*where_clause_item, region_constraints);
     }
 
   auto specified_bound = TyTy::TypeBoundPredicate::error ();
@@ -600,7 +620,7 @@  TypeCheckItem::resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
   failure_flag = check_for_unconstrained (substitutions, trait_constraints,
 					  impl_constraints, self);
 
-  return substitutions;
+  return {substitutions, region_constraints};
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 73cf9ded1fd..8a90ba051eb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -57,7 +57,8 @@  public:
   void visit (HIR::UseDeclaration &) override {}
 
 protected:
-  std::vector<TyTy::SubstitutionParamMapping>
+  std::pair<std::vector<TyTy::SubstitutionParamMapping>,
+	    TyTy::RegionConstraints>
   resolve_impl_block_substitutions (HIR::ImplBlock &impl_block,
 				    bool &failure_flag);
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index e7a86b9eee1..0d108c3959c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -889,9 +889,10 @@  TypeResolveGenericParam::visit (HIR::TypeParam &param)
 }
 
 void
-ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item)
+ResolveWhereClauseItem::Resolve (HIR::WhereClauseItem &item,
+				 TyTy::RegionConstraints &region_constraints)
 {
-  ResolveWhereClauseItem resolver;
+  ResolveWhereClauseItem resolver (region_constraints);
 
   auto binder_pin = resolver.context->push_lifetime_binder ();
 
@@ -922,6 +923,8 @@  ResolveWhereClauseItem::visit (HIR::LifetimeWhereClauseItem &item)
 	{
 	  rust_error_at (UNKNOWN_LOCATION, "failed to resolve lifetime");
 	}
+      region_constraints.region_region.emplace_back (lhs.value (),
+						     rhs_i.value ());
     }
 }
 
@@ -958,7 +961,7 @@  ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 	  }
 	  break;
 	  case HIR::TypeParamBound::BoundType::LIFETIME: {
-	    if (binding->is<TyTy::ParamType> ())
+	    if (auto param = binding->try_as<TyTy::ParamType> ())
 	      {
 		auto *b = static_cast<HIR::Lifetime *> (bound.get ());
 		auto region = context->lookup_and_resolve_lifetime (*b);
@@ -967,6 +970,8 @@  ResolveWhereClauseItem::visit (HIR::TypeBoundWhereClauseItem &item)
 		    rust_error_at (UNKNOWN_LOCATION,
 				   "failed to resolve lifetime");
 		  }
+		region_constraints.type_region.emplace_back (param,
+							     region.value ());
 	      }
 	  }
 	  break;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 31b486958f4..3083a94f97b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -115,15 +115,21 @@  private:
 
 class ResolveWhereClauseItem : public TypeCheckBase
 {
+  // pair(a, b) => a: b
+  TyTy::RegionConstraints &region_constraints;
+
 public:
-  static void Resolve (HIR::WhereClauseItem &item);
+  static void Resolve (HIR::WhereClauseItem &item,
+		       TyTy::RegionConstraints &region_constraints);
 
 protected:
   void visit (HIR::LifetimeWhereClauseItem &item);
   void visit (HIR::TypeBoundWhereClauseItem &item);
 
 private:
-  ResolveWhereClauseItem () : TypeCheckBase () {}
+  ResolveWhereClauseItem (TyTy::RegionConstraints &region_constraints)
+    : region_constraints (region_constraints)
+  {}
 };
 
 } // namespace Resolver
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index 68d9681485a..2b7868685d4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -189,6 +189,7 @@  TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
   std::vector<TyTy::SubstitutionParamMapping> substitutions
     = inherited_substitutions;
 
+  TyTy::RegionConstraints region_constraints;
   HIR::TraitFunctionDecl &function = fn.get_decl ();
   if (function.has_generics ())
     {
@@ -224,6 +225,13 @@  TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 	}
     }
 
+  if (function.has_where_clause ())
+    {
+      for (auto &where_clause_item : function.get_where_clause ().get_items ())
+	ResolveWhereClauseItem::Resolve (*where_clause_item,
+					 region_constraints);
+    }
+
   TyTy::BaseType *ret_type = nullptr;
   if (!function.has_return_type ())
     ret_type = TyTy::TupleType::get_unit_type (fn.get_mappings ().get_hirid ());
@@ -336,7 +344,8 @@  TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const
 			  : TyTy::FnType::FNTYPE_DEFAULT_FLAGS,
     ABI::RUST, std::move (params), ret_type, substitutions,
     TyTy::SubstitutionArgumentMappings::empty (
-      context->get_lifetime_resolver ().get_num_bound_regions ()));
+      context->get_lifetime_resolver ().get_num_bound_regions ()),
+    region_constraints);
   context->insert_type (fn.get_mappings (), resolved);
   return resolved;
 }
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc b/gcc/rust/typecheck/rust-tyty-bounds.cc
index 066fe4781ed..f37cf50d53c 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -306,7 +306,7 @@  namespace TyTy {
 TypeBoundPredicate::TypeBoundPredicate (
   const Resolver::TraitReference &trait_reference, BoundPolarity polarity,
   location_t locus)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
     error_flag (false), polarity (polarity)
 {
@@ -324,7 +324,7 @@  TypeBoundPredicate::TypeBoundPredicate (
 TypeBoundPredicate::TypeBoundPredicate (
   DefId reference, std::vector<SubstitutionParamMapping> subst,
   BoundPolarity polarity, location_t locus)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (reference), locus (locus), error_flag (false),
     polarity (polarity)
 {
@@ -340,13 +340,13 @@  TypeBoundPredicate::TypeBoundPredicate (
 }
 
 TypeBoundPredicate::TypeBoundPredicate (mark_is_error)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (UNKNOWN_DEFID), locus (UNDEF_LOCATION), error_flag (true),
     polarity (BoundPolarity::RegularBound)
 {}
 
 TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
-  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty ()),
+  : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     reference (other.reference), locus (other.locus),
     error_flag (other.error_flag), polarity (other.polarity)
 {
diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc
index fcb09d507a8..0a8340e317d 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.cc
+++ b/gcc/rust/typecheck/rust-tyty-subst.cc
@@ -440,8 +440,9 @@  SubstitutionArgumentMappings::trait_item_mode () const
 
 SubstitutionRef::SubstitutionRef (
   std::vector<SubstitutionParamMapping> substitutions,
-  SubstitutionArgumentMappings arguments)
-  : substitutions (substitutions), used_arguments (arguments)
+  SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
+  : substitutions (substitutions), used_arguments (arguments),
+    region_constraints (region_constraints)
 {}
 
 bool
@@ -588,6 +589,12 @@  SubstitutionRef::get_used_arguments () const
   return used_arguments;
 }
 
+const RegionConstraints &
+SubstitutionRef::get_region_constraints () const
+{
+  return region_constraints;
+}
+
 SubstitutionArgumentMappings
 SubstitutionRef::get_mappings_from_generic_args (
   HIR::GenericArgs &args, const std::vector<Region> &regions)
diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h
index dbabff3d449..562267cd059 100644
--- a/gcc/rust/typecheck/rust-tyty-subst.h
+++ b/gcc/rust/typecheck/rust-tyty-subst.h
@@ -30,8 +30,17 @@ 
 namespace Rust {
 namespace TyTy {
 
-class BaseType;
 class ParamType;
+
+struct RegionConstraints
+{
+  /** 'a: 'b */
+  std::vector<std::pair<Region, Region>> region_region;
+  /** T: 'a */
+  std::vector<std::pair<ParamType *, Region>> type_region;
+};
+
+class BaseType;
 class SubstitutionArgumentMappings;
 class SubstitutionParamMapping
 {
@@ -249,7 +258,8 @@  class SubstitutionRef
 {
 public:
   SubstitutionRef (std::vector<SubstitutionParamMapping> substitutions,
-		   SubstitutionArgumentMappings arguments);
+		   SubstitutionArgumentMappings arguments,
+		   RegionConstraints region_constraints);
 
   bool has_substitutions () const;
 
@@ -404,9 +414,12 @@  public:
 
   WARN_UNUSED_RESULT tl::optional<SubstitutionArg> get_arg_at (size_t i) const;
 
+  const RegionConstraints &get_region_constraints () const;
+
 protected:
   std::vector<SubstitutionParamMapping> substitutions;
   SubstitutionArgumentMappings used_arguments;
+  RegionConstraints region_constraints;
 };
 
 } // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index 890d079d67f..a8d358161fc 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -596,6 +596,7 @@  BaseType::monomorphized_clone () const
 			 fn->get_identifier (), fn->ident, fn->get_flags (),
 			 fn->get_abi (), std::move (cloned_params), retty,
 			 fn->clone_substs (), fn->get_substitution_arguments (),
+			 fn->get_region_constraints (),
 			 fn->get_combined_refs ());
     }
   else if (auto fn = x->try_as<const FnPtr> ())
@@ -620,6 +621,7 @@  BaseType::monomorphized_clone () const
 			  adt->get_adt_kind (), cloned_variants,
 			  adt->clone_substs (), adt->get_repr_options (),
 			  adt->get_used_arguments (),
+			  adt->get_region_constraints (),
 			  adt->get_combined_refs ());
     }
   else
@@ -1639,7 +1641,7 @@  ADTType::clone () const
   return new ADTType (get_ref (), get_ty_ref (), identifier, ident,
 		      get_adt_kind (), cloned_variants, clone_substs (),
 		      get_repr_options (), used_arguments,
-		      get_combined_refs ());
+		      get_region_constraints (), get_combined_refs ());
 }
 
 static bool
@@ -1958,7 +1960,8 @@  FnType::clone () const
   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
 		     ident, flags, abi, std::move (cloned_params),
 		     get_return_type ()->clone (), clone_substs (),
-		     get_substitution_arguments (), get_combined_refs ());
+		     get_substitution_arguments (), get_region_constraints (),
+		     get_combined_refs ());
 }
 
 FnType *
@@ -3573,11 +3576,13 @@  PlaceholderType::is_equal (const BaseType &other) const
 ProjectionType::ProjectionType (
   HirId ref, BaseType *base, const Resolver::TraitReference *trait, DefId item,
   std::vector<SubstitutionParamMapping> subst_refs,
-  SubstitutionArgumentMappings generic_arguments, std::set<HirId> refs)
+  SubstitutionArgumentMappings generic_arguments,
+  RegionConstraints region_constraints, std::set<HirId> refs)
   : BaseType (ref, ref, KIND,
 	      {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
-	      refs),
-    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+	      std::move (refs)),
+    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		     std::move (region_constraints)),
     base (base), trait (trait), item (item)
 {}
 
@@ -3585,11 +3590,13 @@  ProjectionType::ProjectionType (
   HirId ref, HirId ty_ref, BaseType *base,
   const Resolver::TraitReference *trait, DefId item,
   std::vector<SubstitutionParamMapping> subst_refs,
-  SubstitutionArgumentMappings generic_arguments, std::set<HirId> refs)
+  SubstitutionArgumentMappings generic_arguments,
+  RegionConstraints region_constraints, std::set<HirId> refs)
   : BaseType (ref, ty_ref, KIND,
 	      {Resolver::CanonicalPath::create_empty (), BUILTINS_LOCATION},
 	      refs),
-    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+    SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		     std::move (region_constraints)),
     base (base), trait (trait), item (item)
 {}
 
@@ -3640,7 +3647,7 @@  ProjectionType::clone () const
 {
   return new ProjectionType (get_ref (), get_ty_ref (), base->clone (), trait,
 			     item, clone_substs (), used_arguments,
-			     get_combined_refs ());
+			     region_constraints, get_combined_refs ());
 }
 
 ProjectionType *
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index 7384c402f4e..570a57bff01 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -650,9 +650,11 @@  public:
 	   std::vector<SubstitutionParamMapping> subst_refs,
 	   SubstitutionArgumentMappings generic_arguments
 	   = SubstitutionArgumentMappings::error (),
+	   RegionConstraints region_constraints = {},
 	   std::set<HirId> refs = std::set<HirId> ())
     : BaseType (ref, ref, TypeKind::ADT, ident, refs),
-      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		       region_constraints),
       identifier (identifier), variants (variants), adt_kind (adt_kind)
   {}
 
@@ -661,9 +663,11 @@  public:
 	   std::vector<SubstitutionParamMapping> subst_refs,
 	   SubstitutionArgumentMappings generic_arguments
 	   = SubstitutionArgumentMappings::error (),
+	   RegionConstraints region_constraints = {},
 	   std::set<HirId> refs = std::set<HirId> ())
     : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
-      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		       region_constraints),
       identifier (identifier), variants (variants), adt_kind (adt_kind)
   {}
 
@@ -672,9 +676,11 @@  public:
 	   std::vector<SubstitutionParamMapping> subst_refs, ReprOptions repr,
 	   SubstitutionArgumentMappings generic_arguments
 	   = SubstitutionArgumentMappings::error (),
+	   RegionConstraints region_constraints = {},
 	   std::set<HirId> refs = std::set<HirId> ())
     : BaseType (ref, ty_ref, TypeKind::ADT, ident, refs),
-      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments)),
+      SubstitutionRef (std::move (subst_refs), std::move (generic_arguments),
+		       region_constraints),
       identifier (identifier), variants (variants), adt_kind (adt_kind),
       repr (repr)
   {}
@@ -774,9 +780,11 @@  public:
 	  std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
 	  BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
 	  SubstitutionArgumentMappings substitution_argument_mappings,
+	  RegionConstraints region_constraints,
 	  std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ref, TypeKind::FNDEF, ident, refs),
-      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
+      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
+		       region_constraints),
       params (std::move (params)), type (type), flags (flags),
       identifier (identifier), id (id), abi (abi)
   {
@@ -789,9 +797,11 @@  public:
 	  std::vector<std::pair<HIR::Pattern *, BaseType *>> params,
 	  BaseType *type, std::vector<SubstitutionParamMapping> subst_refs,
 	  SubstitutionArgumentMappings substitution_argument_mappings,
+	  RegionConstraints region_constraints,
 	  std::set<HirId> refs = std::set<HirId> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::FNDEF, ident, refs),
-      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings),
+      SubstitutionRef (std::move (subst_refs), substitution_argument_mappings,
+		       region_constraints),
       params (params), type (type), flags (flags), identifier (identifier),
       id (id), abi (abi)
   {
@@ -962,7 +972,8 @@  public:
 	       = std::vector<TypeBoundPredicate> ())
     : CallableTypeInterface (ref, ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()),
+		       SubstitutionArgumentMappings::error (),
+		       {}), // TODO: check region constraints
       parameters (parameters), result_type (std::move (result_type)), id (id),
       captures (captures)
   {
@@ -980,7 +991,7 @@  public:
 	       = std::vector<TypeBoundPredicate> ())
     : CallableTypeInterface (ref, ty_ref, TypeKind::CLOSURE, ident, refs),
       SubstitutionRef (std::move (subst_refs),
-		       SubstitutionArgumentMappings::error ()), // TODO
+		       SubstitutionArgumentMappings::error (), {}), // TODO
       parameters (parameters), result_type (std::move (result_type)), id (id),
       captures (captures)
   {
@@ -1534,6 +1545,7 @@  public:
 		  std::vector<SubstitutionParamMapping> subst_refs,
 		  SubstitutionArgumentMappings generic_arguments
 		  = SubstitutionArgumentMappings::error (),
+		  RegionConstraints region_constraints = {},
 		  std::set<HirId> refs = std::set<HirId> ());
 
   ProjectionType (HirId ref, HirId ty_ref, BaseType *base,
@@ -1541,6 +1553,7 @@  public:
 		  std::vector<SubstitutionParamMapping> subst_refs,
 		  SubstitutionArgumentMappings generic_arguments
 		  = SubstitutionArgumentMappings::error (),
+		  RegionConstraints region_constraints = {},
 		  std::set<HirId> refs = std::set<HirId> ());
 
   void accept_vis (TyVisitor &vis) override;