aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-04-27 22:04:48 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-04-28 12:47:44 +0100
commitff1676e277af52b6aa19e45494d91a810a1c2070 (patch)
tree297e91f9813c753bca6e1b3776b717f36babf872
parent62bcc93ece6cda0dec8803f66b5a45005089e8ab (diff)
downloadgcc-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.h17
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc42
-rw-r--r--gcc/rust/typecheck/rust-tyty.h22
-rw-r--r--gcc/testsuite/rust.test/compile/generics21.rs13
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 &param : 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 &param;
@@ -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);
+}