diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-13 21:14:28 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-16 14:07:50 +0000 |
commit | d96e1594dd378078987900819afc611bd0db19b0 (patch) | |
tree | 7105c8abfaaabe2dbd997aee37e13fe0bed860c4 /gcc | |
parent | 05b9f235566d7d361709c5bc44e7c36598515946 (diff) | |
download | gcc-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')
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 = (); +} |