diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-03-11 11:22:07 +0000 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-03-11 13:54:21 +0000 |
commit | 040b2ec9a6b20aa2441951e47f344d303dd61d7e (patch) | |
tree | 031aecbdcf83d4a96ffe751238266a192de83b66 | |
parent | e076823eda8f11425a705a191d686e9e48be2fc4 (diff) | |
download | gcc-040b2ec9a6b20aa2441951e47f344d303dd61d7e.zip gcc-040b2ec9a6b20aa2441951e47f344d303dd61d7e.tar.gz gcc-040b2ec9a6b20aa2441951e47f344d303dd61d7e.tar.bz2 |
Add code generation for the slice type
This type must respect the layout of the FatPtr type in libcore. Rust
implements slices using Rustc types in libcore and uses a neat trick.
The slice is generated into the FatPtr which contains the pointer and
length of the slice. This is then placed into a union called Repr which
has 3 variants a mutable and immutable pointer to the FatPtr and a final
variant which is the raw FatPtr. This means we can use unsafe access to
the union to gain a pointer to the FatPtr.
Addresses #849
-rw-r--r-- | gcc/rust/backend/rust-compile-type.cc | 34 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/slice1.rs | 27 |
2 files changed, 59 insertions, 2 deletions
diff --git a/gcc/rust/backend/rust-compile-type.cc b/gcc/rust/backend/rust-compile-type.cc index ba6a206..07b95c7 100644 --- a/gcc/rust/backend/rust-compile-type.cc +++ b/gcc/rust/backend/rust-compile-type.cc @@ -349,8 +349,38 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type) void TyTyResolveCompile::visit (const TyTy::SliceType &type) { - // TODO - gcc_unreachable (); + if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type)) + return; + + std::vector<Backend::typed_identifier> fields; + + tree element_type + = TyTyResolveCompile::compile (ctx, type.get_element_type ()); + tree data_field_ty = build_pointer_type (element_type); + Backend::typed_identifier data_field ("data", data_field_ty, Location ()); + fields.push_back (std::move (data_field)); + + // lookup usize + TyTy::BaseType *usize = nullptr; + bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize); + rust_assert (ok); + + tree len_field_ty = TyTyResolveCompile::compile (ctx, usize); + Backend::typed_identifier len_field ("len", len_field_ty, Location ()); + fields.push_back (std::move (len_field)); + + tree type_record = ctx->get_backend ()->struct_type (fields); + + std::string named_struct_str + = std::string ("[") + type.get_element_type ()->get_name () + "]"; + tree named_struct + = ctx->get_backend ()->named_type (named_struct_str, type_record, + type.get_ident ().locus); + + ctx->push_type (named_struct); + translated = named_struct; + + ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type); } void diff --git a/gcc/testsuite/rust/execute/torture/slice1.rs b/gcc/testsuite/rust/execute/torture/slice1.rs new file mode 100644 index 0000000..a0488b3 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/slice1.rs @@ -0,0 +1,27 @@ +// { dg-additional-options "-w" } +struct FatPtr<T> { + data: *const T, + len: usize, +} + +union Repr<T> { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr<T>, +} + +const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] { + unsafe { + let a = FatPtr { data, len }; + let b = Repr { raw: a }; + b.rust + } +} + +fn main() -> i32 { + let a = 123; + let b: *const i32 = &a; + let c = slice_from_raw_parts(b, 1); + + 0 +} |