@@ -45,10 +45,7 @@ use syntax::ast_map;
45
45
use syntax:: ast_util:: { def_id_of_def, local_def} ;
46
46
use syntax:: codemap:: { span, dummy_sp} ;
47
47
use syntax:: opt_vec;
48
- use syntax:: oldvisit:: { default_simple_visitor, default_visitor} ;
49
- use syntax:: oldvisit:: { mk_simple_visitor, mk_vt, visit_crate, visit_item} ;
50
- use syntax:: oldvisit:: { Visitor , SimpleVisitor } ;
51
- use syntax:: oldvisit:: { visit_mod} ;
48
+ use syntax:: visit;
52
49
use syntax:: parse;
53
50
use util:: ppaux:: ty_to_str;
54
51
@@ -168,31 +165,89 @@ pub struct CoherenceChecker {
168
165
base_type_def_ids : @mut HashMap < def_id , def_id > ,
169
166
}
170
167
171
- impl CoherenceChecker {
172
- pub fn check_coherence ( self , crate : & Crate ) {
173
- // Check implementations and traits. This populates the tables
174
- // containing the inherent methods and extension methods. It also
175
- // builds up the trait inheritance table.
176
- visit_crate ( crate , ( ( ) , mk_simple_visitor ( @SimpleVisitor {
177
- visit_item : |item| {
168
+ struct CoherenceCheckVisitor { cc : CoherenceChecker }
169
+
170
+ impl visit:: Visitor < ( ) > for CoherenceCheckVisitor {
171
+ fn visit_item ( & mut self , item : @item, _: ( ) ) {
172
+
178
173
// debug!("(checking coherence) item '%s'",
179
- // self.crate_context.tcx.sess.str_of(item.ident));
174
+ // self.cc. crate_context.tcx.sess.str_of(item.ident));
180
175
181
176
match item. node {
182
177
item_impl( _, ref opt_trait, _, _) => {
183
178
let opt_trait : ~[ trait_ref ] =
184
179
opt_trait. iter ( )
185
180
. map ( |x| ( * x) . clone ( ) )
186
181
. collect ( ) ;
187
- self . check_implementation ( item, opt_trait) ;
182
+ self . cc . check_implementation ( item, opt_trait) ;
188
183
}
189
184
_ => {
190
185
// Nothing to do.
191
186
}
192
187
} ;
193
- } ,
194
- .. * default_simple_visitor ( )
195
- } ) ) ) ;
188
+
189
+ visit:: walk_item ( self , item, ( ) ) ;
190
+ }
191
+ }
192
+
193
+ struct PrivilegedScopeVisitor { cc : CoherenceChecker }
194
+
195
+ impl visit:: Visitor < ( ) > for PrivilegedScopeVisitor {
196
+ fn visit_item ( & mut self , item : @item, _: ( ) ) {
197
+
198
+ match item. node {
199
+ item_mod( ref module_) => {
200
+ // Then visit the module items.
201
+ visit:: walk_mod ( self , module_, ( ) ) ;
202
+ }
203
+ item_impl( _, None , ref ast_ty, _) => {
204
+ if !self . cc . ast_type_is_defined_in_local_crate ( ast_ty) {
205
+ // This is an error.
206
+ let session = self . cc . crate_context . tcx . sess ;
207
+ session. span_err ( item. span ,
208
+ "cannot associate methods with a type outside the \
209
+ crate the type is defined in; define and implement \
210
+ a trait or new type instead") ;
211
+ }
212
+ }
213
+ item_impl( _, Some ( ref trait_ref) , _, _) => {
214
+ // `for_ty` is `Type` in `impl Trait for Type`
215
+ let for_ty =
216
+ ty:: node_id_to_type ( self . cc . crate_context . tcx ,
217
+ item. id ) ;
218
+ if !type_is_defined_in_local_crate ( for_ty) {
219
+ // This implementation is not in scope of its base
220
+ // type. This still might be OK if the trait is
221
+ // defined in the same crate.
222
+
223
+ let trait_def_id =
224
+ self . cc . trait_ref_to_trait_def_id ( trait_ref) ;
225
+
226
+ if trait_def_id. crate != LOCAL_CRATE {
227
+ let session = self . cc . crate_context . tcx . sess ;
228
+ session. span_err ( item. span ,
229
+ "cannot provide an extension implementation \
230
+ for a trait not defined in this crate") ;
231
+ }
232
+ }
233
+
234
+ visit:: walk_item ( self , item, ( ) ) ;
235
+ }
236
+ _ => {
237
+ visit:: walk_item ( self , item, ( ) ) ;
238
+ }
239
+ }
240
+ }
241
+ }
242
+
243
+ impl CoherenceChecker {
244
+ pub fn check_coherence ( self , crate : & Crate ) {
245
+ // Check implementations and traits. This populates the tables
246
+ // containing the inherent methods and extension methods. It also
247
+ // builds up the trait inheritance table.
248
+
249
+ let mut visitor = CoherenceCheckVisitor { cc : self } ;
250
+ visit:: walk_crate ( & mut visitor, crate , ( ) ) ;
196
251
197
252
// Check that there are no overlapping trait instances
198
253
self . check_implementation_coherence ( ) ;
@@ -486,53 +541,8 @@ impl CoherenceChecker {
486
541
487
542
// Privileged scope checking
488
543
pub fn check_privileged_scopes ( self , crate : & Crate ) {
489
- visit_crate ( crate , ( ( ) , mk_vt ( @Visitor {
490
- visit_item : |item, ( _context, visitor) | {
491
- match item. node {
492
- item_mod( ref module_) => {
493
- // Then visit the module items.
494
- visit_mod ( module_, item. span , item. id , ( ( ) , visitor) ) ;
495
- }
496
- item_impl( _, None , ref ast_ty, _) => {
497
- if !self . ast_type_is_defined_in_local_crate ( ast_ty) {
498
- // This is an error.
499
- let session = self . crate_context . tcx . sess ;
500
- session. span_err ( item. span ,
501
- "cannot associate methods with a type outside the \
502
- crate the type is defined in; define and implement \
503
- a trait or new type instead") ;
504
- }
505
- }
506
- item_impl( _, Some ( ref trait_ref) , _, _) => {
507
- // `for_ty` is `Type` in `impl Trait for Type`
508
- let for_ty =
509
- ty:: node_id_to_type ( self . crate_context . tcx ,
510
- item. id ) ;
511
- if !type_is_defined_in_local_crate ( for_ty) {
512
- // This implementation is not in scope of its base
513
- // type. This still might be OK if the trait is
514
- // defined in the same crate.
515
-
516
- let trait_def_id =
517
- self . trait_ref_to_trait_def_id ( trait_ref) ;
518
-
519
- if trait_def_id. crate != LOCAL_CRATE {
520
- let session = self . crate_context . tcx . sess ;
521
- session. span_err ( item. span ,
522
- "cannot provide an extension implementation \
523
- for a trait not defined in this crate") ;
524
- }
525
- }
526
-
527
- visit_item ( item, ( ( ) , visitor) ) ;
528
- }
529
- _ => {
530
- visit_item ( item, ( ( ) , visitor) ) ;
531
- }
532
- }
533
- } ,
534
- .. * default_visitor ( )
535
- } ) ) ) ;
544
+ let mut visitor = PrivilegedScopeVisitor { cc : self } ;
545
+ visit:: walk_crate ( & mut visitor, crate , ( ) ) ;
536
546
}
537
547
538
548
pub fn trait_ref_to_trait_def_id ( & self , trait_ref : & trait_ref ) -> def_id {
0 commit comments