@@ -30,7 +30,7 @@ use middle::trans::machine::*;
3030use middle:: trans:: reflect;
3131use middle:: trans:: tvec;
3232use middle:: trans:: type_:: Type ;
33- use middle:: trans:: type_of:: type_of;
33+ use middle:: trans:: type_of:: { type_of, sizing_type_of } ;
3434use middle:: ty;
3535use util:: ppaux:: ty_to_short_str;
3636use util:: ppaux;
@@ -100,23 +100,29 @@ pub fn lazily_emit_all_tydesc_glue(ccx: @CrateContext,
100100 lazily_emit_tydesc_glue ( ccx, abi:: tydesc_field_visit_glue, static_ti) ;
101101}
102102
103- fn simplified_glue_type ( tcx : ty:: ctxt , field : uint , t : ty:: t ) -> ty:: t {
103+ fn get_glue_type ( ccx : & CrateContext , field : uint , t : ty:: t ) -> ty:: t {
104+ let tcx = ccx. tcx ;
104105 if field == abi:: tydesc_field_drop_glue {
105106 if !ty:: type_needs_drop ( tcx, t) {
106- return ty:: mk_nil ( ) ;
107+ return ty:: mk_i8 ( ) ;
107108 }
108109 match ty:: get ( t) . sty {
109- ty:: ty_box( typ)
110- if !ty:: type_needs_drop ( tcx, typ) =>
111- return ty:: mk_box ( tcx, ty:: mk_nil ( ) ) ,
112-
113- ty:: ty_uniq( typ)
114- if !ty:: type_needs_drop ( tcx, typ) =>
115- return ty:: mk_uniq ( tcx, ty:: mk_nil ( ) ) ,
110+ ty:: ty_box( typ) if !ty:: type_needs_drop ( tcx, typ) =>
111+ return ty:: mk_box ( tcx, ty:: mk_i8 ( ) ) ,
112+
113+ ty:: ty_uniq( typ) if !ty:: type_needs_drop ( tcx, typ) => {
114+ let llty = sizing_type_of ( ccx, typ) ;
115+ // Unique boxes do not allocate for zero-size types. The standard library may assume
116+ // that `free` is never called on the pointer returned for `~ZeroSizeType`.
117+ if llsize_of_alloc ( ccx, llty) == 0 {
118+ return ty:: mk_i8 ( ) ;
119+ } else {
120+ return ty:: mk_uniq ( tcx, ty:: mk_i8 ( ) ) ;
121+ }
122+ }
116123
117- ty:: ty_vec( mt, ty:: vstore_uniq)
118- if !ty:: type_needs_drop ( tcx, mt. ty ) =>
119- return ty:: mk_uniq ( tcx, ty:: mk_nil ( ) ) ,
124+ ty:: ty_vec( mt, ty:: vstore_uniq) if !ty:: type_needs_drop ( tcx, mt. ty ) =>
125+ return ty:: mk_uniq ( tcx, ty:: mk_i8 ( ) ) ,
120126
121127 _ => { }
122128 }
@@ -128,7 +134,7 @@ fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
128134pub fn lazily_emit_tydesc_glue ( ccx : @CrateContext , field : uint , ti : @tydesc_info ) {
129135 let _icx = push_ctxt ( "lazily_emit_tydesc_glue" ) ;
130136
131- let simpl = simplified_glue_type ( ccx. tcx , field, ti. ty ) ;
137+ let simpl = get_glue_type ( ccx, field, ti. ty ) ;
132138 if simpl != ti. ty {
133139 let _icx = push_ctxt ( "lazily_emit_simplified_tydesc_glue" ) ;
134140 let simpl_ti = get_tydesc ( ccx, simpl) ;
@@ -204,7 +210,7 @@ pub fn call_tydesc_glue_full(bcx: &Block, v: ValueRef, tydesc: ValueRef,
204210 PointerCast ( bcx, v, Type :: i8p ( ) )
205211 } else {
206212 let ty = static_ti. unwrap ( ) . ty ;
207- let simpl = simplified_glue_type ( ccx. tcx , field, ty) ;
213+ let simpl = get_glue_type ( ccx, field, ty) ;
208214 if simpl != ty {
209215 PointerCast ( bcx, v, type_of ( ccx, simpl) . ptr_to ( ) )
210216 } else {
0 commit comments