diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-06-20 19:41:42 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-06-21 09:00:30 +0000 |
commit | 065d8c4d79d180f26f51d4e6d88a99a348113906 (patch) | |
tree | d089c4966f48a996cbbcf440add7fc1d2f48adba | |
parent | 8e2619254f7f53d2637148a13e1d5c8e26447c41 (diff) | |
download | gcc-065d8c4d79d180f26f51d4e6d88a99a348113906.zip gcc-065d8c4d79d180f26f51d4e6d88a99a348113906.tar.gz gcc-065d8c4d79d180f26f51d4e6d88a99a348113906.tar.bz2 |
gccrs: Apply generic arguments to the respective trait bounds
When we have an impl block for a generic type such as T which is a generic
type which does not 'bind' generic arguments, which means its not a type
such as an ADT or Fn which holds generic parameter mappings we need to
ensure inference variables are applied to the segment type apropriately so
that inference variables unified correctly and the higher ranked trait
bounds are as well.
Fixes: #1893
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-item.cc (TypeCheckItem::ResolveImplBlockSelfWithInference):
arguments mappings as an out parameter and apply them to the bounds
* typecheck/rust-hir-type-check-item.h: update the prototype
* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments):
apply the arguments to the segment type
gcc/testsuite/ChangeLog:
* rust/compile/issue-1893.rs: fully compile the test case
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.cc | 21 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-item.h | 5 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-1893.rs | 3 |
4 files changed, 27 insertions, 11 deletions
diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.cc b/gcc/rust/typecheck/rust-hir-type-check-item.cc index e4f44d2..a7cb770 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-item.cc @@ -74,8 +74,9 @@ TypeCheckItem::ResolveImplBlockSelf (HIR::ImplBlock &impl_block) } TyTy::BaseType * -TypeCheckItem::ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl, - Location locus) +TypeCheckItem::ResolveImplBlockSelfWithInference ( + HIR::ImplBlock &impl, Location locus, + TyTy::SubstitutionArgumentMappings *infer_arguments) { TypeCheckItem resolver; @@ -112,10 +113,20 @@ TypeCheckItem::ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl, } // create argument mappings - TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), {}, - locus); + *infer_arguments + = TyTy::SubstitutionArgumentMappings (std::move (args), {}, locus); - return SubstMapperInternal::Resolve (self, infer_arguments); + TyTy::BaseType *infer = SubstMapperInternal::Resolve (self, *infer_arguments); + + // we only need to apply to the bounds manually on types which dont bind + // generics + if (!infer->has_subsititions_defined ()) + { + for (auto &bound : infer->get_specified_bounds ()) + bound.handle_substitions (*infer_arguments); + } + + return infer; } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h index 9dbb5b3..0acf95a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.h +++ b/gcc/rust/typecheck/rust-hir-type-check-item.h @@ -35,8 +35,9 @@ public: static TyTy::BaseType *ResolveImplBlockSelf (HIR::ImplBlock &impl_block); - static TyTy::BaseType * - ResolveImplBlockSelfWithInference (HIR::ImplBlock &impl, Location locus); + static TyTy::BaseType *ResolveImplBlockSelfWithInference ( + HIR::ImplBlock &impl, Location locus, + TyTy::SubstitutionArgumentMappings *infer_arguments); void visit (HIR::Module &module) override; void visit (HIR::Function &function) override; diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 834d42f..2251425 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -414,9 +414,16 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id, bool found_impl_trait = context->lookup_associated_trait_impl (impl_block_id, &associated); + + auto mappings = TyTy::SubstitutionArgumentMappings::error (); TyTy::BaseType *impl_block_ty = TypeCheckItem::ResolveImplBlockSelfWithInference ( - *associated_impl_block, seg.get_locus ()); + *associated_impl_block, seg.get_locus (), &mappings); + + // we need to apply the arguments to the segment type so they get + // unified properly + if (!mappings.is_error ()) + tyseg = SubstMapperInternal::Resolve (tyseg, mappings); prev_segment = unify_site (seg.get_mappings ().get_hirid (), TyTy::TyWithLocation (prev_segment), diff --git a/gcc/testsuite/rust/compile/issue-1893.rs b/gcc/testsuite/rust/compile/issue-1893.rs index 8d32e0d..6be1d6d 100644 --- a/gcc/testsuite/rust/compile/issue-1893.rs +++ b/gcc/testsuite/rust/compile/issue-1893.rs @@ -1,4 +1,3 @@ -// { dg-additional-options "-frust-compile-until=nameresolution" } pub enum Option<T> { None, Some(T), @@ -10,10 +9,8 @@ pub enum Result<T, E> { } pub trait TryFrom<T> { - /// The type returned in the event of a conversion error. type Error; - /// Performs the conversion. fn try_from(value: T) -> Result<Self, Self::Error>; } |