aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-03-30 17:53:09 +0100
committerPhilip Herron <herron.philip@googlemail.com>2021-03-31 09:45:07 +0100
commitd7593fec92166db4d454fdf241b1fde6922d72f2 (patch)
tree4a381b854a9db351e093e1c5b52a8af49ea02f72
parent67ed1e36ceae2edd11db4a7f333fe7530f3eed4c (diff)
downloadgcc-d7593fec92166db4d454fdf241b1fde6922d72f2.zip
gcc-d7593fec92166db4d454fdf241b1fde6922d72f2.tar.gz
gcc-d7593fec92166db4d454fdf241b1fde6922d72f2.tar.bz2
Add support for TypeAlias
This allows for a typedef style alias of any type in rust code, as the types are abstracted behind the TyTy interface this falls out quite nicely. In order to support TypeAliases we needed to be able to supported already substituted types in #311. More testing is needed here the GenericParameters on TypeAlias are not being used in the type resolution pass here. Fixes #312 Addresses #311
-rw-r--r--gcc/rust/ast/rust-item.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.h33
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h25
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h16
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h10
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h4
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.h3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-toplevel.h8
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc30
-rw-r--r--gcc/testsuite/rust.test/compile/generics11.rs8
-rw-r--r--gcc/testsuite/rust.test/compile/type-alias1.rs6
-rw-r--r--gcc/testsuite/rust.test/compile/type-alias2.rs6
-rw-r--r--gcc/testsuite/rust.test/xfail_compile/type-alias1.rs6
13 files changed, 139 insertions, 18 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 773bcaf..8ffe150 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -1720,6 +1720,8 @@ public:
return existing_type;
}
+ Identifier get_new_type_name () const { return new_type_name; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h
index 7f6594d..edbc498 100644
--- a/gcc/rust/hir/rust-ast-lower-item.h
+++ b/gcc/rust/hir/rust-ast-lower-item.h
@@ -53,6 +53,39 @@ public:
return resolver.translated;
}
+ void visit (AST::TypeAlias &alias) override
+ {
+ std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
+ HIR::WhereClause where_clause (std::move (where_clause_items));
+ HIR::Visibility vis = HIR::Visibility::create_public ();
+ std::vector<HIR::Attribute> outer_attrs;
+
+ std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
+ if (alias.has_generics ())
+ generic_params = lower_generic_params (alias.get_generic_params ());
+
+ HIR::Type *existing_type
+ = ASTLoweringType::translate (alias.get_type_aliased ().get ());
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, alias.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ translated = new HIR::TypeAlias (mapping, alias.get_new_type_name (),
+ std::move (generic_params),
+ std::move (where_clause),
+ std::unique_ptr<HIR::Type> (existing_type),
+ std::move (vis), std::move (outer_attrs),
+ alias.get_locus ());
+
+ mappings->insert_defid_mapping (mapping.get_defid (), translated);
+ mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (),
+ translated);
+ mappings->insert_location (crate_num, mapping.get_hirid (),
+ alias.get_locus ());
+ }
+
void visit (AST::TupleStruct &struct_decl) override
{
std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h
index c9723f8..a117333 100644
--- a/gcc/rust/hir/tree/rust-hir-item.h
+++ b/gcc/rust/hir/tree/rust-hir-item.h
@@ -1504,6 +1504,31 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ std::vector<std::unique_ptr<GenericParam> > &get_generic_params ()
+ {
+ return generic_params;
+ }
+ const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const
+ {
+ return generic_params;
+ }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ WhereClause &get_where_clause ()
+ {
+ rust_assert (has_where_clause ());
+ return where_clause;
+ }
+
+ // TODO: is this better? Or is a "vis_block" better?
+ std::unique_ptr<Type> &get_type_aliased ()
+ {
+ rust_assert (existing_type != nullptr);
+ return existing_type;
+ }
+
+ Identifier get_new_type_name () const { return new_type_name; }
+
protected:
/* Use covariance to implement clone function as returning this object
* rather than base */
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h
index 1074031..45d94db 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -39,6 +39,22 @@ public:
item->accept_vis (resolver);
};
+ void visit (AST::TypeAlias &alias) override
+ {
+ NodeId scope_node_id = alias.get_node_id ();
+ resolver->get_type_scope ().push (scope_node_id);
+
+ if (alias.has_generics ())
+ {
+ for (auto &generic : alias.get_generic_params ())
+ ResolveGenericParam::go (generic.get (), alias.get_node_id ());
+ }
+
+ ResolveType::go (alias.get_type_aliased ().get (), alias.get_node_id ());
+
+ resolver->get_type_scope ().pop ();
+ }
+
void visit (AST::TupleStruct &struct_decl) override
{
NodeId scope_node_id = struct_decl.get_node_id ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 8baab13..afc0068 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -38,6 +38,16 @@ public:
item->accept_vis (resolver);
};
+ void visit (AST::TypeAlias &alias) override
+ {
+ resolver->get_type_scope ().insert (
+ alias.get_new_type_name (), alias.get_node_id (), alias.get_locus (),
+ false, [&] (std::string, NodeId, Location locus) -> void {
+ rust_error_at (alias.get_locus (), "redefined multiple times");
+ rust_error_at (locus, "was defined here");
+ });
+ }
+
void visit (AST::TupleStruct &struct_decl) override
{
resolver->get_type_scope ().insert (
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 836328f..dc4aaa7 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -115,10 +115,6 @@ public:
}
infered = field_tyty->get_field_type ();
- printf ("ZXZX resolved: %s to: \n", expr.as_string ().c_str ());
- adt->debug ();
- infered->debug ();
- printf ("ZXZX done\n");
}
void visit (HIR::TupleExpr &expr) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.h b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
index dd62622..7e9e862 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-implitem.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.h
@@ -242,15 +242,12 @@ public:
auto expected_ret_tyty = resolve_fn_type->get_return_type ();
context->push_return_type (expected_ret_tyty);
- printf ("XXXX method body boyo: 1!!\n");
-
auto block_expr_ty
= TypeCheckExpr::Resolve (method.get_definition ().get (), false);
context->pop_return_type ();
expected_ret_tyty->unify (block_expr_ty);
- printf ("XXXX method body boyo: 2!!\n");
}
private:
diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
index 702c6c7..0131555 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h
@@ -40,6 +40,14 @@ public:
item->accept_vis (resolver);
}
+ void visit (HIR::TypeAlias &alias) override
+ {
+ TyTy::BaseType *actual_type
+ = TypeCheckType::Resolve (alias.get_type_aliased ().get ());
+
+ context->insert_type (alias.get_mappings (), actual_type);
+ }
+
void visit (HIR::TupleStruct &struct_decl) override
{
std::vector<TyTy::SubstitutionParamMapping> substitutions;
diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc
index b105269..8b2f657 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check.cc
@@ -305,19 +305,27 @@ TypeCheckStructExpr::visit (HIR::PathInExpression &expr)
if (struct_path_resolved->has_substitutions ())
{
HIR::PathExprSegment seg = expr.get_final_segment ();
-
- TyTy::BaseType *subst
- = SubstMapper::Resolve (struct_path_resolved, expr.get_locus (),
- seg.has_generic_args ()
- ? &seg.get_generic_args ()
- : nullptr);
- if (subst == nullptr || subst->get_kind () != TyTy::TypeKind::ADT)
+ if (!struct_path_resolved->needs_substitution ()
+ && seg.has_generic_args ())
{
- rust_fatal_error (mappings->lookup_location (ref),
- "expected a substituted ADT type");
- return;
+ rust_error_at (seg.get_generic_args ().get_locus (),
+ "unexpected type arguments");
+ }
+ else if (struct_path_resolved->needs_substitution ())
+ {
+ TyTy::BaseType *subst
+ = SubstMapper::Resolve (struct_path_resolved, expr.get_locus (),
+ seg.has_generic_args ()
+ ? &seg.get_generic_args ()
+ : nullptr);
+ if (subst == nullptr || subst->get_kind () != TyTy::TypeKind::ADT)
+ {
+ rust_fatal_error (mappings->lookup_location (ref),
+ "expected a substituted ADT type");
+ return;
+ }
+ struct_path_resolved = static_cast<TyTy::ADTType *> (subst);
}
- struct_path_resolved = static_cast<TyTy::ADTType *> (subst);
}
}
diff --git a/gcc/testsuite/rust.test/compile/generics11.rs b/gcc/testsuite/rust.test/compile/generics11.rs
new file mode 100644
index 0000000..3c8f5ba
--- /dev/null
+++ b/gcc/testsuite/rust.test/compile/generics11.rs
@@ -0,0 +1,8 @@
+struct Foo<T>(T, u32);
+
+type TypeAlias = Foo<i32>;
+
+fn main() {
+ let a: Foo<i32>;
+ a = TypeAlias { 0: 123, 1: 456 };
+}
diff --git a/gcc/testsuite/rust.test/compile/type-alias1.rs b/gcc/testsuite/rust.test/compile/type-alias1.rs
new file mode 100644
index 0000000..78bf046
--- /dev/null
+++ b/gcc/testsuite/rust.test/compile/type-alias1.rs
@@ -0,0 +1,6 @@
+type TypeAlias = (i32, u32);
+
+fn main() {
+ let a: TypeAlias;
+ a = (123, 456);
+}
diff --git a/gcc/testsuite/rust.test/compile/type-alias2.rs b/gcc/testsuite/rust.test/compile/type-alias2.rs
new file mode 100644
index 0000000..b1ac205
--- /dev/null
+++ b/gcc/testsuite/rust.test/compile/type-alias2.rs
@@ -0,0 +1,6 @@
+type x = u32;
+
+fn main() {
+ let x: x = 1;
+ let y: x = 2;
+}
diff --git a/gcc/testsuite/rust.test/xfail_compile/type-alias1.rs b/gcc/testsuite/rust.test/xfail_compile/type-alias1.rs
new file mode 100644
index 0000000..c7d7048
--- /dev/null
+++ b/gcc/testsuite/rust.test/xfail_compile/type-alias1.rs
@@ -0,0 +1,6 @@
+type TypeAlias = (i32, u32);
+
+fn main() {
+ let a: TypeAlias;
+ a = (123, 456f32); // { dg-error "expected .u32. got .f32." }
+}