@@ -49,6 +49,8 @@ pub type type_uses = uint; // Bitmask
49
49
pub static use_repr: uint = 1 ; /* Dependency on size/alignment/mode and
50
50
take/drop glue */
51
51
pub static use_tydesc: uint = 2 ; /* Takes the tydesc, or compares */
52
+ pub static use_all: uint = use_repr|use_tydesc;
53
+
52
54
53
55
pub struct Context {
54
56
ccx : @mut CrateContext ,
@@ -57,6 +59,14 @@ pub struct Context {
57
59
58
60
pub fn type_uses_for( ccx : @mut CrateContext , fn_id : def_id , n_tps : uint )
59
61
-> @~[ type_uses ] {
62
+
63
+ fn store_type_uses ( cx : Context , fn_id : def_id ) -> @~[ type_uses ] {
64
+ let Context { uses, ccx } = cx;
65
+ let uses = @copy * uses; // freeze
66
+ ccx. type_use_cache . insert ( fn_id, uses) ;
67
+ uses
68
+ }
69
+
60
70
match ccx. type_use_cache . find ( & fn_id) {
61
71
Some ( uses) => return * uses,
62
72
None => ( )
@@ -69,28 +79,25 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
69
79
} ;
70
80
71
81
// Conservatively assume full use for recursive loops
72
- ccx. type_use_cache . insert ( fn_id, @vec:: from_elem ( n_tps, 3 u ) ) ;
82
+ ccx. type_use_cache . insert ( fn_id, @vec:: from_elem ( n_tps, use_all ) ) ;
73
83
74
84
let cx = Context {
75
85
ccx : ccx,
76
86
uses : @mut vec:: from_elem ( n_tps, 0 )
77
87
} ;
78
- match ty:: get ( ty:: lookup_item_type ( cx. ccx . tcx , fn_id) . ty ) . sty {
79
- ty:: ty_bare_fn( ty:: BareFnTy { sig : ref sig, _} ) |
80
- ty:: ty_closure( ty:: ClosureTy { sig : ref sig, _} ) => {
81
- for sig. inputs. iter( ) . advance |arg| {
82
- type_needs( & cx, use_repr, * arg) ;
83
- }
84
- }
85
- _ => ( )
86
- }
87
88
88
- if fn_id_loc. crate != local_crate {
89
- let Context { uses, _ } = cx;
90
- let uses = @copy * uses; // freeze
91
- ccx. type_use_cache. insert( fn_id, uses) ;
92
- return uses;
89
+ // If the method is a default method, we mark all of the types as
90
+ // used. This is imprecise, but simple. Getting it right is
91
+ // tricky because the substs on the call and the substs on the
92
+ // default method differ, because of substs on the trait/impl.
93
+ let is_default = ccx. tcx . provided_method_sources . contains_key ( & fn_id_loc) ;
94
+ // We also mark all of the params as used if it is an extern thing
95
+ // that we haven't been able to inline yet.
96
+ if is_default || fn_id_loc. crate != local_crate {
97
+ for uint:: range( 0 u, n_tps) |n| { cx. uses [ n] |= use_all; }
98
+ return store_type_uses ( cx, fn_id) ;
93
99
}
100
+
94
101
let map_node = match ccx. tcx . items . find ( & fn_id_loc. node ) {
95
102
Some ( x) => ( /*bad*/ copy * x) ,
96
103
None => ccx. sess . bug ( fmt ! ( "type_uses_for: unbound item ID %?" ,
@@ -106,7 +113,10 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
106
113
// This will be a static trait method. For now, we just assume
107
114
// it fully depends on all of the type information. (Doing
108
115
// otherwise would require finding the actual implementation).
109
- for uint:: range( 0 u, n_tps) |n| { cx. uses[ n] |= use_repr|use_tydesc; }
116
+ for uint:: range( 0 u, n_tps) |n| { cx. uses [ n] |= use_all; }
117
+ // We need to return early, before the arguments are processed,
118
+ // because of difficulties in the handling of Self.
119
+ return store_type_uses ( cx, fn_id) ;
110
120
}
111
121
ast_map:: node_variant( _, _, _) => {
112
122
for uint:: range( 0 u, n_tps) |n| { cx. uses [ n] |= use_repr; }
@@ -171,10 +181,19 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
171
181
token:: get_ident_interner( ) ) ) ) ;
172
182
}
173
183
}
174
- let Context { uses, _ } = cx;
175
- let uses = @copy * uses; // freeze
176
- ccx. type_use_cache . insert ( fn_id, uses) ;
177
- uses
184
+
185
+ // Now handle arguments
186
+ match ty:: get ( ty:: lookup_item_type ( cx. ccx . tcx , fn_id) . ty ) . sty {
187
+ ty:: ty_bare_fn( ty:: BareFnTy { sig : ref sig, _} ) |
188
+ ty:: ty_closure( ty:: ClosureTy { sig : ref sig, _} ) => {
189
+ for sig. inputs. iter( ) . advance |arg| {
190
+ type_needs( & cx, use_repr, * arg) ;
191
+ }
192
+ }
193
+ _ => ( )
194
+ }
195
+
196
+ store_type_uses( cx, fn_id)
178
197
}
179
198
180
199
pub fn type_needs( cx: & Context , use_: uint, ty: ty:: t) {
0 commit comments