@@ -62,11 +62,12 @@ type fn_purity_table = hashmap[ast::def_id, ast::purity];
62
62
type unify_cache_entry = tup ( ty:: t , ty:: t , vec[ mutable ty:: t ] ) ;
63
63
type unify_cache = hashmap [ unify_cache_entry, ty:: unify:: result] ;
64
64
65
+ type obj_info = rec ( vec[ ast:: obj_field ] obj_fields , ast:: def_id this_obj ) ;
66
+
65
67
type crate_ctxt = rec ( session:: session sess,
66
68
ty:: type_cache type_cache,
67
69
@ty_item_table item_items ,
68
- vec[ ast:: obj_field ] obj_fields ,
69
- option:: t[ ast:: def_id ] this_obj ,
70
+ mutable vec[ obj_info] obj_infos ,
70
71
@fn_purity_table fn_purity_table ,
71
72
mutable int next_var_id ,
72
73
unify_cache unify_cache,
@@ -2275,21 +2276,10 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2275
2276
auto t = ty:: mk_nil ( fcx. ccx . tcx ) ;
2276
2277
let ty:: t this_obj_ty;
2277
2278
2278
- auto this_obj_id = fcx. ccx . this_obj ;
2279
- alt ( this_obj_id) {
2280
- // If we're inside a current object, grab its type.
2281
- case ( some[ ast:: def_id] ( ?def_id) ) {
2282
- this_obj_ty = ty:: lookup_item_type ( fcx. ccx . sess ,
2283
- fcx. ccx . tcx , fcx. ccx . type_cache , def_id) . _1 ;
2284
- }
2285
- // Otherwise, we should be able to look up the object we're
2286
- // "with".
2287
- case ( _) {
2288
- // TODO.
2289
-
2290
- fail;
2291
- }
2292
- }
2279
+ auto oinfo_opt = get_obj_info ( fcx. ccx ) ;
2280
+ auto this_obj_id = option:: get[ obj_info] ( oinfo_opt) . this_obj ;
2281
+ this_obj_ty = ty:: lookup_item_type ( fcx. ccx . sess ,
2282
+ fcx. ccx . tcx , fcx. ccx . type_cache , this_obj_id) . _1 ;
2293
2283
2294
2284
// Grab this method's type out of the current object type.
2295
2285
alt ( struct ( fcx. ccx . tcx , this_obj_ty) ) {
@@ -2561,6 +2551,10 @@ fn next_ty_var(&@crate_ctxt ccx) -> ty::t {
2561
2551
ret t;
2562
2552
}
2563
2553
2554
+ fn get_obj_info ( & @crate_ctxt ccx ) -> option:: t [ obj_info ] {
2555
+ ret vec:: last[ obj_info] ( ccx. obj_infos ) ;
2556
+ }
2557
+
2564
2558
fn check_decl_local ( & @fn_ctxt fcx , & @ast:: decl decl) -> @ast:: decl {
2565
2559
alt ( decl. node ) {
2566
2560
case ( ast:: decl_local ( ?local) ) {
@@ -2661,8 +2655,7 @@ fn check_block(&@fn_ctxt fcx, &ast::block block) {
2661
2655
write_nil_type ( fcx. ccx . tcx , fcx. ccx . node_types , block. node . a . id ) ;
2662
2656
}
2663
2657
2664
- fn check_const ( & @crate_ctxt ccx , & span sp, & ast:: ident ident, & @ast:: ty t,
2665
- & @ast:: expr e, & ast:: def_id id, & ast:: ann ann) {
2658
+ fn check_const ( & @crate_ctxt ccx , & span sp, & @ast:: expr e, & ast:: ann ann) {
2666
2659
// FIXME: this is kinda a kludge; we manufacture a fake "function context"
2667
2660
// for checking the initializer expression.
2668
2661
auto rty = ann_to_type ( ccx. node_types , ann) ;
@@ -2675,17 +2668,21 @@ fn check_const(&@crate_ctxt ccx, &span sp, &ast::ident ident, &@ast::ty t,
2675
2668
}
2676
2669
2677
2670
fn check_fn ( & @crate_ctxt ccx , & ast:: fn_decl decl, ast:: proto proto,
2678
- & ast:: block body) -> ast :: _fn {
2671
+ & ast:: block body) {
2679
2672
auto local_ty_table = @common:: new_def_hash[ ty:: t] ( ) ;
2680
2673
2681
2674
// FIXME: duplicate work: the item annotation already has the arg types
2682
2675
// and return type translated to typeck::ty values. We don't need do to it
2683
2676
// again here, we can extract them.
2684
2677
2685
-
2686
- for ( ast:: obj_field f in ccx. obj_fields) {
2687
- auto field_ty = ty:: ann_to_type( ccx. node_types, f. ann) ;
2688
- local_ty_table. insert( f. id, field_ty) ;
2678
+ alt ( get_obj_info ( ccx) ) {
2679
+ case ( option:: some[ obj_info] ( ?oinfo) ) {
2680
+ for ( ast:: obj_field f in oinfo. obj_fields) {
2681
+ auto field_ty = ty:: ann_to_type( ccx. node_types, f. ann) ;
2682
+ local_ty_table. insert( f. id, field_ty) ;
2683
+ }
2684
+ }
2685
+ case ( option:: none[ obj_info] ) { /* no fields */ }
2689
2686
}
2690
2687
2691
2688
// Store the type of each argument in the table.
@@ -2713,21 +2710,38 @@ fn check_fn(&@crate_ctxt ccx, &ast::fn_decl decl, ast::proto proto,
2713
2710
}
2714
2711
2715
2712
writeback:: resolve_local_types_in_block( fcx, body) ;
2713
+ }
2716
2714
2717
- ret rec( decl=decl, proto=proto, body=body) ;
2715
+ fn check_method( & @crate_ctxt ccx, & @ast:: method method) {
2716
+ check_fn( ccx, method. node. meth. decl, method. node. meth. proto,
2717
+ method. node. meth. body) ;
2718
2718
}
2719
2719
2720
- fn update_obj_fields( & @crate_ctxt ccx, & @ast:: item i) -> @crate_ctxt {
2721
- alt ( i. node) {
2720
+ fn check_item( @crate_ctxt ccx, & @ast:: item it) {
2721
+ alt ( it. node) {
2722
+ case ( ast:: item_const( _, _, ?e, _, ?a) ) {
2723
+ check_const( ccx, it. span, e, a) ;
2724
+ }
2725
+ case ( ast:: item_fn( _, ?f, _, _, _) ) {
2726
+ check_fn( ccx, f. decl, f. proto, f. body) ;
2727
+ }
2722
2728
case ( ast:: item_obj( _, ?ob, _, ?obj_def_ids, _) ) {
2729
+ // We're entering an object, so gather up the info we need.
2723
2730
let ast:: def_id di = obj_def_ids. ty;
2724
- ret @rec( obj_fields = ob. fields,
2725
- this_obj = some[ ast:: def_id] ( di) with * ccx) ;
2726
- }
2727
- case ( _) {
2731
+ vec:: push[ obj_info] ( ccx. obj_infos,
2732
+ rec( obj_fields=ob. fields, this_obj=di) ) ;
2733
+
2734
+ // Typecheck the methods.
2735
+ for ( @ast:: method method in ob. methods) {
2736
+ check_method( ccx, method) ;
2737
+ }
2738
+ option:: may[ @ast:: method] ( bind check_method( ccx, _) , ob. dtor) ;
2739
+
2740
+ // Now remove the info from the stack.
2741
+ vec:: pop[ obj_info] ( ccx. obj_infos) ;
2728
2742
}
2743
+ case ( _) { /* nothing to do */ }
2729
2744
}
2730
- ret ccx;
2731
2745
}
2732
2746
2733
2747
@@ -2783,15 +2797,13 @@ fn mk_fn_purity_table(&@ast::crate crate) -> @fn_purity_table {
2783
2797
ret res;
2784
2798
}
2785
2799
2786
- // TODO: Remove the third element of this tuple; rely solely on the node type
2787
- // table.
2788
- type typecheck_result = tup ( node_type_table , ty:: type_cache , @ast:: crate ) ;
2800
+ type typecheck_result = tup ( node_type_table , ty:: type_cache ) ;
2789
2801
2790
2802
fn check_crate ( & ty:: ctxt tcx, & @ast:: crate crate) -> typecheck_result {
2791
2803
auto sess = tcx. sess ;
2792
2804
auto result = collect:: collect_item_types ( sess, tcx, crate ) ;
2793
2805
2794
- let vec[ ast :: obj_field ] fields = [ ] ;
2806
+ let vec[ obj_info ] obj_infos = [ ] ;
2795
2807
2796
2808
auto hasher = hash_unify_cache_entry;
2797
2809
auto eqer = eq_unify_cache_entry;
@@ -2803,28 +2815,24 @@ fn check_crate(&ty::ctxt tcx, &@ast::crate crate) -> typecheck_result {
2803
2815
auto ccx = @rec ( sess=sess,
2804
2816
type_cache=result. _0 ,
2805
2817
item_items=result. _1 ,
2806
- obj_fields=fields,
2807
- this_obj=none[ ast:: def_id] ,
2808
- fn_purity_table = fpt,
2818
+ mutable obj_infos=obj_infos,
2819
+ fn_purity_table=fpt,
2809
2820
mutable next_var_id=0 ,
2810
2821
unify_cache=unify_cache,
2811
2822
mutable cache_hits=0 u,
2812
2823
mutable cache_misses=0 u,
2813
2824
tcx=tcx,
2814
2825
node_types=node_types) ;
2815
2826
2816
- auto fld = fold:: new_identity_fold[ @crate_ctxt] ( ) ;
2817
-
2818
- fld = @rec ( update_env_for_item = bind update_obj_fields ( _, _) ,
2819
- fold_fn = bind check_fn ( _, _, _, _)
2820
- with * fld) ;
2827
+ auto visit = rec ( visit_item_pre = bind check_item ( ccx, _)
2828
+ with walk:: default_visitor ( ) ) ;
2821
2829
2822
- auto crate_1 = fold :: fold_crate [ @crate_ctxt ] ( ccx , fld , crate ) ;
2830
+ walk :: walk_crate ( visit , * crate ) ;
2823
2831
2824
2832
log #fmt( "cache hit rate: %u/%u" , ccx. cache_hits ,
2825
2833
ccx. cache_hits + ccx. cache_misses ) ;
2826
2834
2827
- ret tup ( node_types, ccx. type_cache , crate_1 ) ;
2835
+ ret tup ( node_types, ccx. type_cache ) ;
2828
2836
}
2829
2837
2830
2838
//
0 commit comments