diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-01-25 13:27:50 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-01-26 11:59:39 +0000 |
commit | 854aad3b58e747cad3e46b522c9ef765bdfadca4 (patch) | |
tree | e7c0943131d46cb1b9f2faaa4edfd6a5ede3c172 | |
parent | 0817c29a423aca1c4c3f9ba812f67df35f36fc65 (diff) | |
download | gcc-854aad3b58e747cad3e46b522c9ef765bdfadca4.zip gcc-854aad3b58e747cad3e46b522c9ef765bdfadca4.tar.gz gcc-854aad3b58e747cad3e46b522c9ef765bdfadca4.tar.bz2 |
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
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 16 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-tyty.h | 14 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 4 | ||||
-rw-r--r-- | gcc/rust/rust-backend.h | 3 | ||||
-rw-r--r-- | gcc/rust/rust-gcc.cc | 8 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-call.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-rules.h | 92 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty-visitor.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 50 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 42 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/usize1.rs | 5 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/fail_compilation/usize1.rs | 5 |
13 files changed, 244 insertions, 1 deletions
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<HirId> refs = std::set<HirId> ()) + : TyBase (ref, ref, TypeKind::USIZE) + {} + + USizeType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ()) + : 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<HirId> refs = std::set<HirId> ()) + : TyBase (ref, ref, TypeKind::ISIZE) + {} + + ISizeType (HirId ref, HirId ty_ref, std::set<HirId> refs = std::set<HirId> ()) + : 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 diff --git a/gcc/testsuite/rust.test/compilable/usize1.rs b/gcc/testsuite/rust.test/compilable/usize1.rs new file mode 100644 index 0000000..0df0a85 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/usize1.rs @@ -0,0 +1,5 @@ +fn main() { + let a = [1, 2, 3]; + let b: usize = 1; + let c = a[b]; +} diff --git a/gcc/testsuite/rust.test/fail_compilation/usize1.rs b/gcc/testsuite/rust.test/fail_compilation/usize1.rs new file mode 100644 index 0000000..92393e7 --- /dev/null +++ b/gcc/testsuite/rust.test/fail_compilation/usize1.rs @@ -0,0 +1,5 @@ +fn main() { + let a = [1, 2, 3]; + let b: u32 = 1; + let c = a[b]; +} |