Skip to content

Commit 4cd3d4a

Browse files
committed
More work on typechecking classes
classes-simple doesn't fail until trans now!
1 parent 4220dcf commit 4cd3d4a

File tree

2 files changed

+48
-7
lines changed

2 files changed

+48
-7
lines changed

src/comp/middle/ty.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2493,7 +2493,6 @@ fn enum_variant_with_id(cx: ctxt, enum_id: ast::def_id,
24932493

24942494
// If the given item is in an external crate, looks up its type and adds it to
24952495
// the type cache. Returns the type parameters and type.
2496-
// a precondition (did.crate != ast::local_crate) would be nice
24972496
fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
24982497
alt cx.tcache.find(did) {
24992498
some(tpt) { ret tpt; }

src/comp/middle/typeck.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
209209
}
210210

211211

212-
// Returns the one-level-deep structure of the given type.f
212+
// Returns the one-level-deep structure of the given type.
213213
fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty {
214214
ty::get(structurally_resolved_type(fcx, sp, typ)).struct
215215
}
@@ -1835,6 +1835,30 @@ fn lookup_method_inner(fcx: @fn_ctxt, expr: @ast::expr,
18351835
result
18361836
}
18371837

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+
18381862
fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
18391863
expr: @ast::expr,
18401864
proto: ast::proto,
@@ -2507,11 +2531,29 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
25072531
_ {}
25082532
}
25092533
}
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;
25152557
}
25162558
_ {}
25172559
}

0 commit comments

Comments
 (0)