diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index f92acbaf5c68c..7cf8f56dfd719 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -290,7 +290,7 @@ pub fn malloc_raw_dyn(bcx: block, // Get the tydesc for the body: let static_ti = get_tydesc(ccx, t); - glue::lazily_emit_all_tydesc_glue(ccx, static_ti); + glue::lazily_emit_most_tydesc_glue(ccx, static_ti); // Allocate space: let tydesc = PointerCast(bcx, static_ti.tydesc, T_ptr(T_i8())); @@ -2329,9 +2329,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext, llvm::LLVMPositionBuilderAtEnd(bld, llbb); let start_def_id = ccx.tcx.lang_items.start_fn(); - if start_def_id.crate == ast::local_crate { - ccx.sess.bug("start lang item is never in the local crate") - } else { + if start_def_id.crate != ast::local_crate { let start_fn_type = csearch::get_type(ccx.tcx, start_def_id).ty; trans_external_path(ccx, start_def_id, start_fn_type); @@ -2348,8 +2346,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext, let (start_fn, args) = if use_start_lang_item { let start_def_id = ccx.tcx.lang_items.start_fn(); let start_fn = if start_def_id.crate == ast::local_crate { - ccx.sess.bug("start lang item is never in the local \ - crate") + get_item_val(ccx, start_def_id.node) } else { let start_fn_type = csearch::get_type(ccx.tcx, start_def_id).ty; diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 58c77f037ded3..662d9843f2718 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -724,6 +724,16 @@ pub fn trans_intrinsic(ccx: @CrateContext, fcx.llretptr.get()); } ~"get_tydesc" => { + let tp_ty = substs.tys[0]; + let static_ti = get_tydesc(ccx, tp_ty); + glue::lazily_emit_most_tydesc_glue(ccx, static_ti); + + // FIXME (#3727): change this to T_ptr(ccx.tydesc_ty) when the + // core::sys copy of the get_tydesc interface dies off. + let td = PointerCast(bcx, static_ti.tydesc, T_ptr(T_nil())); + Store(bcx, td, fcx.llretptr.get()); + } + ~"get_tydesc_for_visiting" => { let tp_ty = substs.tys[0]; let static_ti = get_tydesc(ccx, tp_ty); glue::lazily_emit_all_tydesc_glue(ccx, static_ti); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 2f48eda7edd26..12feb8e43098b 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -153,6 +153,15 @@ pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { } } +/// Emits all tydesc glue except for visitor glue. +pub fn lazily_emit_most_tydesc_glue(ccx: @CrateContext, + static_ti: @mut tydesc_info) { + lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti); + lazily_emit_tydesc_glue(ccx, abi::tydesc_field_drop_glue, static_ti); + lazily_emit_tydesc_glue(ccx, abi::tydesc_field_free_glue, static_ti); +} + +/// Emits all tydesc glue, including visitor glue. pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext, static_ti: @mut tydesc_info) { lazily_emit_tydesc_glue(ccx, abi::tydesc_field_take_glue, static_ti); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 381c257f6511c..e0ed48265e6d7 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -864,7 +864,7 @@ pub fn make_impl_vtable(ccx: @CrateContext, // Generate a type descriptor for the vtable. let tydesc = get_tydesc(ccx, self_ty); - glue::lazily_emit_all_tydesc_glue(ccx, tydesc); + glue::lazily_emit_most_tydesc_glue(ccx, tydesc); make_vtable(ccx, tydesc, methods) } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index d4c34a3ace53b..4a7b6ae859f36 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -121,7 +121,8 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint) ~"uninit" | ~"init" | ~"transmute" | ~"move_val" | ~"move_val_init" => use_repr, - ~"get_tydesc" | ~"needs_drop" => use_tydesc, + ~"get_tydesc" | ~"get_tydesc_for_visiting" | + ~"needs_drop" => use_tydesc, ~"atomic_cxchg" | ~"atomic_cxchg_acq"| ~"atomic_cxchg_rel"| ~"atomic_load" | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 6ae03ee45062d..ced50aef29a8b 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3508,6 +3508,10 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { // FIXME (#3730): return *intrinsic::tydesc, not *() (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) } + ~"get_tydesc_for_visiting" => { + // FIXME (#3730): return *intrinsic::tydesc, not *() + (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } ~"visit_tydesc" => { let tydesc_name = special_idents::tydesc; assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs index a05009e375cf9..72baa621b9eb4 100644 --- a/src/libstd/repr.rs +++ b/src/libstd/repr.rs @@ -27,6 +27,7 @@ use reflect; use reflect::{MovePtr, align}; use str::StrSlice; use to_str::ToStr; +use unstable::intrinsics; use vec::raw::{VecRepr, SliceRepr}; use vec; use vec::{OwnedVector, UnboxedVecRepr}; @@ -570,6 +571,7 @@ impl TyVisitor for ReprVisitor { fn visit_closure_ptr(&self, _ck: uint) -> bool { true } } +#[cfg(stage0)] pub fn write_repr(writer: @Writer, object: &T) { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; @@ -580,6 +582,18 @@ pub fn write_repr(writer: @Writer, object: &T) { } } +#[cfg(not(stage0))] +pub fn write_repr(writer: @Writer, object: &T) { + unsafe { + let ptr = ptr::to_unsafe_ptr(object) as *c_void; + let tydesc: *intrinsic::TyDesc = + transmute(intrinsics::get_tydesc_for_visiting::()); + let u = ReprVisitor(ptr, writer); + let v = reflect::MovePtrAdaptor(u); + visit_tydesc(tydesc, @v as @TyVisitor) + } +} + #[cfg(test)] struct P {a: int, b: float} diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 521708621fc89..3323706fc0748 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -122,6 +122,9 @@ pub extern "rust-intrinsic" { // and TyVisitor which are in librustc //fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> (); + #[cfg(not(stage0))] + pub fn get_tydesc_for_visiting() -> *(); + pub fn frame_address(f: &once fn(*u8)); /// Get the address of the `__morestack` stack growth function.