@@ -111,6 +111,7 @@ fn get_base_type_def_id(inference_context: infer_ctxt,
111
111
class CoherenceInfo {
112
112
// Contains implementations of methods that are inherent to a type.
113
113
// Methods in these implementations don't need to be exported.
114
+
114
115
let inherent_methods: hashmap<def_id, @dvec<@Impl >>;
115
116
116
117
// Contains implementations of methods associated with a trait. For these,
@@ -129,14 +130,17 @@ class CoherenceChecker {
129
130
130
131
// A mapping from implementations to the corresponding base type
131
132
// definition ID.
133
+
132
134
let base_type_def_ids: hashmap<def_id, def_id>;
133
135
134
136
// A set of implementations in privileged scopes; i.e. those
135
137
// implementations that are defined in the same scope as their base types.
138
+
136
139
let privileged_implementations : hashmap<node_id, ( ) >;
137
140
138
141
// The set of types that we are currently in the privileged scope of. This
139
142
// is used while we traverse the AST while checking privileged scopes.
143
+
140
144
let privileged_types: hashmap<def_id, ( ) >;
141
145
142
146
new ( crate_context: @crate_ctxt) {
@@ -158,17 +162,7 @@ class CoherenceChecker {
158
162
159
163
alt item. node {
160
164
item_impl ( _, associated_traits, self_type, _) {
161
- // XXX: Accept an array of traits.
162
- let optional_associated_trait;
163
- if associated_traits. len ( ) == 0 {
164
- optional_associated_trait = none;
165
- } else {
166
- optional_associated_trait =
167
- some ( associated_traits[ 0 ] ) ;
168
- }
169
-
170
- self . check_implementation ( item,
171
- optional_associated_trait) ;
165
+ self . check_implementation ( item, associated_traits) ;
172
166
}
173
167
_ {
174
168
// Nothing to do.
@@ -195,47 +189,49 @@ class CoherenceChecker {
195
189
self . add_external_crates ( ) ;
196
190
}
197
191
198
- fn check_implementation ( item : @item,
199
- optional_associated_trait : option < @trait_ref > ) {
200
-
192
+ fn check_implementation ( item : @item, associated_traits : ~[ @trait_ref ] ) {
201
193
let self_type = self . crate_context . tcx . tcache . get ( local_def ( item. id ) ) ;
202
- alt optional_associated_trait {
203
- none {
204
- #debug( "(checking implementation) no associated trait for \
205
- item '%s'",
206
- * item. ident ) ;
207
-
208
- alt get_base_type_def_id ( self . inference_context ,
209
- item. span ,
210
- self_type. ty ) {
211
- none {
212
- let session = self . crate_context . tcx . sess ;
213
- session. span_err ( item. span ,
214
- ~"no base type found for inherent \
215
- implementation; implement a \
216
- trait instead") ;
217
- }
218
- some ( _) {
219
- // Nothing to do.
220
- }
194
+
195
+ // If there are no traits, then this implementation must have a
196
+ // base type.
197
+
198
+ if associated_traits. len ( ) == 0 {
199
+ #debug ( "(checking implementation) no associated traits for item \
200
+ '%s'",
201
+ * item. ident ) ;
202
+
203
+ alt get_base_type_def_id ( self . inference_context ,
204
+ item. span ,
205
+ self_type. ty ) {
206
+ none {
207
+ let session = self . crate_context . tcx . sess ;
208
+ session. span_err ( item. span ,
209
+ ~"no base type found for inherent \
210
+ implementation; implement a \
211
+ trait instead") ;
212
+ }
213
+ some ( _) {
214
+ // Nothing to do.
221
215
}
222
216
}
223
- some( associated_trait) {
224
- let def = self . crate_context. tcx. def_map. get
225
- ( associated_trait. ref_id) ;
226
- #debug( "(checking implementation) adding impl for trait \
227
- '%s', item '%s'",
228
- ast_map:: node_id_to_str( self . crate_context. tcx. items,
229
- associated_trait. ref_id) ,
230
- * item. ident) ;
217
+ }
231
218
232
- let implementation = self . create_impl_from_item( item) ;
233
- self . add_trait_method( def_id_of_def( def) , implementation) ;
234
- }
219
+ for associated_traits. each |associated_trait| {
220
+ let def = self . crate_context . tcx . def_map . get
221
+ ( associated_trait. ref_id ) ;
222
+ #debug ( "(checking implementation) adding impl for trait \
223
+ '%s', item '%s'",
224
+ ast_map:: node_id_to_str ( self . crate_context . tcx . items ,
225
+ associated_trait. ref_id ) ,
226
+ * item. ident ) ;
227
+
228
+ let implementation = self . create_impl_from_item ( item) ;
229
+ self . add_trait_method ( def_id_of_def ( def) , implementation) ;
235
230
}
236
231
237
232
// Add the implementation to the mapping from implementation to base
238
233
// type def ID, if there is a base type for this implementation.
234
+
239
235
alt get_base_type_def_id( self . inference_context ,
240
236
item. span ,
241
237
self_type. ty ) {
@@ -326,6 +322,7 @@ class CoherenceChecker {
326
322
327
323
// Converts a polytype to a monotype by replacing all parameters with
328
324
// type variables.
325
+
329
326
fn universally_quantify_polytype ( polytype : ty_param_bounds_and_ty ) -> t {
330
327
let self_region =
331
328
if !polytype. rp { none}
@@ -385,14 +382,6 @@ class CoherenceChecker {
385
382
}
386
383
}
387
384
item_impl ( _, associated_traits, _, _) {
388
- // XXX: Accept an array of traits.
389
- let optional_trait_ref;
390
- if associated_traits. len( ) == 0 {
391
- optional_trait_ref = none;
392
- } else {
393
- optional_trait_ref = some( associated_traits[ 0 ] ) ;
394
- }
395
-
396
385
alt self . base_type_def_ids . find ( local_def ( item. id ) ) {
397
386
none {
398
387
// Nothing to do.
@@ -411,56 +400,50 @@ class CoherenceChecker {
411
400
} else {
412
401
// This implementation is not in scope of
413
402
// its base type. This still might be OK
414
- // if the trait is defined in the same
403
+ // if the traits are defined in the same
415
404
// crate.
416
405
417
- alt optional_trait_ref {
418
- none {
419
- // There is no trait to implement,
420
- // so this is an error.
406
+ if associated_traits. len ( ) == 0 {
407
+ // There is no trait to implement, so
408
+ // this is an error.
409
+
410
+ let session =
411
+ self . crate_context . tcx . sess ;
412
+ session. span_err ( item. span ,
413
+ ~"cannot implement \
414
+ inherent methods \
415
+ for a type outside \
416
+ the scope the type \
417
+ was defined in ; \
418
+ define and \
419
+ implement a trait \
420
+ instead") ;
421
+ }
421
422
422
- let session =
423
- self . crate_context. tcx. sess;
423
+ for associated_traits. each |trait_ref| {
424
+ // This is OK if and only if the
425
+ // trait was defined in this
426
+ // crate.
427
+
428
+ let def_map = self . crate_context . tcx
429
+ . def_map ;
430
+ let trait_def = def_map. get
431
+ ( trait_ref. ref_id ) ;
432
+ let trait_id =
433
+ def_id_of_def ( trait_def) ;
434
+ if trait_id. crate != local_crate {
435
+ let session = self . crate_context
436
+ . tcx . sess ;
424
437
session. span_err ( item. span ,
425
438
~"cannot \
426
- implement \
427
- inherent \
428
- methods for a \
429
- type outside \
430
- the scope the \
431
- type was \
432
- defined in ; \
433
- define and \
434
- implement a \
435
- trait instead") ;
436
- }
437
- some ( trait_ref) {
438
- // This is OK if and only if the
439
- // trait was defined in this
440
- // crate.
441
-
442
- let def_map = self . crate_context
443
- . tcx . def_map ;
444
- let trait_def =
445
- def_map. get ( trait_ref. ref_id ) ;
446
- let trait_id =
447
- def_id_of_def ( trait_def) ;
448
- if trait_id. crate != local_crate {
449
- let session = self
450
- . crate_context . tcx . sess ;
451
- session. span_err ( item. span ,
452
- ~"cannot \
453
- provide \
454
- an \
455
- extension \
456
- implementa\
457
- tion \
458
- for a \
459
- trait not \
460
- defined \
461
- in this \
462
- crate ");
463
- }
439
+ provide an \
440
+ extension \
441
+ implementa\
442
+ tion \
443
+ for a trait \
444
+ not defined \
445
+ in this \
446
+ crate ");
464
447
}
465
448
}
466
449
}
0 commit comments