From f2c5642d134df70755e0aede94074767cd3958eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Br=C3=BCschweiler?= Date: Wed, 19 Jun 2013 19:54:54 +0200 Subject: [PATCH] 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. --- src/librustc/front/intrinsic.rs | 16 ++++++++++++---- src/librustc/middle/trans/foreign.rs | 9 ++++++--- src/librustc/middle/trans/glue.rs | 5 ++--- src/librustc/middle/trans/type_.rs | 11 ++++++++--- src/librustc/middle/typeck/check/mod.rs | 10 ++++++++-- src/libstd/unstable/intrinsics.rs | 3 +++ 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs index fcb08180a5e..f19e3706253 100644 --- a/src/librustc/front/intrinsic.rs +++ b/src/librustc/front/intrinsic.rs @@ -20,14 +20,22 @@ pub mod intrinsic { // version in sys is no longer present. pub fn get_tydesc() -> *TyDesc { unsafe { - rusti::get_tydesc::() as *TyDesc + rusti::get_tydesc::() } } + pub type GlueFn = extern "Rust" fn(**TyDesc, *i8); + + // NB: this has to be kept in sync with the Rust ABI. pub struct TyDesc { size: uint, - align: uint - // Remaining fields not listed + align: uint, + take_glue: GlueFn, + drop_glue: GlueFn, + free_glue: GlueFn, + visit_glue: GlueFn, + shape: *i8, + shape_tables: *i8 } pub enum Opaque { } @@ -133,7 +141,7 @@ pub mod intrinsic { #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { - pub fn get_tydesc() -> *(); + pub fn get_tydesc() -> *TyDesc; pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor); } } diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 10e63e6af77..855610510bd 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -681,9 +681,12 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let static_ti = get_tydesc(ccx, tp_ty); glue::lazily_emit_all_tydesc_glue(ccx, static_ti); - // FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the - // core::sys copy of the get_tydesc interface dies off. - let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to()); + // FIXME (#3730): ideally this shouldn't need a cast, + // but there's a circularity between translating rust types to llvm + // types and having a tydesc type available. So I can't directly access + // the llvm type of intrinsic::TyDesc struct. + let userland_tydesc_ty = type_of::type_of(ccx, output_type); + let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty); Store(bcx, td, fcx.llretptr.get()); } "init" => { diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index e9febb51005..0930d355035 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -789,7 +789,6 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { }; } -fn type_of_glue_fn(ccx: &CrateContext) -> Type { - let tydescpp = ccx.tydesc_type.ptr_to().ptr_to(); - Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void()) +pub fn type_of_glue_fn(ccx: &CrateContext) -> Type { + Type::glue_fn(ccx.tydesc_type) } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 34a15033109..764bdb026f4 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -189,18 +189,23 @@ impl Type { None => () } + // Bit of a kludge: pick the fn typeref out of the tydesc.. let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); cx.tn.associate_type("glue_fn", &ty); return ty; } + pub fn glue_fn(tydesc: Type) -> Type { + let tydescpp = tydesc.ptr_to().ptr_to(); + Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], + &Type::void()) + } + pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); - let tydescpp = tydesc.ptr_to().ptr_to(); let pvoid = Type::i8p(); - let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ], - &Type::void()).ptr_to(); + let glue_fn_ty = Type::glue_fn(tydesc).ptr_to(); let int_ty = Type::int(arch); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index fa7959c7872..4c074ce197e 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3506,8 +3506,14 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } "get_tydesc" => { - // FIXME (#3730): return *intrinsic::tydesc, not *() - (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + let tydesc_name = special_idents::tydesc; + assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); + let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { + ty: tydesc_ty, + mutbl: ast::m_imm + }); + (1u, ~[], td_ptr) } "visit_tydesc" => { let tydesc_name = special_idents::tydesc; diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index c38b013a75a..08fc90fa908 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -209,6 +209,9 @@ pub extern "rust-intrinsic" { pub fn pref_align_of() -> uint; /// Get a static pointer to a type descriptor. + #[cfg(not(stage0))] + pub fn get_tydesc() -> *::intrinsic::TyDesc; + #[cfg(stage0)] pub fn get_tydesc() -> *(); /// Create a value initialized to zero.