Skip to content

Commit f2c5642

Browse files
committed
Fix get_tydesc() return type
This fixes part of #3730, but not all. Also changes the TyDesc struct to be equivalent with the generated code, with the hope that the above issue may one day be closed for good, i.e. that the TyDesc type can completely be specified in the Rust sources and not be generated.
1 parent 3b126e4 commit f2c5642

File tree

6 files changed

+39
-15
lines changed

6 files changed

+39
-15
lines changed

src/librustc/front/intrinsic.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,22 @@ pub mod intrinsic {
2020
// version in sys is no longer present.
2121
pub fn get_tydesc<T>() -> *TyDesc {
2222
unsafe {
23-
rusti::get_tydesc::<T>() as *TyDesc
23+
rusti::get_tydesc::<T>()
2424
}
2525
}
2626

27+
pub type GlueFn = extern "Rust" fn(**TyDesc, *i8);
28+
29+
// NB: this has to be kept in sync with the Rust ABI.
2730
pub struct TyDesc {
2831
size: uint,
29-
align: uint
30-
// Remaining fields not listed
32+
align: uint,
33+
take_glue: GlueFn,
34+
drop_glue: GlueFn,
35+
free_glue: GlueFn,
36+
visit_glue: GlueFn,
37+
shape: *i8,
38+
shape_tables: *i8
3139
}
3240

3341
pub enum Opaque { }
@@ -133,7 +141,7 @@ pub mod intrinsic {
133141

134142
#[abi = "rust-intrinsic"]
135143
pub extern "rust-intrinsic" {
136-
pub fn get_tydesc<T>() -> *();
144+
pub fn get_tydesc<T>() -> *TyDesc;
137145
pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
138146
}
139147
}

src/librustc/middle/trans/foreign.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
681681
let static_ti = get_tydesc(ccx, tp_ty);
682682
glue::lazily_emit_all_tydesc_glue(ccx, static_ti);
683683

684-
// FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the
685-
// core::sys copy of the get_tydesc interface dies off.
686-
let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to());
684+
// FIXME (#3730): ideally this shouldn't need a cast,
685+
// but there's a circularity between translating rust types to llvm
686+
// types and having a tydesc type available. So I can't directly access
687+
// the llvm type of intrinsic::TyDesc struct.
688+
let userland_tydesc_ty = type_of::type_of(ccx, output_type);
689+
let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty);
687690
Store(bcx, td, fcx.llretptr.get());
688691
}
689692
"init" => {

src/librustc/middle/trans/glue.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,6 @@ pub fn emit_tydescs(ccx: &mut CrateContext) {
789789
};
790790
}
791791

792-
fn type_of_glue_fn(ccx: &CrateContext) -> Type {
793-
let tydescpp = ccx.tydesc_type.ptr_to().ptr_to();
794-
Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void())
792+
pub fn type_of_glue_fn(ccx: &CrateContext) -> Type {
793+
Type::glue_fn(ccx.tydesc_type)
795794
}

src/librustc/middle/trans/type_.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,23 @@ impl Type {
189189
None => ()
190190
}
191191

192+
// Bit of a kludge: pick the fn typeref out of the tydesc..
192193
let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue);
193194
cx.tn.associate_type("glue_fn", &ty);
194195

195196
return ty;
196197
}
197198

199+
pub fn glue_fn(tydesc: Type) -> Type {
200+
let tydescpp = tydesc.ptr_to().ptr_to();
201+
Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ],
202+
&Type::void())
203+
}
204+
198205
pub fn tydesc(arch: Architecture) -> Type {
199206
let mut tydesc = Type::named_struct("tydesc");
200-
let tydescpp = tydesc.ptr_to().ptr_to();
201207
let pvoid = Type::i8p();
202-
let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ],
203-
&Type::void()).ptr_to();
208+
let glue_fn_ty = Type::glue_fn(tydesc).ptr_to();
204209

205210
let int_ty = Type::int(arch);
206211

src/librustc/middle/typeck/check/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3506,8 +3506,14 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
35063506
}
35073507

35083508
"get_tydesc" => {
3509-
// FIXME (#3730): return *intrinsic::tydesc, not *()
3510-
(1u, ~[], ty::mk_nil_ptr(ccx.tcx))
3509+
let tydesc_name = special_idents::tydesc;
3510+
assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
3511+
let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name);
3512+
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
3513+
ty: tydesc_ty,
3514+
mutbl: ast::m_imm
3515+
});
3516+
(1u, ~[], td_ptr)
35113517
}
35123518
"visit_tydesc" => {
35133519
let tydesc_name = special_idents::tydesc;

src/libstd/unstable/intrinsics.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ pub extern "rust-intrinsic" {
209209
pub fn pref_align_of<T>() -> uint;
210210

211211
/// Get a static pointer to a type descriptor.
212+
#[cfg(not(stage0))]
213+
pub fn get_tydesc<T>() -> *::intrinsic::TyDesc;
214+
#[cfg(stage0)]
212215
pub fn get_tydesc<T>() -> *();
213216

214217
/// Create a value initialized to zero.

0 commit comments

Comments
 (0)