@@ -209,7 +209,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
209
209
}
210
210
211
211
212
- // Returns the one-level-deep structure of the given type.f
212
+ // Returns the one-level-deep structure of the given type.
213
213
fn structure_of ( fcx : @fn_ctxt , sp : span , typ : ty:: t ) -> ty:: sty {
214
214
ty:: get ( structurally_resolved_type ( fcx, sp, typ) ) . struct
215
215
}
@@ -1835,6 +1835,30 @@ fn lookup_method_inner(fcx: @fn_ctxt, expr: @ast::expr,
1835
1835
result
1836
1836
}
1837
1837
1838
+ fn lookup_field_ty ( cx : ty:: ctxt , items : [ @ast:: class_item ] ,
1839
+ fieldname : ast:: ident , sp : span )
1840
+ -> ty:: t {
1841
+ for item in items {
1842
+ // this is an access outside the class, so accessing a private
1843
+ // field is an error
1844
+ alt item. node . decl {
1845
+ ast:: instance_var ( declname, t, _, _) if declname == fieldname {
1846
+ alt item. node . privacy {
1847
+ ast:: priv {
1848
+ cx. sess . span_fatal ( sp, "Accessed private field outside \
1849
+ its enclosing class") ;
1850
+ }
1851
+ ast:: pub {
1852
+ ret ast_ty_to_ty( cx, m_check, t) ;
1853
+ }
1854
+ }
1855
+ }
1856
+ _ { /* do nothing */ }
1857
+ }
1858
+ }
1859
+ cx. sess . span_fatal ( sp, #fmt ( "Unbound field %s" , fieldname) ) ;
1860
+ }
1861
+
1838
1862
fn check_expr_fn_with_unifier ( fcx : @fn_ctxt ,
1839
1863
expr : @ast:: expr ,
1840
1864
proto : ast:: proto ,
@@ -2507,11 +2531,29 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
2507
2531
_ { }
2508
2532
}
2509
2533
}
2510
- ty:: ty_class ( _id, _params) {
2511
- // TODO (classes)
2512
- tcx. sess . span_bug ( expr. span ,
2513
- #fmt ( "can't check class field accesses yet: %s" ,
2514
- ty_to_str ( fcx. ccx . tcx , base_t) ) ) ;
2534
+ ty:: ty_class ( base_id, _params) {
2535
+ // (1) verify that the class id actually has a field called
2536
+ // field
2537
+ // For now, this code assumes the class is defined in the local
2538
+ // crate
2539
+ // TODO: handle field references to classes in external crate
2540
+ let err = "Class ID is not bound to a class" ;
2541
+ let field_ty = alt fcx. ccx . tcx . items . find ( base_id. node ) {
2542
+ some ( ast_map:: node_item ( i, _) ) {
2543
+ alt i. node {
2544
+ ast:: item_class ( _, items, _, _, _) {
2545
+ lookup_field_ty ( fcx. ccx . tcx , items, field,
2546
+ expr. span )
2547
+ }
2548
+ _ { fcx. ccx . tcx . sess . span_bug ( expr. span , err) ; }
2549
+ }
2550
+ }
2551
+ _ { fcx. ccx . tcx . sess . span_bug ( expr. span , err) ; }
2552
+ } ;
2553
+ // (2) look up what field's type is, and return it
2554
+ // TODO: actually instantiate any type params
2555
+ write_ty ( tcx, id, field_ty) ;
2556
+ handled = true ;
2515
2557
}
2516
2558
_ { }
2517
2559
}
0 commit comments