From e547f7da588f596bf26923b12ba873878e05d51c Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 28 Apr 2021 12:46:21 +0100 Subject: Tuples can contain TypeParameters TypeParameters can be behind held within Tuples which need substitution but these types cannot hold substitution mappings. Fixes #396 --- gcc/rust/typecheck/rust-substitution-mapper.h | 5 ++++- gcc/rust/typecheck/rust-tyty.cc | 23 +++++++++++++++++++++++ gcc/rust/typecheck/rust-tyty.h | 12 ++++++++++++ gcc/testsuite/rust.test/compile/generics22.rs | 13 +++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/rust.test/compile/generics22.rs (limited to 'gcc') diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index 23105d6..739f1b5 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -154,7 +154,10 @@ public: } // these don't support generic arguments but might contain a type param - void visit (TyTy::TupleType &) override { gcc_unreachable (); } + void visit (TyTy::TupleType &type) override + { + resolved = type.handle_substitions (mappings); + } void visit (TyTy::ReferenceType &type) override { diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index cc6c2f8..b75c139 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -540,6 +540,29 @@ TupleType::clone () get_combined_refs ()); } +TupleType * +TupleType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + auto mappings_table = Analysis::Mappings::get (); + + TupleType *tuple = static_cast (clone ()); + tuple->set_ty_ref (mappings_table->get_next_hir_id ()); + + for (size_t i = 0; i < tuple->fields.size (); i++) + { + TyVar &field = fields.at (i); + if (field.get_tyty ()->contains_type_parameters ()) + { + BaseType *concrete + = Resolver::SubstMapperInternal::Resolve (field.get_tyty (), + mappings); + tuple->fields[i] = TyVar (concrete->get_ty_ref ()); + } + } + + return tuple; +} + void FnType::accept_vis (TyVisitor &vis) { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 0c8168d..bcc694b 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -379,6 +379,18 @@ public: std::string get_name () const override final { return as_string (); } + bool contains_type_parameters () const override final + { + for (auto &f : fields) + { + if (f.get_tyty ()->contains_type_parameters ()) + return true; + } + return false; + } + + TupleType *handle_substitions (SubstitutionArgumentMappings mappings); + private: std::vector fields; }; diff --git a/gcc/testsuite/rust.test/compile/generics22.rs b/gcc/testsuite/rust.test/compile/generics22.rs new file mode 100644 index 0000000..465ebb0 --- /dev/null +++ b/gcc/testsuite/rust.test/compile/generics22.rs @@ -0,0 +1,13 @@ +fn callee(t: (T, bool)) -> i32 { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + 32 +} + +fn caller(t: i32) -> i32 { + callee((t, false)) +} + +fn main() { + let a; + a = caller(123); +} -- cgit v1.1