aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-01-13 21:14:28 +0000
committerPhilip Herron <herron.philip@googlemail.com>2021-01-16 14:07:50 +0000
commitd96e1594dd378078987900819afc611bd0db19b0 (patch)
tree7105c8abfaaabe2dbd997aee37e13fe0bed860c4 /gcc
parent05b9f235566d7d361709c5bc44e7c36598515946 (diff)
downloadgcc-d96e1594dd378078987900819afc611bd0db19b0.zip
gcc-d96e1594dd378078987900819afc611bd0db19b0.tar.gz
gcc-d96e1594dd378078987900819afc611bd0db19b0.tar.bz2
This brings in resolution and type checking of the unit-type.
It is possible to assign and declare variables of unit-type which translate down to zero sized void_type_node. More work is needed to handle array and ADT types using unit-type when emiting gimple. The name+type resolution should be generic enough.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-expr.h2
-rw-r--r--gcc/rust/backend/rust-compile-context.h7
-rw-r--r--gcc/rust/backend/rust-compile-expr.h15
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h15
-rw-r--r--gcc/rust/backend/rust-compile-tyty.h7
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.h22
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h28
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h11
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc12
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h8
-rw-r--r--gcc/rust/rust-backend.h2
-rw-r--r--gcc/rust/rust-gcc.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.h16
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.h1
-rw-r--r--gcc/rust/typecheck/rust-tyctx.cc15
-rw-r--r--gcc/rust/typecheck/rust-tyty-resolver.h10
-rw-r--r--gcc/rust/typecheck/rust-tyty-rules.h5
-rw-r--r--gcc/testsuite/rust.test/compilable/unit_type1.rs6
21 files changed, 198 insertions, 22 deletions
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 2dbaec8..8a1fd6e 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -1345,6 +1345,8 @@ public:
return tuple_elems;
}
+ bool is_unit () const { return tuple_elems.size () == 0; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index 298ff50..5a0805b 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -223,8 +223,6 @@ public:
void visit (TyTy::ErrorType &type) override { gcc_unreachable (); }
- void visit (TyTy::UnitType &type) override { gcc_unreachable (); }
-
void visit (TyTy::InferType &type) override { gcc_unreachable (); }
void visit (TyTy::FnType &type) override { gcc_unreachable (); }
@@ -233,6 +231,11 @@ public:
void visit (TyTy::ParamType &type) override { gcc_unreachable (); }
+ void visit (TyTy::UnitType &type) override
+ {
+ translated = ctx->get_backend ()->void_type ();
+ }
+
void visit (TyTy::ADTType &type) override
{
::Btype *compiled_type = nullptr;
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 0370129..d38ef04 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -38,7 +38,16 @@ public:
return compiler.translated;
}
- virtual ~CompileExpr () {}
+ void visit (HIR::TupleExpr &expr)
+ {
+ if (expr.is_unit ())
+ {
+ translated = ctx->get_backend ()->unit_expression ();
+ return;
+ }
+
+ gcc_unreachable ();
+ }
void visit (HIR::ReturnExpr &expr)
{
@@ -85,10 +94,6 @@ public:
return;
}
- printf ("have ast node id %u ref %u for expr [%s]\n",
- expr.get_mappings ().get_nodeid (), ref_node_id,
- expr.as_string ().c_str ());
-
// these ref_node_ids will resolve to a pattern declaration but we are
// interested in the definition that this refers to get the parent id
Resolver::Definition def;
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 5f7decb..c52f605 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -71,6 +71,18 @@ public:
if (!stmt.has_init_expr ())
return;
+ TyTy::TyBase *ty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (stmt.get_mappings ().get_hirid (),
+ &ty))
+ {
+ rust_fatal_error (stmt.get_locus (), "failed to lookup var decl type");
+ return;
+ }
+
+ // there is an ICE in GCC for void_node
+ if (ty->get_kind () == TyTy::TypeKind::UNIT)
+ return;
+
Bvariable *var = nullptr;
if (!ctx->lookup_var_decl (stmt.get_mappings ().get_hirid (), &var))
{
@@ -79,7 +91,8 @@ public:
return;
}
- auto *init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
+ Bexpression *init = CompileExpr::Compile (stmt.get_init_expr (), ctx);
+
auto fnctx = ctx->peek_fn ();
auto s = ctx->get_backend ()->init_statement (fnctx.fndecl, var, init);
ctx->add_statement (s);
diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h
index 137b74b..cd220e0 100644
--- a/gcc/rust/backend/rust-compile-tyty.h
+++ b/gcc/rust/backend/rust-compile-tyty.h
@@ -45,8 +45,6 @@ public:
void visit (TyTy::ErrorType &type) override { gcc_unreachable (); }
- void visit (TyTy::UnitType &type) override { gcc_unreachable (); }
-
void visit (TyTy::InferType &type) override { gcc_unreachable (); }
void visit (TyTy::StructFieldType &type) override { gcc_unreachable (); }
@@ -57,6 +55,11 @@ public:
void visit (TyTy::ArrayType &type) override { gcc_unreachable (); }
+ void visit (TyTy::UnitType &type) override
+ {
+ translated = backend->void_type ();
+ }
+
void visit (TyTy::FnType &type) override
{
Backend::Btyped_identifier receiver;
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 51bf108..701efd5 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -132,7 +132,27 @@ public:
return resolver.translated;
}
- virtual ~ASTLoweringExpr () {}
+ void visit (AST::TupleExpr &expr)
+ {
+ std::vector<HIR::Attribute> inner_attribs;
+ std::vector<HIR::Attribute> outer_attribs;
+ std::vector<std::unique_ptr<HIR::Expr> > tuple_elements;
+ for (auto &e : expr.get_tuple_elems ())
+ {
+ HIR::Expr *t = ASTLoweringExpr::translate (e.get ());
+ tuple_elements.push_back (std::unique_ptr<HIR::Expr> (t));
+ }
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ translated
+ = new HIR::TupleExpr (std::move (mapping), std::move (tuple_elements),
+ std::move (inner_attribs),
+ std::move (outer_attribs), expr.get_locus ());
+ }
void visit (AST::IfExpr &expr)
{
diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h
index 2e14ad2..fdf8f46 100644
--- a/gcc/rust/hir/rust-ast-lower-type.h
+++ b/gcc/rust/hir/rust-ast-lower-type.h
@@ -33,12 +33,34 @@ public:
{
ASTLoweringType resolver;
type->accept_vis (resolver);
+
+ resolver.mappings->insert_location (
+ resolver.translated->get_mappings ().get_crate_num (),
+ resolver.translated->get_mappings ().get_hirid (),
+ type->get_locus_slow ());
+
return resolver.translated;
}
- virtual ~ASTLoweringType () {}
+ void visit (AST::TupleType &tuple)
+ {
+ std::vector<std::unique_ptr<HIR::Type> > elems;
+ for (auto &e : tuple.get_elems ())
+ {
+ HIR::Type *t = ASTLoweringType::translate (e.get ());
+ elems.push_back (std::unique_ptr<HIR::Type> (t));
+ }
+
+ auto crate_num = mappings->get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (),
+ mappings->get_next_hir_id (crate_num),
+ mappings->get_next_localdef_id (crate_num));
+
+ translated = new HIR::TupleType (std::move (mapping), std::move (elems),
+ tuple.get_locus ());
+ }
- virtual void visit (AST::TypePathSegment &segment)
+ void visit (AST::TypePathSegment &segment)
{
HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
translated_segment
@@ -47,7 +69,7 @@ public:
segment.get_locus ());
}
- virtual void visit (AST::TypePath &path)
+ void visit (AST::TypePath &path)
{
std::vector<std::unique_ptr<HIR::TypePathSegment> > translated_segments;
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 11be8b6..5d63507 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -1233,6 +1233,17 @@ public:
void accept_vis (HIRVisitor &vis) override;
+ const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const
+ {
+ return tuple_elems;
+ }
+ std::vector<std::unique_ptr<Expr> > &get_tuple_elems ()
+ {
+ return tuple_elems;
+ }
+
+ bool is_unit () const { return tuple_elems.size () == 0; }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h
index 324d820..abab268 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.h
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.h
@@ -35,7 +35,13 @@ public:
expr->accept_vis (resolver);
};
- ~ResolveExpr () {}
+ void visit (AST::TupleExpr &expr)
+ {
+ if (expr.is_unit ())
+ return;
+
+ gcc_unreachable ();
+ }
void visit (AST::PathInExpression &expr)
{
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 8ec3a9c..ae352b9 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -40,7 +40,17 @@ public:
}
};
- ~ResolveType () {}
+ void visit (AST::TupleType &tuple)
+ {
+ if (tuple.is_unit_type ())
+ {
+ resolved_node = resolver->get_unit_type_node_id ();
+ return;
+ }
+
+ // TODO see github #78
+ gcc_unreachable ();
+ }
void visit (AST::TypePath &path)
{
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index d6eed93..e0b4f3a 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -113,7 +113,7 @@ Resolver::insert_builtin_types (Rib *r)
Linemap::predeclared_location ());
}
-std::vector<AST::TypePath *> &
+std::vector<AST::Type *> &
Resolver::get_builtin_types ()
{
return builtins;
@@ -160,6 +160,16 @@ Resolver::generate_builtins ()
MKBUILTIN_TYPE ("bool", builtins, rbool);
MKBUILTIN_TYPE ("f32", builtins, f32);
MKBUILTIN_TYPE ("f64", builtins, f64);
+
+ // unit type ()
+ TyTy::UnitType *unit_tyty = new TyTy::UnitType (mappings->get_next_hir_id ());
+ std::vector<std::unique_ptr<AST::Type> > elems;
+ AST::TupleType *unit_type
+ = new AST::TupleType (std::move (elems), Linemap::predeclared_location ());
+ builtins.push_back (unit_type);
+ tyctx->insert_builtin (unit_tyty->get_ref (), unit_type->get_node_id (),
+ unit_tyty);
+ set_unit_type_node_id (unit_type->get_node_id ());
}
void
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 515ebfd..4d98e7f 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -209,7 +209,7 @@ public:
// these will be required for type resolution passes to
// map back to tyty nodes
- std::vector<AST::TypePath *> &get_builtin_types ();
+ std::vector<AST::Type *> &get_builtin_types ();
void push_new_name_rib (Rib *r);
void push_new_type_rib (Rib *r);
@@ -232,6 +232,9 @@ public:
NodeId get_global_type_node_id () { return global_type_node_id; }
+ void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; }
+ NodeId get_unit_type_node_id () { return unit_ty_node_id; }
+
private:
Resolver ();
@@ -240,12 +243,13 @@ private:
Analysis::Mappings *mappings;
TypeCheckContext *tyctx;
- std::vector<AST::TypePath *> builtins;
+ std::vector<AST::Type *> builtins;
Scope name_scope;
Scope type_scope;
NodeId global_type_node_id;
+ NodeId unit_ty_node_id;
// map a AST Node to a Rib
std::map<NodeId, Rib *> name_ribs;
diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h
index 210eff3..02c12ee 100644
--- a/gcc/rust/rust-backend.h
+++ b/gcc/rust/rust-backend.h
@@ -254,6 +254,8 @@ public:
// Create a nil pointer expression.
virtual Bexpression *nil_pointer_expression () = 0;
+ virtual Bexpression *unit_expression () = 0;
+
// Create a reference to a variable.
virtual Bexpression *var_expression (Bvariable *var, Location) = 0;
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index bfa7609..748aa5a 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -225,6 +225,8 @@ public:
return this->make_expression (null_pointer_node);
}
+ Bexpression *unit_expression () { return this->make_expression (void_node); }
+
Bexpression *var_expression (Bvariable *var, Location);
Bexpression *indirect_expression (Btype *, Bexpression *expr,
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index f2014a1..d7729cc 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -43,6 +43,22 @@ public:
return resolver.infered;
}
+ void visit (HIR::TupleExpr &expr)
+ {
+ if (expr.is_unit ())
+ {
+ auto unit_node_id = resolver->get_unit_type_node_id ();
+ if (!context->lookup_builtin (unit_node_id, &infered))
+ {
+ rust_error_at (expr.get_locus (),
+ "failed to lookup builtin unit type");
+ }
+ return;
+ }
+
+ gcc_unreachable ();
+ }
+
void visit (HIR::ReturnExpr &expr)
{
auto ret = context->peek_return_type ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h
index 8ff4c44..fdb4176 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.h
@@ -76,6 +76,22 @@ public:
return resolver.translated;
}
+ void visit (HIR::TupleType &tuple)
+ {
+ if (tuple.is_unit_type ())
+ {
+ auto unit_node_id = resolver->get_unit_type_node_id ();
+ if (!context->lookup_builtin (unit_node_id, &translated))
+ {
+ rust_error_at (tuple.get_locus (),
+ "failed to lookup builtin unit type");
+ }
+ return;
+ }
+
+ gcc_unreachable ();
+ }
+
void visit (HIR::TypePath &path)
{
// check if this is already defined or not
diff --git a/gcc/rust/typecheck/rust-hir-type-check.h b/gcc/rust/typecheck/rust-hir-type-check.h
index 6deecdd..3572f22 100644
--- a/gcc/rust/typecheck/rust-hir-type-check.h
+++ b/gcc/rust/typecheck/rust-hir-type-check.h
@@ -33,6 +33,7 @@ public:
~TypeCheckContext ();
+ bool lookup_builtin (NodeId id, TyTy::TyBase **type);
bool lookup_builtin (std::string name, TyTy::TyBase **type);
void insert_builtin (HirId id, NodeId ref, TyTy::TyBase *type);
diff --git a/gcc/rust/typecheck/rust-tyctx.cc b/gcc/rust/typecheck/rust-tyctx.cc
index cd171d1..15b4c26 100644
--- a/gcc/rust/typecheck/rust-tyctx.cc
+++ b/gcc/rust/typecheck/rust-tyctx.cc
@@ -36,6 +36,21 @@ TypeCheckContext::TypeCheckContext () {}
TypeCheckContext::~TypeCheckContext () {}
bool
+TypeCheckContext::lookup_builtin (NodeId id, TyTy::TyBase **type)
+{
+ auto ref_it = node_id_refs.find (id);
+ if (ref_it == node_id_refs.end ())
+ return false;
+
+ auto it = resolved.find (ref_it->second);
+ if (it == resolved.end ())
+ return false;
+
+ *type = it->second;
+ return true;
+}
+
+bool
TypeCheckContext::lookup_builtin (std::string name, TyTy::TyBase **type)
{
for (auto &builtin : builtins)
diff --git a/gcc/rust/typecheck/rust-tyty-resolver.h b/gcc/rust/typecheck/rust-tyty-resolver.h
index 22c3c91..3c31076 100644
--- a/gcc/rust/typecheck/rust-tyty-resolver.h
+++ b/gcc/rust/typecheck/rust-tyty-resolver.h
@@ -108,13 +108,19 @@ public:
{
auto combined = resolved_tyty->combine (it);
if (combined == nullptr)
- break;
+ {
+ rust_fatal_error (decl->get_locus_slow (),
+ "type-check resolver failed");
+ break;
+ }
resolved_tyty = combined;
}
// something is not inferred we need to look at all references now
- if (resolved_tyty == nullptr || resolved_tyty->is_unit ())
+ if (resolved_tyty == nullptr
+ || resolved_tyty->get_kind () == TyTy::TypeKind::INFER
+ || resolved_tyty->get_kind () == TyTy::TypeKind::ERROR)
{
rust_fatal_error (decl->get_locus_slow (), "failed to resolve type");
return false;
diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h
index 677013f..ce23fa2 100644
--- a/gcc/rust/typecheck/rust-tyty-rules.h
+++ b/gcc/rust/typecheck/rust-tyty-rules.h
@@ -215,7 +215,10 @@ public:
return resolved;
}
- void visit (IntType &type) override { rust_assert (false); }
+ void visit (UnitType &type) override
+ {
+ resolved = new UnitType (type.get_ref ());
+ }
private:
UnitType *base;
diff --git a/gcc/testsuite/rust.test/compilable/unit_type1.rs b/gcc/testsuite/rust.test/compilable/unit_type1.rs
new file mode 100644
index 0000000..ea1ebb3
--- /dev/null
+++ b/gcc/testsuite/rust.test/compilable/unit_type1.rs
@@ -0,0 +1,6 @@
+fn main() {
+ let a: () = ();
+
+ let b;
+ b = ();
+}