diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-28 12:22:11 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-28 12:22:11 +0000 |
commit | f189f5bbab73b5d04faee4f4d2198f023c9e1522 (patch) | |
tree | e8e59b34c0c4bba0c932b172b6adc76d557f3b6b /gcc | |
parent | 62bcc93ece6cda0dec8803f66b5a45005089e8ab (diff) | |
parent | e547f7da588f596bf26923b12ba873878e05d51c (diff) | |
download | gcc-f189f5bbab73b5d04faee4f4d2198f023c9e1522.zip gcc-f189f5bbab73b5d04faee4f4d2198f023c9e1522.tar.gz gcc-f189f5bbab73b5d04faee4f4d2198f023c9e1522.tar.bz2 |
Merge #398
398: ReferenceTypes and Tuple can hold Type Parameters r=philberty a=philberty
We need to perform internal substitutions on Reference and Tuple Types in order to type check them.
These types cannot hold substitution parameters so they need to be performed with the internal substitution mapper.
Fixes #396
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-substitution-mapper.h | 20 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 65 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 34 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compile/generics21.rs | 13 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compile/generics22.rs | 13 |
5 files changed, 138 insertions, 7 deletions
diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index d022019..739f1b5 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -153,8 +153,24 @@ public: resolved = concrete; } + // these don't support generic arguments but might contain a type param + void visit (TyTy::TupleType &type) override + { + resolved = type.handle_substitions (mappings); + } + + 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::TupleType &) 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 +181,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..b75c139 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); @@ -539,6 +540,29 @@ TupleType::clone () get_combined_refs ()); } +TupleType * +TupleType::handle_substitions (SubstitutionArgumentMappings mappings) +{ + auto mappings_table = Analysis::Mappings::get (); + + TupleType *tuple = static_cast<TupleType *> (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) { @@ -558,7 +582,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 +691,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 +713,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 +744,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 +1237,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 +1332,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..bcc694b 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; @@ -364,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<TyVar> fields; }; @@ -1212,6 +1239,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); +} 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: (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); +} |