about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-10-23 19:18:18 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-10-24 10:54:09 -0700
commit4da58a5bd6f921b446e46cf65790975598289308 (patch)
tree3e0de65d3b2b901ebf2ca5adaa587036fcbbc336 /src/rustc
parent61bb3571a59f4659a0a46565c71fa7ecfa352811 (diff)
rustc: Implement typechecking for tuple structs. r=nmatsakis
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/middle/resolve.rs21
-rw-r--r--src/rustc/middle/typeck/collect.rs34
2 files changed, 49 insertions, 6 deletions
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs
index efddd6f4471..1f7b3b1c861 100644
--- a/src/rustc/middle/resolve.rs
+++ b/src/rustc/middle/resolve.rs
@@ -9,8 +9,7 @@ use middle::pat_util::{pat_bindings};
 use syntax::ast::{_mod, add, arm};
 use syntax::ast::{bind_by_ref, bind_by_implicit_ref, bind_by_value};
 use syntax::ast::{bitand, bitor, bitxor};
-use syntax::ast::{binding_mode, blk,
-                     capture_clause, class_ctor, class_dtor};
+use syntax::ast::{binding_mode, blk, capture_clause, class_ctor, class_dtor};
 use syntax::ast::{crate, crate_num, decl_item};
 use syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn};
 use syntax::ast::{def_foreign_mod, def_id, def_label, def_local, def_mod};
@@ -39,7 +38,7 @@ use syntax::ast::{trait_ref, tuple_variant_kind, Ty, ty_bool, ty_char};
 use syntax::ast::{ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16, ty_i32};
 use syntax::ast::{ty_i64, ty_i8, ty_int, ty_param, ty_path, ty_str, ty_u};
 use syntax::ast::{ty_u16, ty_u32, ty_u64, ty_u8, ty_uint, type_value_ns};
-use syntax::ast::{ty_param_bound};
+use syntax::ast::{ty_param_bound, unnamed_field};
 use syntax::ast::{variant, view_item, view_item_export, view_item_import};
 use syntax::ast::{view_item_use, view_path_glob, view_path_list};
 use syntax::ast::{view_path_simple, visibility, anonymous, named};
@@ -1179,12 +1178,22 @@ impl Resolver {
             }
 
             // These items live in both the type and value namespaces.
-            item_class(*) => {
+            item_class(struct_def, _) => {
                 let (name_bindings, new_parent) =
                     self.add_child(ident, parent, ForbidDuplicateTypes, sp);
 
-                (*name_bindings).define_type
-                    (privacy, def_ty(local_def(item.id)), sp);
+                name_bindings.define_type(
+                    privacy, def_ty(local_def(item.id)), sp);
+
+                // If this struct is tuple-like or enum-like, define a name
+                // in the value namespace.
+                if struct_def.fields.len() == 0 ||
+                        struct_def.fields[0].node.kind == unnamed_field {
+                    name_bindings.define_value(
+                        privacy,
+                        def_class(local_def(struct_def.ctor_id)),
+                        sp);
+                }
 
                 // Record the def ID of this struct.
                 self.structs.insert(local_def(item.id), ());
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index 1660f1e076c..c8dcde52ebb 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -22,6 +22,7 @@ are represented as `ty_param()` instances.
 
 use astconv::{ast_conv, ty_of_fn_decl, ty_of_arg, ast_ty_to_ty};
 use ast_util::trait_method_to_ty_method;
+use middle::ty::{FnMeta, FnSig, FnTyBase};
 use rscope::*;
 use ty::{FnTyBase, FnMeta, FnSig, InstantiatedTraitRef};
 use util::common::pluralize;
@@ -559,6 +560,39 @@ fn convert_struct(ccx: @crate_ctxt,
         write_ty_to_tcx(tcx, trait_ref.impl_id, tpt.ty);
         tcx.tcache.insert(local_def(trait_ref.impl_id), tpt);
     }
+
+    // If this struct is enum-like or tuple-like, create the type of its
+    // constructor.
+    if struct_def.fields.len() == 0 {
+        // Enum-like.
+        write_ty_to_tcx(tcx, struct_def.ctor_id, selfty);
+        tcx.tcache.insert(local_def(struct_def.ctor_id), tpt);
+    } else if struct_def.fields[0].node.kind == ast::unnamed_field {
+        // Tuple-like.
+        let ctor_fn_ty = ty::mk_fn(tcx, FnTyBase {
+            meta: FnMeta {
+                purity: ast::pure_fn,
+                proto: ty::proto_bare,
+                bounds: @~[],
+                ret_style: ast::return_val,
+            },
+            sig: FnSig {
+                inputs: do struct_def.fields.map |field| {
+                    {
+                        mode: ast::expl(ast::by_copy),
+                        ty: ccx.tcx.tcache.get(local_def(field.node.id)).ty
+                    }
+                },
+                output: selfty
+            }
+        });
+        write_ty_to_tcx(tcx, struct_def.ctor_id, ctor_fn_ty);
+        tcx.tcache.insert(local_def(struct_def.ctor_id), {
+            bounds: tpt.bounds,
+            region_param: tpt.region_param,
+            ty: ctor_fn_ty
+        });
+    }
 }
 
 fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {