@@ -129,7 +129,8 @@ use syntax::opt_vec;
129
129
use syntax:: parse:: token;
130
130
use syntax:: parse:: token:: special_idents;
131
131
use syntax:: print:: pprust;
132
- use syntax:: oldvisit;
132
+ use syntax:: visit;
133
+ use syntax:: visit:: Visitor ;
133
134
use syntax;
134
135
135
136
pub mod _match;
@@ -296,12 +297,18 @@ impl ExprTyProvider for FnCtxt {
296
297
}
297
298
}
298
299
300
+ struct CheckItemTypesVisitor { ccx : @mut CrateCtxt }
301
+
302
+ impl Visitor < ( ) > for CheckItemTypesVisitor {
303
+ fn visit_item ( & mut self , i : @ast:: item , _: ( ) ) {
304
+ check_item ( self . ccx , i) ;
305
+ visit:: walk_item ( self , i, ( ) ) ;
306
+ }
307
+ }
308
+
299
309
pub fn check_item_types ( ccx : @mut CrateCtxt , crate : & ast:: Crate ) {
300
- let visit = oldvisit:: mk_simple_visitor ( @oldvisit:: SimpleVisitor {
301
- visit_item : |a| check_item ( ccx, a) ,
302
- .. * oldvisit:: default_simple_visitor ( )
303
- } ) ;
304
- oldvisit:: visit_crate ( crate , ( ( ) , visit) ) ;
310
+ let mut visit = CheckItemTypesVisitor { ccx : ccx } ;
311
+ visit:: walk_crate ( & mut visit, crate , ( ) ) ;
305
312
}
306
313
307
314
pub fn check_bare_fn ( ccx : @mut CrateCtxt ,
@@ -326,6 +333,76 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt,
326
333
}
327
334
}
328
335
336
+ struct GatherLocalsVisitor {
337
+ fcx : @mut FnCtxt ,
338
+ tcx : ty:: ctxt ,
339
+ }
340
+
341
+ impl GatherLocalsVisitor {
342
+ fn assign ( & mut self , nid : ast:: NodeId , ty_opt : Option < ty:: t > ) {
343
+ match ty_opt {
344
+ None => {
345
+ // infer the variable's type
346
+ let var_id = self . fcx . infcx ( ) . next_ty_var_id ( ) ;
347
+ let var_ty = ty:: mk_var ( self . fcx . tcx ( ) , var_id) ;
348
+ self . fcx . inh . locals . insert ( nid, var_ty) ;
349
+ }
350
+ Some ( typ) => {
351
+ // take type that the user specified
352
+ self . fcx . inh . locals . insert ( nid, typ) ;
353
+ }
354
+ }
355
+ }
356
+ }
357
+
358
+ impl Visitor < ( ) > for GatherLocalsVisitor {
359
+ // Add explicitly-declared locals.
360
+ fn visit_local ( & mut self , local : @ast:: Local , _: ( ) ) {
361
+ let o_ty = match local. ty . node {
362
+ ast:: ty_infer => None ,
363
+ _ => Some ( self . fcx . to_ty ( & local. ty ) )
364
+ } ;
365
+ self . assign ( local. id , o_ty) ;
366
+ debug ! ( "Local variable %s is assigned type %s" ,
367
+ self . fcx. pat_to_str( local. pat) ,
368
+ self . fcx. infcx( ) . ty_to_str(
369
+ self . fcx. inh. locals. get_copy( & local. id) ) ) ;
370
+ visit:: walk_local ( self , local, ( ) ) ;
371
+
372
+ }
373
+ // Add pattern bindings.
374
+ fn visit_pat ( & mut self , p : @ast:: pat , _: ( ) ) {
375
+ match p. node {
376
+ ast:: pat_ident( _, ref path, _)
377
+ if pat_util:: pat_is_binding ( self . fcx . ccx . tcx . def_map , p) => {
378
+ self . assign ( p. id , None ) ;
379
+ debug ! ( "Pattern binding %s is assigned to %s" ,
380
+ self . tcx. sess. str_of( path. idents[ 0 ] ) ,
381
+ self . fcx. infcx( ) . ty_to_str(
382
+ self . fcx. inh. locals. get_copy( & p. id) ) ) ;
383
+ }
384
+ _ => { }
385
+ }
386
+ visit:: walk_pat ( self , p, ( ) ) ;
387
+
388
+ }
389
+
390
+ fn visit_block ( & mut self , b : & ast:: Block , _: ( ) ) {
391
+ // non-obvious: the `blk` variable maps to region lb, so
392
+ // we have to keep this up-to-date. This
393
+ // is... unfortunate. It'd be nice to not need this.
394
+ do self . fcx . with_region_lb ( b. id ) {
395
+ visit:: walk_block ( self , b, ( ) ) ;
396
+ }
397
+ }
398
+
399
+ // Don't descend into fns and items
400
+ fn visit_fn ( & mut self , _: & visit:: fn_kind , _: & ast:: fn_decl ,
401
+ _: & ast:: Block , _: span , _: ast:: NodeId , _: ( ) ) { }
402
+ fn visit_item ( & mut self , _: @ast:: item , _: ( ) ) { }
403
+
404
+ }
405
+
329
406
pub fn check_fn( ccx : @mut CrateCtxt ,
330
407
opt_self_info : Option < SelfInfo > ,
331
408
purity : ast:: purity ,
@@ -429,24 +506,11 @@ pub fn check_fn(ccx: @mut CrateCtxt,
429
506
opt_self_info : Option < SelfInfo > ) {
430
507
let tcx = fcx. ccx . tcx ;
431
508
432
- let assign: @fn ( ast:: NodeId , Option < ty:: t > ) = |nid, ty_opt| {
433
- match ty_opt {
434
- None => {
435
- // infer the variable's type
436
- let var_id = fcx. infcx ( ) . next_ty_var_id ( ) ;
437
- let var_ty = ty:: mk_var ( fcx. tcx ( ) , var_id) ;
438
- fcx. inh . locals . insert ( nid, var_ty) ;
439
- }
440
- Some ( typ) => {
441
- // take type that the user specified
442
- fcx. inh . locals . insert ( nid, typ) ;
443
- }
444
- }
445
- } ;
509
+ let mut visit = GatherLocalsVisitor { fcx : fcx, tcx : tcx, } ;
446
510
447
511
// Add the self parameter
448
512
for self_info in opt_self_info. iter ( ) {
449
- assign ( self_info. self_id , Some ( self_info. self_ty ) ) ;
513
+ visit . assign ( self_info. self_id , Some ( self_info. self_ty ) ) ;
450
514
debug ! ( "self is assigned to %s" ,
451
515
fcx. infcx( ) . ty_to_str(
452
516
fcx. inh. locals. get_copy( & self_info. self_id) ) ) ;
@@ -457,7 +521,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
457
521
// Create type variables for each argument.
458
522
do pat_util:: pat_bindings ( tcx. def_map , input. pat )
459
523
|_bm, pat_id, _sp, _path| {
460
- assign ( pat_id, None ) ;
524
+ visit . assign ( pat_id, None ) ;
461
525
}
462
526
463
527
// Check the pattern.
@@ -468,66 +532,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
468
532
_match:: check_pat ( & pcx, input. pat , * arg_ty) ;
469
533
}
470
534
471
- // Add explicitly-declared locals.
472
- let visit_local: @fn ( @ast:: Local , ( ( ) , oldvisit:: vt < ( ) > ) ) =
473
- |local, ( e, v) | {
474
- let o_ty = match local. ty . node {
475
- ast:: ty_infer => None ,
476
- _ => Some ( fcx. to_ty ( & local. ty ) )
477
- } ;
478
- assign ( local. id , o_ty) ;
479
- debug ! ( "Local variable %s is assigned type %s" ,
480
- fcx. pat_to_str( local. pat) ,
481
- fcx. infcx( ) . ty_to_str(
482
- fcx. inh. locals. get_copy( & local. id) ) ) ;
483
- oldvisit:: visit_local ( local, ( e, v) ) ;
484
- } ;
485
-
486
- // Add pattern bindings.
487
- let visit_pat: @fn ( @ast:: pat , ( ( ) , oldvisit:: vt < ( ) > ) ) = |p, ( e, v) | {
488
- match p. node {
489
- ast:: pat_ident( _, ref path, _)
490
- if pat_util:: pat_is_binding ( fcx. ccx . tcx . def_map , p) => {
491
- assign ( p. id , None ) ;
492
- debug ! ( "Pattern binding %s is assigned to %s" ,
493
- tcx. sess. str_of( path. idents[ 0 ] ) ,
494
- fcx. infcx( ) . ty_to_str(
495
- fcx. inh. locals. get_copy( & p. id) ) ) ;
496
- }
497
- _ => { }
498
- }
499
- oldvisit:: visit_pat ( p, ( e, v) ) ;
500
- } ;
501
-
502
- let visit_block:
503
- @fn ( & ast:: Block , ( ( ) , oldvisit:: vt < ( ) > ) ) = |b, ( e, v) | {
504
- // non-obvious: the `blk` variable maps to region lb, so
505
- // we have to keep this up-to-date. This
506
- // is... unfortunate. It'd be nice to not need this.
507
- do fcx. with_region_lb ( b. id ) {
508
- oldvisit:: visit_block ( b, ( e, v) ) ;
509
- }
510
- } ;
511
-
512
- // Don't descend into fns and items
513
- fn visit_fn ( _fk : & oldvisit:: fn_kind ,
514
- _decl : & ast:: fn_decl ,
515
- _body : & ast:: Block ,
516
- _sp : span ,
517
- _id : ast:: NodeId ,
518
- ( _t, _v) : ( ( ) , oldvisit:: vt < ( ) > ) ) {
519
- }
520
- fn visit_item ( _i : @ast:: item , ( _e, _v) : ( ( ) , oldvisit:: vt < ( ) > ) ) { }
521
-
522
- let visit = oldvisit:: mk_vt (
523
- @oldvisit:: Visitor { visit_local : visit_local,
524
- visit_pat : visit_pat,
525
- visit_fn : visit_fn,
526
- visit_item : visit_item,
527
- visit_block : visit_block,
528
- ..* oldvisit:: default_visitor ( ) } ) ;
529
-
530
- ( visit. visit_block ) ( body, ( ( ) , visit) ) ;
535
+ visit. visit_block ( body, ( ) ) ;
531
536
}
532
537
}
533
538
0 commit comments