From: Philip Herron Date: Tue, 20 Jun 2023 11:21:02 +0000 (+0100) Subject: gccrs: add new method to infer impl block type X-Git-Tag: basepoints/gcc-15~2458 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4476c9a8e386575c272c96a7e9383b011f273d77;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc index 6d6ab63e85f2..8a06e6dbd189 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 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 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 432b29271a5b..fc49dc69b05c 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 4bac75a63d97..7de6f6627b09 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),