diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-04-27 22:04:48 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2021-04-28 12:47:44 +0100 |
commit | ff1676e277af52b6aa19e45494d91a810a1c2070 (patch) | |
tree | 297e91f9813c753bca6e1b3776b717f36babf872 | |
parent | 62bcc93ece6cda0dec8803f66b5a45005089e8ab (diff) | |
download | gcc-ff1676e277af52b6aa19e45494d91a810a1c2070.zip gcc-ff1676e277af52b6aa19e45494d91a810a1c2070.tar.gz gcc-ff1676e277af52b6aa19e45494d91a810a1c2070.tar.bz2 |
Reference types can contain TypeParameters
TypeParameters can be behind ReferenceTypes which needs substitution but
these types cannot hold substitution mappings.
Fixes #396
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 17 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 42 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 22 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compile/generics21.rs | 13 |
4 files changed, 87 insertions, 7 deletions
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index d022019..23105d6 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -153,8 +153,21 @@ public: resolved = concrete; } - void visit (TyTy::InferType &) override { gcc_unreachable (); } + // these don't support generic arguments but might contain a type param void visit (TyTy::TupleType &) override { gcc_unreachable (); } + + void visit (TyTy::ReferenceType &type) override + { + resolved = type.handle_substitions (mappings); + } + + void visit (TyTy::ParamType &type) override + { + resolved = type.handle_substitions (mappings); + } + + // nothing to do for these + void visit (TyTy::InferType &) override { gcc_unreachable (); } void visit (TyTy::FnPtr &) override { gcc_unreachable (); } void visit (TyTy::ArrayType &) override { gcc_unreachable (); } void visit (TyTy::BoolType &) override { gcc_unreachable (); } @@ -165,8 +178,6 @@ public: void visit (TyTy::ISizeType &) override { gcc_unreachable (); } void visit (TyTy::ErrorType &) override { gcc_unreachable (); } void visit (TyTy::CharType &) override { gcc_unreachable (); } - void visit (TyTy::ReferenceType &) override { gcc_unreachable (); } - void visit (TyTy::ParamType &) override { gcc_unreachable (); } void visit (TyTy::StrType &) override { gcc_unreachable (); } void visit (TyTy::NeverType &) override { gcc_unreachable (); } diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 8cc9089..cc6c2f8 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -452,7 +452,8 @@ ADTType::handle_substitions (SubstitutionArgumentMappings subst_mappings) field->get_field_type ()->set_ty_ref (argt->get_ref ()); } } - else if (fty->has_subsititions_defined ()) + else if (fty->has_subsititions_defined () + || fty->contains_type_parameters ()) { BaseType *concrete = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings); @@ -558,7 +559,7 @@ FnType::as_string () const } std::string ret_str = type->as_string (); - return "fn (" + params_str + ") -> " + ret_str; + return "fn" + subst_as_string () + " (" + params_str + ") -> " + ret_str; } BaseType * @@ -667,7 +668,8 @@ FnType::handle_substitions (SubstitutionArgumentMappings subst_mappings) fty->set_ty_ref (argt->get_ref ()); } } - else if (fty->has_subsititions_defined ()) + else if (fty->needs_generic_substitutions () + || fty->contains_type_parameters ()) { BaseType *concrete = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings); @@ -688,6 +690,7 @@ FnType::handle_substitions (SubstitutionArgumentMappings subst_mappings) for (auto ¶m : fn->get_params ()) { auto fty = param.second; + bool is_param_ty = fty->get_kind () == TypeKind::PARAM; if (is_param_ty) { @@ -718,7 +721,8 @@ FnType::handle_substitions (SubstitutionArgumentMappings subst_mappings) fty->set_ty_ref (argt->get_ref ()); } } - else if (fty->has_subsititions_defined ()) + else if (fty->has_subsititions_defined () + || fty->contains_type_parameters ()) { BaseType *concrete = Resolver::SubstMapperInternal::Resolve (fty, subst_mappings); @@ -1210,6 +1214,22 @@ ReferenceType::clone () get_combined_refs ()); } +ReferenceType * +ReferenceType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + auto mappings_table = Analysis::Mappings::get (); + + ReferenceType *ref = static_cast<ReferenceType *> (clone ()); + ref->set_ty_ref (mappings_table->get_next_hir_id ()); + + // might be &T or &ADT so this needs to be recursive + auto base = ref->get_base (); + BaseType *concrete = Resolver::SubstMapperInternal::Resolve (base, mappings); + ref->base = TyVar (concrete->get_ty_ref ()); + + return ref; +} + void ParamType::accept_vis (TyVisitor &vis) { @@ -1289,6 +1309,20 @@ ParamType::is_equal (const BaseType &other) const return resolve ()->is_equal (other); } +ParamType * +ParamType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + ParamType *p = static_cast<ParamType *> (clone ()); + + SubstitutionArg arg = SubstitutionArg::error (); + bool ok = mappings.get_argument_for_symbol (this, &arg); + rust_assert (ok); + + p->set_ty_ref (arg.get_tyty ()->get_ref ()); + + return p; +} + BaseType * StrType::clone () { diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index f3ff609..0c8168d 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -122,6 +122,8 @@ public: virtual bool needs_generic_substitutions () const { return false; } + virtual bool contains_type_parameters () const { return false; } + std::string mappings_str () const { std::string buffer = "Ref: " + std::to_string (get_ref ()) @@ -242,6 +244,7 @@ public: std::string get_name () const override final { return as_string (); } }; +class SubstitutionArgumentMappings; class ParamType : public BaseType { public: @@ -278,6 +281,18 @@ public: bool is_equal (const BaseType &other) const override; + bool contains_type_parameters () const override final + { + if (can_resolve ()) + { + auto r = resolve (); + return r->contains_type_parameters (); + } + return true; + } + + ParamType *handle_substitions (SubstitutionArgumentMappings mappings); + private: std::string symbol; HIR::GenericParam ¶m; @@ -1212,6 +1227,13 @@ public: BaseType *clone () final override; + bool contains_type_parameters () const override final + { + return get_base ()->contains_type_parameters (); + } + + ReferenceType *handle_substitions (SubstitutionArgumentMappings mappings); + private: TyVar base; }; diff --git a/gcc/testsuite/rust.test/compile/generics21.rs b/gcc/testsuite/rust.test/compile/generics21.rs new file mode 100644 index 0000000..dc4e935 --- /dev/null +++ b/gcc/testsuite/rust.test/compile/generics21.rs @@ -0,0 +1,13 @@ +fn callee<T>(t: &T) -> i32 { + // { dg-warning "unused name" "" { target *-*-* } .-1 } + 32 +} + +fn caller(t: i32) -> i32 { + callee(&t) +} + +fn main() { + let a; + a = caller(123); +} |