Skip to content

Commit

Permalink
Add code generation for the slice type
Browse files Browse the repository at this point in the history
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
  • Loading branch information
philberty committed Mar 11, 2022
1 parent e076823 commit 040b2ec
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
34 changes: 32 additions & 2 deletions gcc/rust/backend/rust-compile-type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions gcc/testsuite/rust/execute/torture/slice1.rs
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 040b2ec

Please sign in to comment.