diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-06-20 12:21:02 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-06-21 09:00:30 +0000 |
commit | 7bb7c2a44e6e2b3ea6f95891ee60e2b91cc8cd59 (patch) | |
tree | 278c945180efbda52d36383f55b2579077e07da5 | |
parent | 3a27f1e9058c67a153f5911af052ccbf253e7e58 (diff) | |
download | gcc-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.cc | 45 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 7 |
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), |