@@ -55,8 +55,9 @@ type ty_table = hashmap[ast::def_id, ty::t];
55
55
tag obj_info {
56
56
// Regular objects have a node_id at compile time.
57
57
regular_obj( ast:: obj_field[ ] , ast:: node_id) ;
58
- // Anonymous objects only have a type at compile time.
59
- anon_obj ( ast:: obj_field[ ] , ty:: t) ;
58
+ // Anonymous objects only have a type at compile time. It's optional
59
+ // because not all anonymous objects have a with_obj to attach to.
60
+ anon_obj ( ast:: obj_field[ ] , option:: t[ ty:: sty] ) ;
60
61
}
61
62
62
63
type crate_ctxt = rec( mutable obj_info[ ] obj_infos, ty:: ctxt tcx) ;
@@ -2114,7 +2115,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2114
2115
}
2115
2116
case ( ast:: expr_self_method( ?ident) ) {
2116
2117
auto t = ty:: mk_nil( fcx. ccx. tcx) ;
2117
- let ty:: t this_obj_ty = ty:: mk_nil( fcx. ccx. tcx) ;
2118
+ let option:: t[ ty:: sty] this_obj_sty =
2119
+ some( structure_of( fcx, expr. span, ty:: mk_nil( fcx. ccx. tcx) ) ) ;
2118
2120
let option:: t[ obj_info] this_obj_info = get_obj_info( fcx. ccx) ;
2119
2121
alt ( this_obj_info) {
2120
2122
case ( some( ?oinfo) ) {
@@ -2128,7 +2130,10 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2128
2130
// If we're typechecking a self-method on
2129
2131
// a regular object, this lookup should
2130
2132
// succeed.
2131
- this_obj_ty = tpt. _1;
2133
+ this_obj_sty =
2134
+ some( structure_of( fcx,
2135
+ expr. span,
2136
+ tpt. _1) ) ;
2132
2137
}
2133
2138
case ( none) {
2134
2139
fcx. ccx. tcx. sess. bug(
@@ -2137,8 +2142,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2137
2142
}
2138
2143
}
2139
2144
}
2140
- case ( anon_obj( _, ?obj_ty ) ) {
2141
- this_obj_ty = obj_ty ;
2145
+ case ( anon_obj( _, ?obj_sty ) ) {
2146
+ this_obj_sty = obj_sty ;
2142
2147
}
2143
2148
}
2144
2149
}
@@ -2151,15 +2156,21 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2151
2156
}
2152
2157
2153
2158
// Grab this method's type out of the current object type.
2154
- alt ( structure_of( fcx, expr. span, this_obj_ty) ) {
2155
- case ( ty:: ty_obj( ?methods) ) {
2156
- for ( ty:: method method in methods) {
2157
- if ( method. ident == ident) {
2158
- t = ty:: method_ty_to_fn_ty( fcx. ccx. tcx, method) ;
2159
+ alt ( this_obj_sty) {
2160
+ case ( some( ?sty) ) {
2161
+ alt ( sty) {
2162
+ case ( ty:: ty_obj( ?methods) ) {
2163
+ for ( ty:: method method in methods) {
2164
+ if ( method. ident == ident) {
2165
+ t = ty:: method_ty_to_fn_ty( fcx. ccx. tcx,
2166
+ method) ;
2167
+ }
2168
+ }
2159
2169
}
2170
+ case ( _) { fail; }
2160
2171
}
2161
2172
}
2162
- case ( _ ) { fail ; }
2173
+ case ( none ) { }
2163
2174
}
2164
2175
write:: ty_only_fixup( fcx, id, t) ;
2165
2176
require_impure( fcx. ccx. tcx. sess, fcx. purity, expr. span) ;
@@ -2442,40 +2453,49 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2442
2453
// Typecheck 'with_obj'. If it exists, it had better have
2443
2454
// object type.
2444
2455
let ty:: method[ ] with_obj_methods = ~[ ] ;
2445
- auto with_obj_ty = ty:: mk_nil( fcx. ccx. tcx) ;
2456
+ let ty:: t with_obj_ty = ty:: mk_nil( fcx. ccx. tcx) ;
2457
+ let option:: t[ ty:: sty] with_obj_sty = none;
2446
2458
alt ( ao. with_obj) {
2447
2459
case ( none) { }
2448
2460
case ( some( ?e) ) {
2461
+ // If there's a with_obj, we push it onto the
2462
+ // obj_infos stack so that self-calls can be checked
2463
+ // within its context later.
2449
2464
check_expr( fcx, e) ;
2450
2465
with_obj_ty = expr_ty( fcx. ccx. tcx, e) ;
2451
-
2452
- alt ( structure_of( fcx, e. span, with_obj_ty) ) {
2453
- case ( ty:: ty_obj( ?ms) ) {
2454
- with_obj_methods = ms;
2455
- }
2456
- case ( _) {
2457
- // The user is trying to extend a non-object.
2458
- fcx. ccx. tcx. sess. span_fatal(
2459
- e. span,
2460
- syntax:: print:: pprust:: expr_to_str( e) +
2461
- " does not have object type" ) ;
2466
+ with_obj_sty = some( structure_of( fcx, e. span,
2467
+ with_obj_ty) ) ;
2468
+
2469
+ alt ( with_obj_sty) {
2470
+ case ( none) { }
2471
+ case ( some( ?sty) ) {
2472
+ alt ( sty) {
2473
+ case ( ty:: ty_obj( ?ms) ) {
2474
+ with_obj_methods = ms;
2475
+ }
2476
+ case ( _) {
2477
+ // The user is trying to extend a
2478
+ // non-object.
2479
+ fcx. ccx. tcx. sess. span_fatal(
2480
+ e. span,
2481
+ syntax:: print:: pprust:: expr_to_str( e) +
2482
+ " does not have object type" ) ;
2483
+ }
2484
+ }
2462
2485
}
2463
2486
}
2464
2487
}
2465
2488
}
2466
2489
2467
- log_err "Pushing an anon obj onto the obj_infos stack..." ;
2468
- fn anon_obj_field_to_obj_field( & ast:: anon_obj_field f)
2490
+ fn ao_field_to_o_field( & ast:: anon_obj_field f)
2469
2491
-> ast:: obj_field {
2470
2492
ret rec( mut =f. mut , ty=f. ty, ident=f. ident, id=f. id) ;
2471
2493
}
2472
2494
fcx. ccx. obj_infos +=
2473
- ~[ anon_obj( ivec:: map( anon_obj_field_to_obj_field,
2474
- fields) ,
2475
- with_obj_ty) ] ;
2495
+ ~[ anon_obj( ivec:: map( ao_field_to_o_field, fields) ,
2496
+ with_obj_sty) ] ;
2476
2497
2477
2498
methods += with_obj_methods;
2478
-
2479
2499
ret methods;
2480
2500
}
2481
2501
0 commit comments