From 854aad3b58e747cad3e46b522c9ef765bdfadca4 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Mon, 25 Jan 2021 13:27:50 +0000 Subject: Add usize and isize types Arrays can only be indexed by usize and this enforces that rule. These types are sized based on the pointer size of the host arch. Fixes #87 --- gcc/rust/backend/rust-compile-context.h | 16 +++++ gcc/rust/backend/rust-compile-tyty.h | 14 ++++ gcc/rust/resolve/rust-ast-resolve.cc | 4 ++ gcc/rust/rust-backend.h | 3 + gcc/rust/rust-gcc.cc | 8 +++ gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 +- gcc/rust/typecheck/rust-tyty-call.h | 2 + gcc/rust/typecheck/rust-tyty-rules.h | 92 +++++++++++++++++++++++++++ gcc/rust/typecheck/rust-tyty-visitor.h | 2 + gcc/rust/typecheck/rust-tyty.cc | 50 +++++++++++++++ gcc/rust/typecheck/rust-tyty.h | 42 ++++++++++++ 11 files changed, 234 insertions(+), 1 deletion(-) (limited to 'gcc/rust') diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index ed03f02..034568f 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -374,6 +374,22 @@ public: translated = compiled_type; } + void visit (TyTy::USizeType &type) override + { + ::Btype *compiled_type = nullptr; + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); + rust_assert (ok); + translated = compiled_type; + } + + void visit (TyTy::ISizeType &type) override + { + ::Btype *compiled_type = nullptr; + bool ok = ctx->lookup_compiled_types (type.get_ty_ref (), &compiled_type); + rust_assert (ok); + translated = compiled_type; + } + private: TyTyResolveCompile (Context *ctx) : ctx (ctx) {} diff --git a/gcc/rust/backend/rust-compile-tyty.h b/gcc/rust/backend/rust-compile-tyty.h index b6794bc..2c54b17 100644 --- a/gcc/rust/backend/rust-compile-tyty.h +++ b/gcc/rust/backend/rust-compile-tyty.h @@ -190,6 +190,20 @@ public: gcc_unreachable (); } + void visit (TyTy::USizeType &type) override + { + translated = backend->named_type ( + "usize", backend->integer_type (true, backend->get_pointer_size ()), + Linemap::predeclared_location ()); + } + + void visit (TyTy::ISizeType &type) override + { + translated = backend->named_type ( + "isize", backend->integer_type (false, backend->get_pointer_size ()), + Linemap::predeclared_location ()); + } + private: TyTyCompile (::Backend *backend) : backend (backend), translated (nullptr), diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index ec53ae0..c6d7148 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -146,6 +146,8 @@ Resolver::generate_builtins () = new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F32); auto f64 = new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F64); + auto usize = new TyTy::USizeType (mappings->get_next_hir_id ()); + auto isize = new TyTy::ISizeType (mappings->get_next_hir_id ()); MKBUILTIN_TYPE ("u8", builtins, u8); MKBUILTIN_TYPE ("u16", builtins, u16); @@ -160,6 +162,8 @@ Resolver::generate_builtins () MKBUILTIN_TYPE ("bool", builtins, rbool); MKBUILTIN_TYPE ("f32", builtins, f32); MKBUILTIN_TYPE ("f64", builtins, f64); + MKBUILTIN_TYPE ("usize", builtins, usize); + MKBUILTIN_TYPE ("isize", builtins, isize); // unit type () TyTy::UnitType *unit_tyty = new TyTy::UnitType (mappings->get_next_hir_id ()); diff --git a/gcc/rust/rust-backend.h b/gcc/rust/rust-backend.h index 184f8fa..7b0ccf9 100644 --- a/gcc/rust/rust-backend.h +++ b/gcc/rust/rust-backend.h @@ -98,6 +98,9 @@ public: // Get the unnamed boolean type. virtual Btype *bool_type () = 0; + // Get the Host pointer size in bits + virtual int get_pointer_size () = 0; + // Get an unnamed integer type with the given signedness and number // of bits. virtual Btype *integer_type (bool is_unsigned, int bits) = 0; diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index 6f8dc46..0729b1e 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -165,6 +165,8 @@ public: Btype *bool_type () { return this->make_type (boolean_type_node); } + int get_pointer_size (); + Btype *integer_type (bool, int); Btype *float_type (int); @@ -758,6 +760,12 @@ Gcc_backend::Gcc_backend () // Get an unnamed integer type. +int +Gcc_backend::get_pointer_size () +{ + return POINTER_SIZE; +} + Btype * Gcc_backend::integer_type (bool is_unsigned, int bits) { diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 8f60f72..17f1611 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -631,7 +631,7 @@ public: void visit (HIR::ArrayIndexExpr &expr) { TyTy::TyBase *size_ty; - if (!context->lookup_builtin ("i32", &size_ty)) + if (!context->lookup_builtin ("usize", &size_ty)) { rust_error_at ( expr.get_locus (), diff --git a/gcc/rust/typecheck/rust-tyty-call.h b/gcc/rust/typecheck/rust-tyty-call.h index 84cfdce..2b3cfb6 100644 --- a/gcc/rust/typecheck/rust-tyty-call.h +++ b/gcc/rust/typecheck/rust-tyty-call.h @@ -49,6 +49,8 @@ public: void visit (IntType &type) override { gcc_unreachable (); } void visit (UintType &type) override { gcc_unreachable (); } void visit (FloatType &type) override { gcc_unreachable (); } + void visit (USizeType &type) override { gcc_unreachable (); } + void visit (ISizeType &type) override { gcc_unreachable (); } void visit (ErrorType &type) override { gcc_unreachable (); } // tuple-structs diff --git a/gcc/rust/typecheck/rust-tyty-rules.h b/gcc/rust/typecheck/rust-tyty-rules.h index 890931f..e17cec7 100644 --- a/gcc/rust/typecheck/rust-tyty-rules.h +++ b/gcc/rust/typecheck/rust-tyty-rules.h @@ -134,6 +134,20 @@ public: base->as_string ().c_str (), type.as_string ().c_str ()); } + virtual void visit (USizeType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + } + + virtual void visit (ISizeType &type) override + { + Location ref_locus = mappings->lookup_location (type.get_ref ()); + rust_error_at (ref_locus, "expected [%s] got [%s]", + base->as_string ().c_str (), type.as_string ().c_str ()); + } + virtual void visit (FloatType &type) override { Location ref_locus = mappings->lookup_location (type.get_ref ()); @@ -230,6 +244,36 @@ public: BaseRules::visit (type); } + void visit (USizeType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL) + || (base->get_infer_kind () + == TyTy::InferType::InferTypeKind::INTEGRAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseRules::visit (type); + } + + void visit (ISizeType &type) override + { + bool is_valid + = (base->get_infer_kind () == TyTy::InferType::InferTypeKind::GENERAL) + || (base->get_infer_kind () + == TyTy::InferType::InferTypeKind::INTEGRAL); + if (is_valid) + { + resolved = type.clone (); + return; + } + + BaseRules::visit (type); + } + void visit (FloatType &type) override { bool is_valid @@ -591,6 +635,54 @@ private: TupleType *base; }; +class USizeRules : public BaseRules +{ +public: + USizeRules (USizeType *base) : BaseRules (base), base (base) {} + + void visit (InferType &type) override + { + // cant assign a float inference variable + if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT) + { + BaseRules::visit (type); + return; + } + + resolved = base->clone (); + resolved->set_ref (type.get_ref ()); + } + + void visit (USizeType &type) override { resolved = type.clone (); } + +private: + USizeType *base; +}; + +class ISizeRules : public BaseRules +{ +public: + ISizeRules (ISizeType *base) : BaseRules (base), base (base) {} + + void visit (InferType &type) override + { + // cant assign a float inference variable + if (type.get_infer_kind () == InferType::InferTypeKind::FLOAT) + { + BaseRules::visit (type); + return; + } + + resolved = base->clone (); + resolved->set_ref (type.get_ref ()); + } + + void visit (ISizeType &type) override { resolved = type.clone (); } + +private: + ISizeType *base; +}; + } // namespace TyTy } // namespace Rust diff --git a/gcc/rust/typecheck/rust-tyty-visitor.h b/gcc/rust/typecheck/rust-tyty-visitor.h index 3997295..6ae0e80 100644 --- a/gcc/rust/typecheck/rust-tyty-visitor.h +++ b/gcc/rust/typecheck/rust-tyty-visitor.h @@ -38,6 +38,8 @@ public: virtual void visit (IntType &type) = 0; virtual void visit (UintType &type) = 0; virtual void visit (FloatType &type) = 0; + virtual void visit (USizeType &type) = 0; + virtual void visit (ISizeType &type) = 0; virtual void visit (ErrorType &type) = 0; }; diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 9efde68..249e876 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -432,6 +432,56 @@ FloatType::clone () } void +USizeType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +std::string +USizeType::as_string () const +{ + return "usize"; +} + +TyBase * +USizeType::combine (TyBase *other) +{ + USizeRules r (this); + return r.combine (other); +} + +TyBase * +USizeType::clone () +{ + return new USizeType (get_ref (), get_ty_ref (), get_combined_refs ()); +} + +void +ISizeType::accept_vis (TyVisitor &vis) +{ + vis.visit (*this); +} + +std::string +ISizeType::as_string () const +{ + return "isize"; +} + +TyBase * +ISizeType::combine (TyBase *other) +{ + ISizeRules r (this); + return r.combine (other); +} + +TyBase * +ISizeType::clone () +{ + return new ISizeType (get_ref (), get_ty_ref (), get_combined_refs ()); +} + +void TypeCheckCallExpr::visit (ADTType &type) { if (call.num_params () != type.num_fields ()) diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 6c6f27c..860ef96 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -43,6 +43,8 @@ enum TypeKind FLOAT, UNIT, FIELD, + USIZE, + ISIZE, // there are more to add... ERROR }; @@ -510,6 +512,46 @@ private: FloatKind float_kind; }; +class USizeType : public TyBase +{ +public: + USizeType (HirId ref, std::set refs = std::set ()) + : TyBase (ref, ref, TypeKind::USIZE) + {} + + USizeType (HirId ref, HirId ty_ref, std::set refs = std::set ()) + : TyBase (ref, ty_ref, TypeKind::USIZE) + {} + + void accept_vis (TyVisitor &vis) override; + + std::string as_string () const override; + + TyBase *combine (TyBase *other) override; + + TyBase *clone () final override; +}; + +class ISizeType : public TyBase +{ +public: + ISizeType (HirId ref, std::set refs = std::set ()) + : TyBase (ref, ref, TypeKind::ISIZE) + {} + + ISizeType (HirId ref, HirId ty_ref, std::set refs = std::set ()) + : TyBase (ref, ty_ref, TypeKind::ISIZE) + {} + + void accept_vis (TyVisitor &vis) override; + + std::string as_string () const override; + + TyBase *combine (TyBase *other) override; + + TyBase *clone () final override; +}; + } // namespace TyTy } // namespace Rust -- cgit v1.1