From aa67deff3303a14fa43e5e4693338c0b9f409e9d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 26 Mar 2013 06:05:40 -0400 Subject: [PATCH 1/3] remove sty_by_ref, though traces still remain due to dtors --- src/librustc/metadata/decoder.rs | 1 - src/librustc/metadata/encoder.rs | 3 --- src/librustc/middle/borrowck/gather_loans.rs | 15 ------------ src/librustc/middle/liveness.rs | 5 ---- src/librustc/middle/moves.rs | 15 +----------- src/librustc/middle/resolve.rs | 3 +-- src/librustc/middle/trans/meth.rs | 17 +------------ src/librustc/middle/typeck/check/method.rs | 8 +++---- src/libsyntax/ast.rs | 1 - src/libsyntax/ext/deriving/clone.rs | 2 +- src/libsyntax/ext/deriving/eq.rs | 2 +- src/libsyntax/ext/deriving/iter_bytes.rs | 2 +- src/libsyntax/ext/deriving/mod.rs | 2 +- src/libsyntax/parse/parser.rs | 25 ++++---------------- src/libsyntax/print/pprust.rs | 5 ++-- 15 files changed, 18 insertions(+), 88 deletions(-) diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 14b455651a571..010ba4d252291 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -630,7 +630,6 @@ fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ { let self_ty_kind = string[0]; match self_ty_kind as char { 's' => { return ast::sty_static; } - 'r' => { return ast::sty_by_ref; } 'v' => { return ast::sty_value; } '@' => { return ast::sty_box(get_mutability(string[1])); } '~' => { return ast::sty_uniq(get_mutability(string[1])); } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 490fa357bb537..419fe98f3d524 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -410,9 +410,6 @@ fn encode_self_type(ebml_w: writer::Encoder, self_type: ast::self_ty_) { sty_static => { ebml_w.writer.write(&[ 's' as u8 ]); } - sty_by_ref => { - ebml_w.writer.write(&[ 'r' as u8 ]); - } sty_value => { ebml_w.writer.write(&[ 'v' as u8 ]); } diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index bd6a9ab30976d..d18aa1c12dfae 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -180,21 +180,6 @@ fn req_loans_in_expr(ex: @ast::expr, } } - match self.bccx.method_map.find(&ex.id) { - Some(ref method_map_entry) => { - match (*method_map_entry).explicit_self { - ast::sty_by_ref => { - let rcvr_cmt = self.bccx.cat_expr(rcvr); - self.guarantee_valid(rcvr_cmt, m_imm, scope_r); - } - _ => {} // Nothing to do. - } - } - None => { - self.tcx().sess.span_bug(ex.span, ~"no method map entry"); - } - } - visit::visit_expr(ex, self, vt); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index a92234ba1298e..15fc4317bf3a8 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -467,11 +467,6 @@ fn visit_fn(fk: &visit::fn_kind, match *fk { fk_method(_, _, method) => { match method.self_ty.node { - sty_by_ref => { - fn_maps.add_variable(Arg(method.self_id, - special_idents::self_, - by_ref)); - } sty_value | sty_region(*) | sty_box(_) | sty_uniq(_) => { fn_maps.add_variable(Arg(method.self_id, special_idents::self_, diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 16f133b8794d8..d97ec6b99051d 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -737,20 +737,7 @@ pub impl VisitContext { receiver_expr: @expr, visitor: vt) { - let callee_mode = match self.method_map.find(&expr_id) { - Some(ref method_map_entry) => { - match method_map_entry.explicit_self { - sty_by_ref => by_ref, - _ => by_copy - } - } - None => { - self.tcx.sess.span_bug( - span, - ~"no method map entry"); - } - }; - self.use_fn_arg(callee_mode, receiver_expr, visitor); + self.use_fn_arg(by_copy, receiver_expr, visitor); } fn use_fn_args(&self, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index afc2c9f3352d3..66dc1a37e514a 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -50,7 +50,7 @@ use syntax::ast::{named_field, ne, neg, node_id, pat, pat_enum, pat_ident}; use syntax::ast::{path, pat_box, pat_lit, pat_range, pat_struct}; use syntax::ast::{pat_tup, pat_uniq, pat_wild, prim_ty, private, provided}; use syntax::ast::{public, required, rem, self_ty_, shl, shr, stmt_decl}; -use syntax::ast::{struct_dtor, struct_field, struct_variant_kind, sty_by_ref}; +use syntax::ast::{struct_dtor, struct_field, struct_variant_kind}; use syntax::ast::{sty_static, subtract, trait_ref, tuple_variant_kind, Ty}; use syntax::ast::{ty_bool, ty_char, ty_f, ty_f32, ty_f64, ty_float, ty_i}; use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, TyParam, ty_path}; @@ -3792,7 +3792,6 @@ pub impl Resolver { // we only have self ty if it is a non static method let self_binding = match method.self_ty.node { sty_static => { NoSelfBinding } - sty_by_ref => { HasSelfBinding(method.self_id, true) } _ => { HasSelfBinding(method.self_id, false) } }; diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 1f348bc3e24df..c37702e8d2b09 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -596,7 +596,7 @@ pub fn trans_trait_callee(bcx: block, let llpair = match explicit_self { ast::sty_region(*) => Load(bcx, llpair), - ast::sty_static | ast::sty_by_ref | ast::sty_value | + ast::sty_static | ast::sty_value | ast::sty_box(_) | ast::sty_uniq(_) => llpair }; @@ -645,21 +645,6 @@ pub fn trans_trait_callee_from_llval(bcx: block, ast::sty_static => { bcx.tcx().sess.bug(~"shouldn't see static method here"); } - ast::sty_by_ref => { - // We need to pass a pointer to a pointer to the payload. - match store { - ty::BoxTraitStore | - ty::BareTraitStore | - ty::UniqTraitStore => { - llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); - } - ty::RegionTraitStore(_) => { - llself = llbox; - } - } - - self_mode = ast::by_ref; - } ast::sty_value => { bcx.tcx().sess.bug(~"methods with by-value self should not be \ called on objects"); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index aefd95ab78726..320f0206fb871 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -99,7 +99,7 @@ use core::hashmap::linear::LinearSet; use core::result; use core::uint; use core::vec; -use syntax::ast::{def_id, sty_by_ref, sty_value, sty_region, sty_box}; +use syntax::ast::{def_id, sty_value, sty_region, sty_box}; use syntax::ast::{sty_uniq, sty_static, node_id, by_copy, by_ref}; use syntax::ast::{m_const, m_mutbl, m_imm}; use syntax::ast; @@ -527,7 +527,7 @@ pub impl<'self> LookupContext<'self> { ast::sty_region(_) => { return; // inapplicable } - ast::sty_by_ref | ast::sty_region(_) => vstore_slice(r) + ast::sty_region(_) => vstore_slice(r) ast::sty_box(_) => vstore_box, // XXX NDM mutability ast::sty_uniq(_) => vstore_uniq } @@ -741,7 +741,7 @@ pub impl<'self> LookupContext<'self> { // shouldn't really have to be. let rcvr_substs = { match self_decl { - sty_static | sty_value | sty_by_ref | + sty_static | sty_value | sty_box(_) | sty_uniq(_) => { self_substs } @@ -1327,7 +1327,7 @@ pub fn transform_self_type_for_method(tcx: ty::ctxt, tcx.sess.bug(~"calling transform_self_type_for_method on \ static method"); } - sty_by_ref | sty_value => { + sty_value => { impl_ty } sty_region(_, mutability) => { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 6071cc643a367..8fa062d4980da 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1003,7 +1003,6 @@ impl to_bytes::IterBytes for ret_style { #[deriving(Eq)] pub enum self_ty_ { sty_static, // no self - sty_by_ref, // `` sty_value, // `self` sty_region(Option<@Lifetime>, mutability), // `&'lt self` sty_box(mutability), // `@self` diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs index 68458bd516eed..df4dd2735fcd1 100644 --- a/src/libsyntax/ext/deriving/clone.rs +++ b/src/libsyntax/ext/deriving/clone.rs @@ -17,7 +17,7 @@ use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; use ast::{stmt, struct_def, struct_variant_kind}; -use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; use ext::build; diff --git a/src/libsyntax/ext/deriving/eq.rs b/src/libsyntax/ext/deriving/eq.rs index 8cee6bd7290b4..531390035db81 100644 --- a/src/libsyntax/ext/deriving/eq.rs +++ b/src/libsyntax/ext/deriving/eq.rs @@ -17,7 +17,7 @@ use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; use ast::{stmt, struct_def, struct_variant_kind}; -use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; use ext::build; diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 3c1ee7e029644..528db0d10721d 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -17,7 +17,7 @@ use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; use ast::{stmt, struct_def, struct_variant_kind}; -use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; use ext::build; diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index e879bcdc4764f..21477d6e0675e 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -20,7 +20,7 @@ use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; use ast::{stmt, struct_def, struct_variant_kind}; -use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; +use ast::{sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; use ext::build; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 53d618e3340a5..5d907c10984de 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -46,7 +46,7 @@ use ast::{rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; -use ast::{sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, sty_value}; +use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value}; use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok}; use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box}; use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn}; @@ -471,8 +471,6 @@ pub impl Parser { ) |p| { let attrs = p.parse_outer_attributes(); let lo = p.span.lo; - let is_static = p.parse_staticness(); - let static_sty = spanned(lo, p.span.hi, sty_static); let vis = p.parse_visibility(); let pur = p.parse_fn_purity(); @@ -487,12 +485,6 @@ pub impl Parser { // names to be left off if there is a definition... either::Left(p.parse_arg_general(false)) }; - // XXX: Wrong. Shouldn't allow both static and self_ty - let self_ty = if is_static || self_ty.node == sty_by_ref { - static_sty - } else { - self_ty - }; let hi = p.last_span.hi; debug!("parse_trait_methods(): trait method signature ends in \ @@ -2877,7 +2869,7 @@ pub impl Parser { p.expect_self_ident(); cnstr(mutability) } else { - sty_by_ref + sty_static } } @@ -2926,7 +2918,7 @@ pub impl Parser { self.expect_self_ident(); sty_region(Some(lifetime), mutability) } else { - sty_by_ref + sty_static } } @@ -2950,13 +2942,13 @@ pub impl Parser { sty_value } _ => { - sty_by_ref + sty_static } }; // If we parsed a self type, expect a comma before the argument list. let args_or_capture_items; - if self_ty != sty_by_ref { + if self_ty != sty_static { match *self.token { token::COMMA => { self.bump(); @@ -3058,7 +3050,6 @@ pub impl Parser { let attrs = self.parse_outer_attributes(); let lo = self.span.lo; - let is_static = self.parse_staticness(); let static_sty = spanned(lo, self.span.hi, sty_static); let visa = self.parse_visibility(); @@ -3068,12 +3059,6 @@ pub impl Parser { let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| { p.parse_arg() }; - // XXX: interaction between staticness, self_ty is broken now - let self_ty = if is_static || self_ty.node == sty_by_ref { - static_sty - } else { - self_ty - }; let (inner_attrs, body) = self.parse_inner_attrs_and_block(true); let hi = body.span.hi; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 9a9834c488b19..a592319de0ed8 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1643,7 +1643,7 @@ pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) { // Returns whether it printed anything pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool { match self_ty { - ast::sty_static | ast::sty_by_ref => { return false; } + ast::sty_static => { return false; } ast::sty_value => { word(s.s, ~"self"); } ast::sty_region(lt, m) => { word(s.s, ~"&"); @@ -1669,7 +1669,7 @@ pub fn print_fn(s: @ps, opt_self_ty: Option, vis: ast::visibility) { head(s, ~""); - print_fn_header_info(s, opt_self_ty, purity, ast::Many, None, vis); + print_fn_header_info(s, purity, ast::Many, None, vis); nbsp(s); print_ident(s, name); print_generics(s, generics); @@ -2175,7 +2175,6 @@ pub fn print_opt_sigil(s: @ps, opt_sigil: Option) { } pub fn print_fn_header_info(s: @ps, - opt_sty: Option, purity: ast::purity, onceness: ast::Onceness, opt_sigil: Option, From 2c17ff7dbc667a7d579b02b86d4c08a1093683fd Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 26 Mar 2013 12:50:49 -0400 Subject: [PATCH 2/3] Simplify and remove unnecessary use of ast_map --- src/librustc/middle/typeck/check/mod.rs | 39 +------------------------ src/libsyntax/parse/parser.rs | 2 -- 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 75c6bfd5d6405..d568773f90f81 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1064,44 +1064,7 @@ pub fn impl_self_ty(vcx: &VtableContext, -> ty_param_substs_and_ty { let tcx = vcx.tcx(); - let (n_tps, region_param, raw_ty) = if did.crate == ast::local_crate { - let region_param = tcx.region_paramd_items.find(&did.node). - map_consume(|x| *x); - match tcx.items.find(&did.node) { - Some(&ast_map::node_item(@ast::item { - node: ast::item_impl(ref ts, _, st, _), - _ - }, _)) => { - let region_parameterization = - RegionParameterization::from_variance_and_generics( - region_param, - ts); - (ts.ty_params.len(), - region_param, - vcx.ccx.to_ty(&rscope::type_rscope(region_parameterization), st)) - } - Some(&ast_map::node_item(@ast::item { - node: ast::item_struct(_, ref ts), - id: class_id, - _ - },_)) => { - /* If the impl is a class, the self ty is just the class ty - (doing a no-op subst for the ty params; in the next step, - we substitute in fresh vars for them) - */ - (ts.ty_params.len(), - region_param, - ty::mk_struct(tcx, local_def(class_id), - substs { - self_r: rscope::bound_self_region(region_param), - self_ty: None, - tps: ty::ty_params_to_tys(tcx, ts) - })) - } - _ => { tcx.sess.bug(~"impl_self_ty: unbound item or item that \ - doesn't have a self_ty"); } - } - } else { + let (n_tps, region_param, raw_ty) = { let ity = ty::lookup_item_type(tcx, did); (vec::len(*ity.bounds), ity.region_param, ity.ty) }; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5d907c10984de..34fe1764a0719 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3050,8 +3050,6 @@ pub impl Parser { let attrs = self.parse_outer_attributes(); let lo = self.span.lo; - let static_sty = spanned(lo, self.span.hi, sty_static); - let visa = self.parse_visibility(); let pur = self.parse_fn_purity(); let ident = self.parse_ident(); From 069529bc5cc14f63035609cdfae5b21ca7999d4b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 26 Mar 2013 15:04:30 -0400 Subject: [PATCH 3/3] Autoref the argument to the index operator (#4920) --- src/libcore/ops.rs | 2 +- src/librustc/middle/astencode.rs | 10 ++-- src/librustc/middle/moves.rs | 28 +++------- src/librustc/middle/trans/expr.rs | 16 +++--- src/librustc/middle/typeck/check/mod.rs | 4 +- src/libstd/bitv.rs | 10 ++-- src/libstd/ebml.rs | 8 ++- src/test/run-pass/operator-overloading.rs | 4 +- src/test/run-pass/overload-index-operator.rs | 55 ++++++++++++++++++++ 9 files changed, 88 insertions(+), 49 deletions(-) create mode 100644 src/test/run-pass/overload-index-operator.rs diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 2f7fe1e4aa8bf..d0623ef604076 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -77,5 +77,5 @@ pub trait Shr { #[lang="index"] pub trait Index { - fn index(&self, index: Index) -> Result; + fn index(&self, index: &Index) -> Result; } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 1e1dde3303788..2ec5b59b9c551 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -342,7 +342,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 as uint]; + let chi_doc = par_doc.get(c::tag_tree as uint); let d = &reader::Decoder(chi_doc); Decodable::decode(d) } @@ -1089,9 +1089,9 @@ impl ebml_decoder_decoder_helpers for reader::Decoder { fn decode_side_tables(xcx: @ExtendedDecodeContext, ast_doc: ebml::Doc) { let dcx = xcx.dcx; - let tbl_doc = ast_doc[c::tag_table as uint]; + let tbl_doc = ast_doc.get(c::tag_table as uint); for reader::docs(tbl_doc) |tag, entry_doc| { - let id0 = entry_doc[c::tag_table_id as uint].as_int(); + let id0 = entry_doc.get(c::tag_table_id as uint).as_int(); let id = xcx.tr_id(id0); debug!(">> Side table document with tag 0x%x \ @@ -1103,7 +1103,7 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext, } else if tag == (c::tag_table_moves_map as uint) { dcx.maps.moves_map.insert(id); } else { - let val_doc = entry_doc[c::tag_table_val as uint]; + let val_doc = entry_doc.get(c::tag_table_val as uint); let val_dsr = &reader::Decoder(val_doc); if tag == (c::tag_table_def as uint) { let def = decode_def(xcx, val_doc); @@ -1172,7 +1172,7 @@ fn encode_item_ast(ebml_w: writer::Encoder, item: @ast::item) { #[cfg(test)] fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item { - let chi_doc = par_doc[c::tag_tree as uint]; + let chi_doc = par_doc.get(c::tag_tree as uint); let d = &reader::Decoder(chi_doc); @Decodable::decode(d) } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index d97ec6b99051d..f5382d69174d0 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -436,7 +436,7 @@ pub impl VisitContext { expr_unary(deref, base) => { // *base if !self.use_overloaded_operator( - expr, DontDerefArgs, base, [], visitor) + expr, base, [], visitor) { // Moving out of *base moves out of base. self.use_expr(base, comp_mode, visitor); @@ -450,7 +450,7 @@ pub impl VisitContext { expr_index(lhs, rhs) => { // lhs[rhs] if !self.use_overloaded_operator( - expr, DontDerefArgs, lhs, [rhs], visitor) + expr, lhs, [rhs], visitor) { self.use_expr(lhs, comp_mode, visitor); self.consume_expr(rhs, visitor); @@ -579,7 +579,7 @@ pub impl VisitContext { expr_unary(_, lhs) => { if !self.use_overloaded_operator( - expr, DontDerefArgs, lhs, [], visitor) + expr, lhs, [], visitor) { self.consume_expr(lhs, visitor); } @@ -587,7 +587,7 @@ pub impl VisitContext { expr_binary(_, lhs, rhs) => { if !self.use_overloaded_operator( - expr, DoDerefArgs, lhs, [rhs], visitor) + expr, lhs, [rhs], visitor) { self.consume_expr(lhs, visitor); self.consume_expr(rhs, visitor); @@ -659,7 +659,6 @@ pub impl VisitContext { fn use_overloaded_operator(&self, expr: @expr, - deref_args: DerefArgs, receiver_expr: @expr, arg_exprs: &[@expr], visitor: vt) -> bool @@ -670,21 +669,10 @@ pub impl VisitContext { self.use_receiver(expr.id, expr.span, receiver_expr, visitor); - // The deref_args stuff should eventually be converted into - // adjustments. Moreover, it should eventually be applied - // consistently to all overloaded operators. But that's not - // how it is today. - match deref_args { - DoDerefArgs => { - // we are always passing in a borrowed pointer, - // so it's always read mode: - for arg_exprs.each |arg_expr| { - self.use_expr(*arg_expr, Read, visitor); - } - } - DontDerefArgs => { - self.use_fn_args(expr.callee_id, arg_exprs, visitor); - } + // for overloaded operatrs, we are always passing in a + // borrowed pointer, so it's always read mode: + for arg_exprs.each |arg_expr| { + self.use_expr(*arg_expr, Read, visitor); } return true; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 33576a682a7f1..0da1a9acef212 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -766,18 +766,15 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, } ast::expr_binary(_, lhs, rhs) => { // if not overloaded, would be RvalueDatumExpr - return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest, - DoAutorefArg); + return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest); } ast::expr_unary(_, subexpr) => { // if not overloaded, would be RvalueDatumExpr - return trans_overloaded_op(bcx, expr, subexpr, ~[], dest, - DontAutorefArg); + return trans_overloaded_op(bcx, expr, subexpr, ~[], dest); } ast::expr_index(base, idx) => { // if not overloaded, would be RvalueDatumExpr - return trans_overloaded_op(bcx, expr, base, ~[idx], dest, - DontAutorefArg); + return trans_overloaded_op(bcx, expr, base, ~[idx], dest); } ast::expr_cast(val, _) => { match ty::get(node_id_type(bcx, expr.id)).sty { @@ -1644,8 +1641,7 @@ fn trans_overloaded_op(bcx: block, expr: @ast::expr, rcvr: @ast::expr, +args: ~[@ast::expr], - dest: Dest, - +autoref_arg: AutorefArg) -> block + dest: Dest) -> block { let origin = *bcx.ccx().maps.method_map.get(&expr.id); let fty = node_id_type(bcx, expr.callee_id); @@ -1653,7 +1649,7 @@ fn trans_overloaded_op(bcx: block, bcx, expr.info(), fty, expr_ty(bcx, expr), |bcx| meth::trans_method_callee(bcx, expr.callee_id, rcvr, origin), - callee::ArgExprs(args), dest, autoref_arg); + callee::ArgExprs(args), dest, DoAutorefArg); } fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, @@ -1806,7 +1802,7 @@ fn trans_assign_op(bcx: block, // FIXME(#2528) evaluates the receiver twice!! let scratch = scratch_datum(bcx, dst_datum.ty, false); let bcx = trans_overloaded_op(bcx, expr, dst, ~[src], - SaveIn(scratch.val), DoAutorefArg); + SaveIn(scratch.val)); return scratch.move_to_datum(bcx, DROP_EXISTING, dst_datum); } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index d568773f90f81..732026a3033a0 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1549,7 +1549,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, lookup_op_method( fcx, ex, rhs_expr, rhs_t, fcx.tcx().sess.ident_of(mname), ~[], - DontDerefArgs, DontAutoderefReceiver, + DoDerefArgs, DontAutoderefReceiver, || { fcx.type_error_message(ex.span, |actual| { fmt!("cannot apply unary operator `%s` to type `%s`", @@ -2757,7 +2757,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, expr.span, raw_base_t); let ret_ty = lookup_op_method(fcx, expr, base, resolved, tcx.sess.ident_of(~"index"), - ~[idx], DontDerefArgs, AutoderefReceiver, + ~[idx], DoDerefArgs, AutoderefReceiver, || { fcx.type_error_message(expr.span, |actual| fmt!("cannot index a value \ diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index 3acc95a3aad62..8bac0fed3c925 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -437,7 +437,8 @@ pub impl Bitv { if offset >= bitv.nbits { 0 } else { - bitv[offset] as u8 << (7 - bit) + // NOTE cannot use bitv[offset] until snapshot + bitv.index(&offset) as u8 << (7 - bit) } } @@ -459,7 +460,8 @@ pub impl Bitv { * Transform self into a [bool] by turning each bit into a bool */ fn to_bools(&self) -> ~[bool] { - vec::from_fn(self.nbits, |i| self[i]) + // NOTE cannot use self[i] until snapshot + vec::from_fn(self.nbits, |i| self.index(&i)) } /** @@ -555,8 +557,8 @@ pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv { } impl ops::Index for Bitv { - fn index(&self, i: uint) -> bool { - self.get(i) + fn index(&self, i: &uint) -> bool { + self.get(*i) } } diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs index 92898af2993de..b82616d386af8 100644 --- a/src/libstd/ebml.rs +++ b/src/libstd/ebml.rs @@ -68,11 +68,9 @@ pub mod reader { // ebml reading - impl ops::Index for Doc { - fn index(&self, tag: uint) -> Doc { - unsafe { - get_doc(*self, tag) - } + pub impl Doc { + fn get(&self, tag: uint) -> Doc { + get_doc(*self, tag) } } diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs index 9299e3e365e33..6f479140d73ae 100644 --- a/src/test/run-pass/operator-overloading.rs +++ b/src/test/run-pass/operator-overloading.rs @@ -40,8 +40,8 @@ impl ops::Not for Point { } impl ops::Index for Point { - fn index(&self, +x: bool) -> int { - if x { self.x } else { self.y } + fn index(&self, +x: &bool) -> int { + if *x { self.x } else { self.y } } } diff --git a/src/test/run-pass/overload-index-operator.rs b/src/test/run-pass/overload-index-operator.rs new file mode 100644 index 0000000000000..7d1d0c6be0e5e --- /dev/null +++ b/src/test/run-pass/overload-index-operator.rs @@ -0,0 +1,55 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test overloading of the `[]` operator. In particular test that it +// takes its argument *by reference*. + +use core::ops::Index; + +struct AssociationList { + pairs: ~[AssociationPair] +} + +struct AssociationPair { + key: K, + value: V +} + +impl AssociationList { + fn push(&mut self, key: K, value: V) { + self.pairs.push(AssociationPair {key: key, value: value}); + } +} + +impl Index for AssociationList { + fn index(&self, index: &K) -> V { + for self.pairs.each |pair| { + if pair.key == *index { + return copy pair.value; + } + } + fail!(fmt!("No value found for key: %?", index)); + } +} + +pub fn main() { + let foo = ~"foo"; + let bar = ~"bar"; + + let mut list = AssociationList {pairs: ~[]}; + list.push(copy foo, 22); + list.push(copy bar, 44); + + fail_unless!(list[foo] == 22) + fail_unless!(list[bar] == 44) + + fail_unless!(list[foo] == 22) + fail_unless!(list[bar] == 44) +} \ No newline at end of file