diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 4fe26ea0b94..fda51e744ce 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -399,17 +399,17 @@ pub fn malloc_raw_dyn_managed<'a>( // Type descriptor and type glue stuff -pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { +pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> Rc { match ccx.tydescs.borrow().find(&t) { - Some(&inf) => return inf, + Some(inf) => return inf.clone(), _ => { } } ccx.stats.n_static_tydescs.set(ccx.stats.n_static_tydescs.get() + 1u); - let inf = glue::declare_tydesc(ccx, t); + let inf = Rc::new(glue::declare_tydesc(ccx, t)); - ccx.tydescs.borrow_mut().insert(t, inf); - return inf; + ccx.tydescs.borrow_mut().insert(t, inf.clone()); + inf } #[allow(dead_code)] // useful diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index 144ffe494b2..119750cd9ce 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -64,7 +64,7 @@ pub struct CrateContext { pub item_symbols: RefCell>, pub link_meta: LinkMeta, pub drop_glues: RefCell>, - pub tydescs: RefCell>, + pub tydescs: RefCell>>, /// Set when running emit_tydescs to enforce that no more tydescs are /// created. pub finished_tydescs: Cell, diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 02da7f9797d..8488261db9c 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -145,39 +145,34 @@ pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef { glue } -pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: @tydesc_info) { +pub fn lazily_emit_visit_glue(ccx: &CrateContext, ti: &tydesc_info) -> ValueRef { let _icx = push_ctxt("lazily_emit_visit_glue"); let llfnty = Type::glue_fn(ccx, type_of(ccx, ti.ty).ptr_to()); match ti.visit_glue.get() { - Some(_) => (), + Some(visit_glue) => visit_glue, None => { debug!("+++ lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty)); let glue_fn = declare_generic_glue(ccx, ti.ty, llfnty, "visit"); ti.visit_glue.set(Some(glue_fn)); make_generic_glue(ccx, ti.ty, glue_fn, make_visit_glue, "visit"); debug!("--- lazily_emit_tydesc_glue VISIT {}", ppaux::ty_to_str(ccx.tcx(), ti.ty)); + glue_fn } } } // See [Note-arg-mode] pub fn call_visit_glue(bcx: &Block, v: ValueRef, tydesc: ValueRef, - static_ti: Option<@tydesc_info>) { + static_ti: Option<&tydesc_info>) { let _icx = push_ctxt("call_tydesc_glue_full"); let ccx = bcx.ccx(); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. if bcx.unreachable.get() && !ccx.sess().no_landing_pads() { return; } - let static_glue_fn = match static_ti { - None => None, - Some(sti) => { - lazily_emit_visit_glue(ccx, sti); - sti.visit_glue.get() - } - }; + let static_glue_fn = static_ti.map(|sti| lazily_emit_visit_glue(ccx, sti)); // When static type info is available, avoid casting to a generic pointer. let llrawptr = if static_glue_fn.is_none() { @@ -404,7 +399,7 @@ fn incr_refcnt_of_boxed<'a>(bcx: &'a Block<'a>, // Generates the declaration for (but doesn't emit) a type descriptor. -pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { +pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> tydesc_info { // If emit_tydescs already ran, then we shouldn't be creating any new // tydescs. assert!(!ccx.finished_tydescs.get()); @@ -430,16 +425,15 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { let ty_name = token::intern_and_get_ident(ppaux::ty_to_str(ccx.tcx(), t)); let ty_name = C_str_slice(ccx, ty_name); - let inf = @tydesc_info { + debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t)); + tydesc_info { ty: t, tydesc: gvar, size: llsize, align: llalign, name: ty_name, visit_glue: Cell::new(None), - }; - debug!("--- declare_tydesc {}", ppaux::ty_to_str(ccx.tcx(), t)); - return inf; + } } fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, @@ -491,9 +485,7 @@ pub fn emit_tydescs(ccx: &CrateContext) { // As of this point, allow no more tydescs to be created. ccx.finished_tydescs.set(true); let glue_fn_ty = Type::generic_glue_fn(ccx).ptr_to(); - for (_, &val) in ccx.tydescs.borrow().iter() { - let ti = val; - + for (_, ti) in ccx.tydescs.borrow().iter() { // Each of the glue functions needs to be cast to a generic type // before being put into the tydesc because we only have a singleton // tydesc type. Then we'll recast each function to its real type when diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index dc5946201f3..3a0083ba5c6 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -328,7 +328,7 @@ pub fn trans_intrinsic(ccx: &CrateContext, "get_tydesc" => { let tp_ty = *substs.tys.get(0); let static_ti = get_tydesc(ccx, tp_ty); - glue::lazily_emit_visit_glue(ccx, static_ti); + glue::lazily_emit_visit_glue(ccx, &*static_ti); // FIXME (#3730): ideally this shouldn't need a cast, // but there's a circularity between translating rust types to llvm diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index ed956b74ea9..a1752862715 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -76,7 +76,7 @@ impl<'a, 'b> Reflector<'a, 'b> { pub fn c_tydesc(&mut self, t: ty::t) -> ValueRef { let bcx = self.bcx; let static_ti = get_tydesc(bcx.ccx(), t); - glue::lazily_emit_visit_glue(bcx.ccx(), static_ti); + glue::lazily_emit_visit_glue(bcx.ccx(), &*static_ti); PointerCast(bcx, static_ti.tydesc, self.tydesc_ty.ptr_to()) }