about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/driver/driver.rs4
-rw-r--r--src/rustc/middle/astencode.rs16
-rw-r--r--src/rustc/middle/lang_items.rs24
-rw-r--r--src/rustc/middle/resolve3.rs113
-rw-r--r--src/rustc/middle/ty.rs24
-rw-r--r--src/rustc/middle/typeck/check.rs16
-rw-r--r--src/rustc/middle/typeck/check/method.rs3
7 files changed, 140 insertions, 60 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs
index 6c7d24973b9..ee0f28c9a0e 100644
--- a/src/rustc/driver/driver.rs
+++ b/src/rustc/driver/driver.rs
@@ -170,7 +170,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
                              session::sess_os_to_meta_os(sess.targ_cfg.os),
                              sess.opts.static));
 
-    time(time_passes, ~"language item collection", ||
+    let lang_items = time(time_passes, ~"language item collection", ||
          middle::lang_items::collect_language_items(crate, sess));
 
     let { def_map: def_map,
@@ -178,7 +178,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
           impl_map: impl_map,
           trait_map: trait_map } =
         time(time_passes, ~"resolution", ||
-             middle::resolve3::resolve_crate(sess, ast_map, crate));
+             middle::resolve3::resolve_crate(sess, lang_items, crate));
 
     let freevars = time(time_passes, ~"freevar finding", ||
         freevars::annotate_freevars(def_map, crate));
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index d47598cd8cb..84ada7726ab 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -13,6 +13,8 @@ import std::ebml;
 import std::ebml::writer;
 import std::ebml::serializer;
 import std::ebml::deserializer;
+import std::ebml::extensions;
+import std::ebml::get_doc;
 import std::map::hashmap;
 import std::serialization::serializer;
 import std::serialization::deserializer;
@@ -285,7 +287,7 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
 }
 
 fn decode_ast(par_doc: ebml::doc) -> ast::inlined_item {
-    let chi_doc = par_doc[c::tag_tree];
+    let chi_doc = par_doc[c::tag_tree as uint];
     let d = ebml::ebml_deserializer(chi_doc);
     ast::deserialize_inlined_item(d)
 }
@@ -776,15 +778,11 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
 
 trait doc_decoder_helpers {
     fn as_int() -> int;
-    fn [](tag: c::astencode_tag) -> ebml::doc;
     fn opt_child(tag: c::astencode_tag) -> option<ebml::doc>;
 }
 
 impl decoder of doc_decoder_helpers for ebml::doc {
     fn as_int() -> int { ebml::doc_as_u64(self) as int }
-    fn [](tag: c::astencode_tag) -> ebml::doc {
-        ebml::get_doc(self, tag as uint)
-    }
     fn opt_child(tag: c::astencode_tag) -> option<ebml::doc> {
         ebml::maybe_get_doc(self, tag as uint)
     }
@@ -843,9 +841,9 @@ impl decoder of ebml_deserializer_decoder_helpers
 fn decode_side_tables(xcx: extended_decode_ctxt,
                       ast_doc: ebml::doc) {
     let dcx = xcx.dcx;
-    let tbl_doc = ast_doc[c::tag_table];
+    let tbl_doc = ast_doc[c::tag_table as uint];
     for ebml::docs(tbl_doc) |tag, entry_doc| {
-        let id0 = entry_doc[c::tag_table_id].as_int();
+        let id0 = entry_doc[c::tag_table_id as uint].as_int();
         let id = xcx.tr_id(id0);
 
         #debug[">> Side table document with tag 0x%x \
@@ -855,7 +853,7 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
         if tag == (c::tag_table_mutbl as uint) {
             dcx.maps.mutbl_map.insert(id, ());
         } else {
-            let val_doc = entry_doc[c::tag_table_val];
+            let val_doc = entry_doc[c::tag_table_val as uint];
             let val_dsr = ebml::ebml_deserializer(val_doc);
             if tag == (c::tag_table_def as uint) {
                 let def = decode_def(xcx, val_doc);
@@ -916,7 +914,7 @@ fn encode_item_ast(ebml_w: ebml::writer, item: @ast::item) {
 
 #[cfg(test)]
 fn decode_item_ast(par_doc: ebml::doc) -> @ast::item {
-    let chi_doc = par_doc[c::tag_tree];
+    let chi_doc = par_doc[c::tag_tree as uint];
     let d = ebml::ebml_deserializer(chi_doc);
     @ast::deserialize_item(d)
 }
diff --git a/src/rustc/middle/lang_items.rs b/src/rustc/middle/lang_items.rs
index 2353da51f98..0aaacee019a 100644
--- a/src/rustc/middle/lang_items.rs
+++ b/src/rustc/middle/lang_items.rs
@@ -34,7 +34,11 @@ class LanguageItems {
     let mut div_trait: option<def_id>;
     let mut modulo_trait: option<def_id>;
     let mut neg_trait: option<def_id>;
-    let mut bitops_trait: option<def_id>;
+    let mut bitxor_trait: option<def_id>;
+    let mut bitand_trait: option<def_id>;
+    let mut bitor_trait: option<def_id>;
+    let mut shl_trait: option<def_id>;
+    let mut shr_trait: option<def_id>;
     let mut index_trait: option<def_id>;
 
     new() {
@@ -49,7 +53,11 @@ class LanguageItems {
         self.div_trait = none;
         self.modulo_trait = none;
         self.neg_trait = none;
-        self.bitops_trait = none;
+        self.bitxor_trait = none;
+        self.bitand_trait = none;
+        self.bitor_trait = none;
+        self.shl_trait = none;
+        self.shr_trait = none;
         self.index_trait = none;
     }
 }
@@ -84,7 +92,11 @@ class LanguageItemCollector {
         self.item_refs.insert(~"div", &mut self.items.div_trait);
         self.item_refs.insert(~"modulo", &mut self.items.modulo_trait);
         self.item_refs.insert(~"neg", &mut self.items.neg_trait);
-        self.item_refs.insert(~"bitops", &mut self.items.bitops_trait);
+        self.item_refs.insert(~"bitxor", &mut self.items.bitxor_trait);
+        self.item_refs.insert(~"bitand", &mut self.items.bitand_trait);
+        self.item_refs.insert(~"bitor", &mut self.items.bitor_trait);
+        self.item_refs.insert(~"shl", &mut self.items.shl_trait);
+        self.item_refs.insert(~"shr", &mut self.items.shr_trait);
         self.item_refs.insert(~"index", &mut self.items.index_trait);
     }
 
@@ -125,8 +137,8 @@ class LanguageItemCollector {
                     some(original_def_id)
                             if original_def_id != item_def_id => {
 
-                        self.session.warn(#fmt("duplicate entry for `%s`",
-                                               value));
+                        self.session.err(#fmt("duplicate entry for `%s`",
+                                              value));
                     }
                     some(_) | none => {
                         // OK.
@@ -184,7 +196,7 @@ class LanguageItemCollector {
         for self.item_refs.each |key, item_ref| {
             alt copy *item_ref {
                 none => {
-                    self.session.warn(#fmt("no item found for `%s`", key));
+                    self.session.err(#fmt("no item found for `%s`", key));
                 }
                 some(did) => {
                     // OK.
diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs
index 8af823ac072..8b40d8136ab 100644
--- a/src/rustc/middle/resolve3.rs
+++ b/src/rustc/middle/resolve3.rs
@@ -3,33 +3,38 @@ import metadata::csearch::{each_path, get_impls_for_mod};
 import metadata::csearch::{get_method_names_if_trait, lookup_defs};
 import metadata::cstore::find_use_stmt_cnum;
 import metadata::decoder::{def_like, dl_def, dl_field, dl_impl};
+import middle::lang_items::LanguageItems;
 import middle::lint::{deny, allow, forbid, level, unused_imports, warn};
-import syntax::ast::{_mod, arm, blk, bound_const, bound_copy, bound_trait};
-import syntax::ast::{bound_owned};
-import syntax::ast::{bound_send, capture_clause, class_ctor, class_dtor};
-import syntax::ast::{class_member, class_method, crate, crate_num, decl_item};
-import syntax::ast::{def, def_arg, def_binding, def_class, def_const, def_fn};
+import syntax::ast::{_mod, add, arm, bitand, bitor, bitxor, blk, bound_const};
+import syntax::ast::{bound_copy, bound_owned, bound_send, bound_trait};
+import syntax::ast::{capture_clause, class_ctor, class_dtor, class_member};
+import syntax::ast::{class_method, crate, crate_num, decl_item, def, def_arg};
+import syntax::ast::{def_binding, def_class, def_const, def_fn};
 import syntax::ast::{def_foreign_mod, def_id, def_local, def_mod};
 import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param,
                      def_typaram_binder};
 import syntax::ast::{def_upvar, def_use, def_variant, expr, expr_assign_op};
 import syntax::ast::{expr_binary, expr_cast, expr_field, expr_fn};
 import syntax::ast::{expr_fn_block, expr_index, expr_new, expr_path};
+import syntax::ast::{def_prim_ty, def_region, def_self, def_ty, def_ty_param};
+import syntax::ast::{def_upvar, def_use, def_variant, div, eq, expr};
+import syntax::ast::{expr_assign_op, expr_binary, expr_cast, expr_field};
+import syntax::ast::{expr_fn, expr_fn_block, expr_index, expr_new, expr_path};
 import syntax::ast::{expr_struct, expr_unary, fn_decl, foreign_item};
-import syntax::ast::{foreign_item_fn, ident, trait_ref, impure_fn};
+import syntax::ast::{foreign_item_fn, ge, gt, ident, trait_ref, impure_fn};
 import syntax::ast::{instance_var, item, item_class, item_const, item_enum};
 import syntax::ast::{item_fn, item_mac, item_foreign_mod, item_impl};
-import syntax::ast::{item_mod, item_trait, item_ty, local, local_crate};
-import syntax::ast::{method, node_id, pat, pat_enum, pat_ident};
-import syntax::ast::{path, prim_ty, pat_box, pat_uniq, pat_lit, pat_range};
-import syntax::ast::{pat_rec, pat_tup, pat_wild, stmt_decl};
-import syntax::ast::{ty, ty_bool, ty_char, ty_f, ty_f32, ty_f64};
-import syntax::ast::{ty_float, ty_i, ty_i16, ty_i32, ty_i64, ty_i8, ty_int};
-import syntax::ast::{ty_param, ty_path, ty_str, ty_u, ty_u16, ty_u32, ty_u64};
-import syntax::ast::{ty_u8, ty_uint, variant, view_item, view_item_export};
-import syntax::ast::{view_item_import, view_item_use, view_path_glob};
-import syntax::ast::{view_path_list, view_path_simple};
-import syntax::ast::{required, provided};
+import syntax::ast::{item_mod, item_trait, item_ty, le, local, local_crate};
+import syntax::ast::{lt, method, mul, ne, neg, node_id, pat, pat_enum};
+import syntax::ast::{pat_ident, path, prim_ty, pat_box, pat_uniq, pat_lit};
+import syntax::ast::{pat_range, pat_rec, pat_tup, pat_wild, provided};
+import syntax::ast::{required, rem, shl, stmt_decl, subtract, ty, ty_bool};
+import syntax::ast::{ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i, ty_i16};
+import syntax::ast::{ty_i32, ty_i64, ty_i8, ty_int, ty_param, ty_path};
+import syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
+import syntax::ast::{variant, view_item, view_item_export, view_item_import};
+import syntax::ast::{view_item_use, view_path_glob, view_path_list};
+import syntax::ast::{view_path_simple};
 import syntax::ast_util::{def_id_of_def, dummy_sp, local_def, new_def_hash};
 import syntax::ast_util::{walk_pat};
 import syntax::attr::{attr_metas, contains_name};
@@ -47,8 +52,7 @@ import str::{connect, split_str};
 import vec::pop;
 
 import std::list::{cons, list, nil};
-import std::map::{hashmap, int_hash};
-import ASTMap = syntax::ast_map::map;
+import std::map::{hashmap, int_hash, str_hash};
 import str_eq = str::eq;
 
 // Definition mapping
@@ -608,7 +612,7 @@ class PrimitiveTypeTable {
 /// The main resolver class.
 class Resolver {
     let session: session;
-    let ast_map: ASTMap;
+    let lang_items: LanguageItems;
     let crate: @crate;
 
     let atom_table: @AtomTable;
@@ -655,9 +659,9 @@ class Resolver {
     let export_map: ExportMap;
     let trait_map: TraitMap;
 
-    new(session: session, ast_map: ASTMap, crate: @crate) {
+    new(session: session, lang_items: LanguageItems, crate: @crate) {
         self.session = session;
-        self.ast_map = ast_map;
+        self.lang_items = copy lang_items;
         self.crate = crate;
 
         self.atom_table = @AtomTable();
@@ -4312,16 +4316,61 @@ class Resolver {
 
     fn record_candidate_traits_for_expr_if_necessary(expr: @expr) {
         alt expr.node {
-            expr_field(_, ident, _) {
+            expr_field(_, ident, _) => {
                 let atom = (*self.atom_table).intern(ident);
                 let traits = self.search_for_traits_containing_method(atom);
                 self.trait_map.insert(expr.id, traits);
             }
-            _ {
+            expr_binary(add, _, _) | expr_assign_op(add, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.add_trait);
+            }
+            expr_binary(subtract, _, _) | expr_assign_op(subtract, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.sub_trait);
+            }
+            expr_binary(mul, _, _) | expr_assign_op(mul, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.mul_trait);
+            }
+            expr_binary(div, _, _) | expr_assign_op(div, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.div_trait);
+            }
+            expr_binary(rem, _, _) | expr_assign_op(rem, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.modulo_trait);
+            }
+            expr_binary(bitxor, _, _) | expr_assign_op(bitxor, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.bitxor_trait);
+            }
+            expr_binary(bitand, _, _) | expr_assign_op(bitand, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.bitand_trait);
+            }
+            expr_binary(bitor, _, _) | expr_assign_op(bitor, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.bitor_trait);
+            }
+            expr_binary(shl, _, _) | expr_assign_op(shl, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.shl_trait);
+            }
+            expr_binary(shr, _, _) | expr_assign_op(shr, _, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.shr_trait);
+            }
+            expr_unary(neg, _) => {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.neg_trait);
+            }
+            expr_index(*) {
+                self.add_fixed_trait_for_expr(expr.id,
+                                              self.lang_items.index_trait);
+            }
+            _ => {
                 // Nothing to do.
-                //
-                // XXX: Handle more here... operator overloading, placement
-                // new, etc.
             }
         }
     }
@@ -4414,6 +4463,12 @@ class Resolver {
         }
     }
 
+    fn add_fixed_trait_for_expr(expr_id: node_id, +trait_id: option<def_id>) {
+        let traits = @dvec();
+        traits.push(trait_id.get());
+        self.trait_map.insert(expr_id, traits);
+    }
+
     fn record_def(node_id: node_id, def: def) {
         #debug("(recording def) recording %? for %?", def, node_id);
         self.def_map.insert(node_id, def);
@@ -4622,13 +4677,13 @@ class Resolver {
 }
 
 /// Entry point to crate resolution.
-fn resolve_crate(session: session, ast_map: ASTMap, crate: @crate)
+fn resolve_crate(session: session, lang_items: LanguageItems, crate: @crate)
               -> { def_map: DefMap,
                    exp_map: ExportMap,
                    impl_map: ImplMap,
                    trait_map: TraitMap } {
 
-    let resolver = @Resolver(session, ast_map, crate);
+    let resolver = @Resolver(session, lang_items, crate);
     (*resolver).resolve(resolver);
     ret {
         def_map: resolver.def_map,
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index d99e35ce418..891bbca5d19 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -1472,6 +1472,30 @@ impl operators for kind {
     }
 }
 
+impl operators of ops::bitand<kind,kind> for kind {
+    pure fn bitand(other: kind) -> kind {
+        unchecked {
+            lower_kind(self, other)
+        }
+    }
+}
+
+impl operators of ops::bitor<kind,kind> for kind {
+    pure fn bitor(other: kind) -> kind {
+        unchecked {
+            raise_kind(self, other)
+        }
+    }
+}
+
+impl operators of ops::sub<kind,kind> for kind {
+    pure fn sub(other: kind) -> kind {
+        unchecked {
+            kind_(*self & !*other)
+        }
+    }
+}
+
 // Using these query functions is preferable to direct comparison or matching
 // against the kind constants, as we may modify the kind hierarchy in the
 // future.
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index ce7536b5bf9..d472991d85f 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -961,14 +961,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         ret if_bot;
     }
 
-    fn binop_method(op: ast::binop) -> option<~str> {
-        alt op {
-          ast::add | ast::subtract | ast::mul | ast::div | ast::rem |
-          ast::bitxor | ast::bitand | ast::bitor | ast::shl | ast::shr
-          { some(ast_util::binop_to_str(op)) }
-          _ { none }
-        }
-    }
     fn lookup_op_method(fcx: @fn_ctxt, op_ex: @ast::expr,
                         self_ex: @ast::expr, self_t: ty::t,
                         opname: ~str, args: ~[@ast::expr])
@@ -1041,7 +1033,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                         lhs_expr: @ast::expr, lhs_resolved_t: ty::t,
                         op: ast::binop, rhs: @ast::expr) -> (ty::t, bool) {
         let tcx = fcx.ccx.tcx;
-        alt binop_method(op) {
+        alt ast_util::binop_to_method_name(op) {
           some(name) {
             alt lookup_op_method(fcx, ex,
                                  lhs_expr, lhs_resolved_t,
@@ -1365,7 +1357,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
             oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t);
             if !(ty::type_is_integral(oprnd_t) ||
                  ty::get(oprnd_t).struct == ty::ty_bool) {
-                oprnd_t = check_user_unop(fcx, ~"!", ~"!", expr,
+                oprnd_t = check_user_unop(fcx, ~"!", ~"not", expr,
                                          oprnd, oprnd_t);
             }
           }
@@ -1373,7 +1365,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
             oprnd_t = structurally_resolved_type(fcx, oprnd.span, oprnd_t);
             if !(ty::type_is_integral(oprnd_t) ||
                  ty::type_is_fp(oprnd_t)) {
-                oprnd_t = check_user_unop(fcx, ~"-", ~"unary-", expr,
+                oprnd_t = check_user_unop(fcx, ~"-", ~"neg", expr,
                                          oprnd, oprnd_t);
             }
           }
@@ -1831,7 +1823,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
           none {
             let resolved = structurally_resolved_type(fcx, expr.span,
                                                       raw_base_t);
-            alt lookup_op_method(fcx, expr, base, resolved, ~"[]",
+            alt lookup_op_method(fcx, expr, base, resolved, ~"index",
                                  ~[idx]) {
               some((ret_ty, _)) { fcx.write_ty(id, ret_ty); }
               _ {
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index 7f269944059..a9ecf5e092e 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -447,8 +447,7 @@ class lookup {
         // Add trait methods.
         alt self.fcx.ccx.trait_map.find(self.expr.id) {
             none {
-                // XXX: This particular operation is not yet trait-ified;
-                // leave it alone for now.
+                // Should only happen for placement new right now.
             }
             some(trait_ids) {
                 for (*trait_ids).each |trait_id| {