@@ -1784,22 +1784,98 @@ fn trans_external_path(ccx: @crate_ctxt, did: ast::def_id, t: ty::t)
1784
1784
ret get_extern_const ( ccx. externs , ccx. llmod , name, llty) ;
1785
1785
}
1786
1786
1787
- fn monomorphic_fn ( ccx : @crate_ctxt , fn_id : ast:: def_id , substs : [ ty:: t ] ,
1787
+ fn normalize_for_monomorphization ( tcx : ty:: ctxt , ty : ty:: t ) -> option < ty:: t > {
1788
+ // FIXME[mono] could do this recursively. is that worthwhile?
1789
+ alt ty:: get ( ty) . struct {
1790
+ ty:: ty_box ( mt) { some ( ty:: mk_opaque_box ( tcx) ) }
1791
+ ty:: ty_fn ( fty) { some ( ty:: mk_fn ( tcx, { proto: fty. proto ,
1792
+ inputs: [ ] ,
1793
+ output: ty:: mk_nil ( tcx) ,
1794
+ ret_style: ast:: return_val,
1795
+ constraints: [ ] } ) ) }
1796
+ ty:: ty_iface ( _, _) { some ( ty:: mk_fn ( tcx, { proto: ast:: proto_box,
1797
+ inputs: [ ] ,
1798
+ output: ty:: mk_nil ( tcx) ,
1799
+ ret_style: ast:: return_val,
1800
+ constraints: [ ] } ) ) }
1801
+ ty:: ty_ptr ( _) { some ( ty:: mk_uint ( tcx) ) }
1802
+ _ { none }
1803
+ }
1804
+ }
1805
+
1806
+ fn make_mono_id ( ccx : @crate_ctxt , item : ast:: def_id , substs : [ ty:: t ] ,
1807
+ vtables : option < typeck:: vtable_res > ,
1808
+ param_uses : option < [ type_use:: type_uses ] > ) -> mono_id {
1809
+ let precise_param_ids = alt vtables {
1810
+ some( vts) {
1811
+ let bounds = ty:: lookup_item_type ( ccx. tcx , item) . bounds ;
1812
+ let i = 0 u;
1813
+ vec:: map2 ( * bounds, substs, { |bounds, subst|
1814
+ let v = [ ] ;
1815
+ for bound in * bounds {
1816
+ alt bound {
1817
+ ty : : bound_iface ( _) {
1818
+ v += [ impl:: vtable_id ( ccx, vts[ i] ) ] ;
1819
+ i += 1 u;
1820
+ }
1821
+ _ { }
1822
+ }
1823
+ }
1824
+ mono_precise ( subst, if v. len ( ) > 0 u { some ( v) } else { none } )
1825
+ } )
1826
+ }
1827
+ none {
1828
+ vec : : map ( substs, { |subst| mono_precise ( subst, none) } )
1829
+ }
1830
+ } ;
1831
+ let param_ids = alt param_uses {
1832
+ some( uses) {
1833
+ vec:: map2 ( precise_param_ids, uses, { |id, uses|
1834
+ alt check id {
1835
+ mono_precise( _, some ( _) ) { id }
1836
+ mono_precise ( subst, none) {
1837
+ if uses == 0 u { mono_any }
1838
+ else if uses == type_use:: use_repr &&
1839
+ !ty:: type_needs_drop ( ccx. tcx , subst) {
1840
+ let llty = type_of ( ccx, subst) ;
1841
+ let size = shape:: llsize_of_real ( ccx, llty) ;
1842
+ let align = shape:: llalign_of_real ( ccx, llty) ;
1843
+ // Special value for nil to prevent problems with undef
1844
+ // return pointers.
1845
+ if size == 1 u && ty:: type_is_nil ( subst) {
1846
+ mono_repr ( 0 u, 0 u)
1847
+ } else { mono_repr ( size, align) }
1848
+ } else { id }
1849
+ }
1850
+ }
1851
+ } )
1852
+ }
1853
+ none { precise_param_ids }
1854
+ } ;
1855
+ @{ def: item, params: param_ids}
1856
+ }
1857
+
1858
+ fn monomorphic_fn ( ccx : @crate_ctxt , fn_id : ast:: def_id , real_substs : [ ty:: t ] ,
1788
1859
vtables : option < typeck:: vtable_res > )
1789
1860
-> { val : ValueRef , must_cast : bool , intrinsic : bool } {
1790
1861
let mut must_cast = false ;
1791
- let substs = vec:: map ( substs , { |t|
1792
- alt ty :: get ( t ) . struct {
1793
- ty :: ty_box ( mt ) { must_cast = true ; ty :: mk_opaque_box ( ccx . tcx ) }
1794
- _ { t }
1862
+ let substs = vec:: map ( real_substs , { |t|
1863
+ alt normalize_for_monomorphization ( ccx . tcx , t ) {
1864
+ some ( t ) { must_cast = true ; t }
1865
+ none { t }
1795
1866
}
1796
1867
} ) ;
1797
- let hash_id = @{ def: fn_id, substs: substs, vtables: alt vtables {
1798
- some( os) { some_vts ( vec:: map ( * os, impl:: vtable_id) ) }
1799
- none { no_vts }
1800
- } } ;
1868
+
1869
+ let param_uses = type_use:: type_uses_for ( ccx, fn_id, substs. len ( ) ) ;
1870
+ let hash_id = make_mono_id ( ccx, fn_id, substs, vtables, some ( param_uses) ) ;
1871
+ if vec:: any ( hash_id. params ,
1872
+ { |p| alt p { mono_precise( _, _) { false } _ { true } } } ) {
1873
+ must_cast = true ;
1874
+ }
1801
1875
alt ccx. monomorphized . find ( hash_id) {
1802
- some ( val) { ret { val : val, must_cast : must_cast, intrinsic : false } ; }
1876
+ some ( val) {
1877
+ ret { val : val, must_cast : must_cast, intrinsic : false } ;
1878
+ }
1803
1879
none { }
1804
1880
}
1805
1881
@@ -1867,12 +1943,12 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
1867
1943
impl_self ( selfty) , psubsts, fn_id. node , none) ;
1868
1944
}
1869
1945
ast_map:: node_ctor ( i) {
1870
- alt check ccx . tcx . items . get ( i . id ) {
1871
- ast_map :: node_item ( @ { node : ast:: item_res ( decl, _, _, _, _ ) , _ } , _) {
1946
+ alt check i . node {
1947
+ ast:: item_res ( decl, _, _, _, _) {
1872
1948
set_inline_hint ( lldecl) ;
1873
1949
trans_res_ctor ( ccx, pt, decl, fn_id. node , psubsts, lldecl) ;
1874
1950
}
1875
- ast_map :: node_item ( @ { node : ast:: item_class ( _, _, ctor) , _ } , _ ) {
1951
+ ast:: item_class ( _, _, ctor) {
1876
1952
ccx. sess . unimpl ( "monomorphic class constructor" ) ;
1877
1953
}
1878
1954
}
@@ -4606,6 +4682,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
4606
4682
tydescs: ty:: new_ty_hash ( ) ,
4607
4683
external: util:: common:: new_def_hash ( ) ,
4608
4684
monomorphized: map:: hashmap ( hash_mono_id, { |a, b| a == b} ) ,
4685
+ type_use_cache: util:: common:: new_def_hash ( ) ,
4609
4686
vtables: map:: hashmap ( hash_mono_id, { |a, b| a == b} ) ,
4610
4687
module_data: str_hash :: < ValueRef > ( ) ,
4611
4688
lltypes: ty:: new_ty_hash ( ) ,
0 commit comments