aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-06-20 12:21:02 +0100
committerPhilip Herron <philip.herron@embecosm.com>2023-06-21 09:00:30 +0000
commit7bb7c2a44e6e2b3ea6f95891ee60e2b91cc8cd59 (patch)
tree278c945180efbda52d36383f55b2579077e07da5
parent3a27f1e9058c67a153f5911af052ccbf253e7e58 (diff)
downloadgcc-7bb7c2a44e6e2b3ea6f95891ee60e2b91cc8cd59.zip
gcc-7bb7c2a44e6e2b3ea6f95891ee60e2b91cc8cd59.tar.gz
gcc-7bb7c2a44e6e2b3ea6f95891ee60e2b91cc8cd59.tar.bz2
gccrs: add new method to infer impl block type
When we resolve a path segment the associated impl Self may not be a type which 'binds' generic types. Which would be any type which does not inherit SubstitionRef base class. There is a case where an impl block for generic type T has bound generics on the trait bound of the trait impl block this allows us to infer the T for this case. Addresses #1893 gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-item.cc (TypeCheckItem::ResolveImplBlockSelfWithInference): New helper utility to infer non concrete types and handle the case where its not a binding generic type (which inherits SubstitutionRef) * typecheck/rust-hir-type-check-item.h: new helper prototype * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): use this helper Signed-off-by: Philip Herron <herron.philip@googlemail.com>
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.cc45
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-item.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc7
3 files changed, 50 insertions, 5 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc
index 4b9f9bc..e4f44d2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc
@@ -73,6 +73,51 @@ TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block)
return resolver.resolve_impl_block_self (impl_block);
}
+TyTy::BaseType *
+TypeCheckItem::ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl,
+ Location locus)
+{
+ TypeCheckItem resolver;
+
+ bool failed_flag = false;
+ std::vector<TyTy::SubstitutionParamMapping> substitutions
+ = resolver.resolve_impl_block_substitutions (impl, failed_flag);
+ if (failed_flag)
+ {
+ return new TyTy::ErrorType (impl.get_mappings ().get_hirid ());
+ }
+
+ // now that we have the param mappings we need to query the self type
+ TyTy::BaseType *self = resolver.resolve_impl_block_self (impl);
+
+ // nothing to do
+ if (substitutions.empty () || self->is_concrete ())
+ return self;
+
+ // generate inference variables for the subst-param-mappings
+ std::vector<TyTy::SubstitutionArg> args;
+ for (auto &p : substitutions)
+ {
+ if (p.needs_substitution ())
+ {
+ TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
+ args.push_back (TyTy::SubstitutionArg (&p, infer_var.get_tyty ()));
+ }
+ else
+ {
+ TyTy::ParamType *param = p.get_param_ty ();
+ TyTy::BaseType *resolved = param->destructure ();
+ args.push_back (TyTy::SubstitutionArg (&p, resolved));
+ }
+ }
+
+ // create argument mappings
+ TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), {},
+ locus);
+
+ return SubstMapperInternal::Resolve (self, infer_arguments);
+}
+
void
TypeCheckItem::visit (HIR::TypeAlias &alias)
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h
index 68eac7c..9dbb5b3 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-item.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-item.h
@@ -35,6 +35,9 @@ public:
static TyTy::BaseType *ResolveImplBlockSelf (HIR::ImplBlock &impl_block);
+ static TyTy::BaseType *
+ ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl, Location locus);
+
void visit (HIR::Module &module) override;
void visit (HIR::Function &function) override;
void visit (HIR::TypeAlias &alias) override;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index dcdf17d..d685d73 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -415,11 +415,8 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
= context->lookup_associated_trait_impl (impl_block_id,
&associated);
TyTy::BaseType *impl_block_ty
- = TypeCheckItem::ResolveImplBlockSelf (*associated_impl_block);
-
- if (impl_block_ty->needs_generic_substitutions ())
- impl_block_ty
- = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+ = TypeCheckItem::ResolveImplBlockSelfWithInference (
+ *associated_impl_block, seg.get_locus ());
prev_segment = unify_site (seg.get_mappings ().get_hirid (),
TyTy::TyWithLocation (prev_segment),