about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-02-20 21:37:37 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-02-20 22:26:19 -0800
commit4cd3d4ab1ec70f7d572c585168b225a3ce83100a (patch)
treef7a1fc75369c7fd61172bd26b6042e2d483b1f0a /src/comp
parent4220dcf1e9de2c2d2c329ecefa80108b63a69145 (diff)
More work on typechecking classes
classes-simple doesn't fail until trans now!
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/ty.rs1
-rw-r--r--src/comp/middle/typeck.rs54
2 files changed, 48 insertions, 7 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 3e9822ab4fd..2bd37585d04 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -2493,7 +2493,6 @@ fn enum_variant_with_id(cx: ctxt, enum_id: ast::def_id,
 
 // If the given item is in an external crate, looks up its type and adds it to
 // the type cache. Returns the type parameters and type.
-// a precondition (did.crate != ast::local_crate) would be nice
 fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
     alt cx.tcache.find(did) {
       some(tpt) { ret tpt; }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 69db4b8bca6..f844ad4c2ea 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -209,7 +209,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
 }
 
 
-// Returns the one-level-deep structure of the given type.f
+// Returns the one-level-deep structure of the given type.
 fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty {
     ty::get(structurally_resolved_type(fcx, sp, typ)).struct
 }
@@ -1835,6 +1835,30 @@ fn lookup_method_inner(fcx: @fn_ctxt, expr: @ast::expr,
     result
 }
 
+fn lookup_field_ty(cx: ty::ctxt, items:[@ast::class_item],
+                   fieldname: ast::ident, sp: span)
+    -> ty::t {
+    for item in items {
+      // this is an access outside the class, so accessing a private
+      // field is an error
+        alt item.node.decl {
+          ast::instance_var(declname, t, _, _) if declname == fieldname {
+             alt item.node.privacy {
+                ast::priv {
+                    cx.sess.span_fatal(sp, "Accessed private field outside \
+                       its enclosing class");
+                }
+                ast::pub {
+                    ret ast_ty_to_ty(cx, m_check, t);
+                }
+             }
+          }
+          _ { /* do nothing */ }
+        }
+    }
+    cx.sess.span_fatal(sp, #fmt("Unbound field %s", fieldname));
+}
+
 fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
                               expr: @ast::expr,
                               proto: ast::proto,
@@ -2507,11 +2531,29 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
               _ {}
             }
           }
-          ty::ty_class(_id, _params) {
-              // TODO (classes)
-              tcx.sess.span_bug(expr.span,
-                  #fmt("can't check class field accesses yet: %s",
-                    ty_to_str(fcx.ccx.tcx, base_t)));
+          ty::ty_class(base_id, _params) {
+              // (1) verify that the class id actually has a field called
+              // field
+              // For now, this code assumes the class is defined in the local
+              // crate
+              // TODO: handle field references to classes in external crate
+              let err = "Class ID is not bound to a class";
+              let field_ty = alt fcx.ccx.tcx.items.find(base_id.node) {
+                      some(ast_map::node_item(i,_)) {
+                          alt i.node {
+                             ast::item_class(_, items, _, _, _) {
+                                 lookup_field_ty(fcx.ccx.tcx, items, field,
+                                    expr.span)
+                             }
+                             _ { fcx.ccx.tcx.sess.span_bug(expr.span, err); }
+                          }
+                      }
+                      _ { fcx.ccx.tcx.sess.span_bug(expr.span, err); }
+              };
+              // (2) look up what field's type is, and return it
+              // TODO: actually instantiate any type params
+              write_ty(tcx, id, field_ty);
+              handled = true;
           }
           _ {}
         }