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
This commit is contained in:
parent
e076823eda
commit
040b2ec9a6
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue