diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index e85afca2000..38594ea2c17 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -65,6 +65,7 @@ const debug_llvm: uint = 1 << 13; const count_type_sizes: uint = 1 << 14; const meta_stats: uint = 1 << 15; const no_opt: uint = 1 << 16; +const no_monomorphic_collapse: uint = 1 << 17; fn debugging_opts_map() -> ~[(~str, ~str, uint)] { ~[(~"verbose", ~"in general, enable more debug printouts", verbose), @@ -90,6 +91,8 @@ fn debugging_opts_map() -> ~[(~str, ~str, uint)] { count_type_sizes), (~"meta-stats", ~"gather metadata statistics", meta_stats), (~"no-opt", ~"do not optimize, even if -O is passed", no_opt), + (~"no-monomorphic-collapse", ~"do not collapse template instantiations", + no_monomorphic_collapse), ] } @@ -242,6 +245,9 @@ impl Session { fn borrowck_stats() -> bool { self.debugging_opt(borrowck_stats) } fn borrowck_note_pure() -> bool { self.debugging_opt(borrowck_note_pure) } fn borrowck_note_loan() -> bool { self.debugging_opt(borrowck_note_loan) } + fn no_monomorphic_collapse() -> bool { + self.debugging_opt(no_monomorphic_collapse) + } fn str_of(id: ast::ident) -> ~str { *self.parse_sess.interner.get(id) diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index accc683eb27..ed1fd0f685d 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -320,37 +320,43 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t], let param_ids = match param_uses { Some(uses) => { vec::map2(precise_param_ids, uses, |id, uses| { - match *id { - (a, b@Some(_)) => mono_precise(a, b), - (subst, None) => { - if *uses == 0u { - mono_any - } else if *uses == type_use::use_repr && - !ty::type_needs_drop(ccx.tcx, subst) - { - let llty = type_of::type_of(ccx, subst); - let size = machine::llbitsize_of_real(ccx, llty); - let align = shape::llalign_of_pref(ccx, llty); - let mode = datum::appropriate_mode(subst); + if ccx.sess.no_monomorphic_collapse() { + match *id { + (a, b) => mono_precise(a, b) + } + } else { + match *id { + (a, b@Some(_)) => mono_precise(a, b), + (subst, None) => { + if *uses == 0u { + mono_any + } else if *uses == type_use::use_repr && + !ty::type_needs_drop(ccx.tcx, subst) + { + let llty = type_of::type_of(ccx, subst); + let size = machine::llbitsize_of_real(ccx, llty); + let align = shape::llalign_of_pref(ccx, llty); + let mode = datum::appropriate_mode(subst); - // FIXME(#3547)---scalars and floats are - // treated differently in most ABIs. But we - // should be doing something more detailed - // here. - let is_float = match ty::get(subst).sty { - ty::ty_float(_) => true, - _ => false - }; + // FIXME(#3547)---scalars and floats are + // treated differently in most ABIs. But we + // should be doing something more detailed + // here. + let is_float = match ty::get(subst).sty { + ty::ty_float(_) => true, + _ => false + }; - // Special value for nil to prevent problems - // with undef return pointers. - if size <= 8u && ty::type_is_nil(subst) { - mono_repr(0u, 0u, is_float, mode) + // Special value for nil to prevent problems + // with undef return pointers. + if size <= 8u && ty::type_is_nil(subst) { + mono_repr(0u, 0u, is_float, mode) + } else { + mono_repr(size, align, is_float, mode) + } } else { - mono_repr(size, align, is_float, mode) + mono_precise(subst, None) } - } else { - mono_precise(subst, None) } } }