Skip to content

Commit fa0a153

Browse files
committed
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
1 parent 6e64e66 commit fa0a153

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

gcc/rust/backend/rust-compile-type.cc

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,38 @@ TyTyResolveCompile::visit (const TyTy::ArrayType &type)
349349
void
350350
TyTyResolveCompile::visit (const TyTy::SliceType &type)
351351
{
352-
// TODO
353-
gcc_unreachable ();
352+
if (ctx->lookup_compiled_types (type.get_ty_ref (), &translated, &type))
353+
return;
354+
355+
std::vector<Backend::typed_identifier> fields;
356+
357+
tree element_type
358+
= TyTyResolveCompile::compile (ctx, type.get_element_type ());
359+
tree data_field_ty = build_pointer_type (element_type);
360+
Backend::typed_identifier data_field ("data", data_field_ty, Location ());
361+
fields.push_back (std::move (data_field));
362+
363+
// lookup usize
364+
TyTy::BaseType *usize = nullptr;
365+
bool ok = ctx->get_tyctx ()->lookup_builtin ("usize", &usize);
366+
rust_assert (ok);
367+
368+
tree len_field_ty = TyTyResolveCompile::compile (ctx, usize);
369+
Backend::typed_identifier len_field ("len", len_field_ty, Location ());
370+
fields.push_back (std::move (len_field));
371+
372+
tree type_record = ctx->get_backend ()->struct_type (fields);
373+
374+
std::string named_struct_str
375+
= std::string ("[") + type.get_element_type ()->get_name () + "]";
376+
tree named_struct
377+
= ctx->get_backend ()->named_type (named_struct_str, type_record,
378+
type.get_ident ().locus);
379+
380+
ctx->push_type (named_struct);
381+
translated = named_struct;
382+
383+
ctx->insert_compiled_type (type.get_ty_ref (), named_struct, &type);
354384
}
355385

356386
void
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// { dg-additional-options "-w" }
2+
struct FatPtr<T> {
3+
data: *const T,
4+
len: usize,
5+
}
6+
7+
union Repr<T> {
8+
rust: *const [T],
9+
rust_mut: *mut [T],
10+
raw: FatPtr<T>,
11+
}
12+
13+
const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
14+
unsafe {
15+
let a = FatPtr { data, len };
16+
let b = Repr { raw: a };
17+
b.rust
18+
}
19+
}
20+
21+
fn main() -> i32 {
22+
let a = 123;
23+
let b: *const i32 = &a;
24+
let c = slice_from_raw_parts(b, 1);
25+
26+
0
27+
}

0 commit comments

Comments
 (0)