mirror of
https://github.com/rust-lang/rust
synced 2024-09-15 22:50:55 +00:00
auto merge of #5558 : nikomatsakis/rust/issue-4920-autoref-index-operator, r=nikomatsakis
Per discussion on IRC. r? @pcwalton
This commit is contained in:
commit
995425badb
|
@ -77,5 +77,5 @@ pub trait Shr<RHS,Result> {
|
||||||
|
|
||||||
#[lang="index"]
|
#[lang="index"]
|
||||||
pub trait Index<Index,Result> {
|
pub trait Index<Index,Result> {
|
||||||
fn index(&self, index: Index) -> Result;
|
fn index(&self, index: &Index) -> Result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,7 +630,6 @@ fn get_mutability(ch: u8) -> ast::mutability {
|
||||||
let self_ty_kind = string[0];
|
let self_ty_kind = string[0];
|
||||||
match self_ty_kind as char {
|
match self_ty_kind as char {
|
||||||
's' => { return ast::sty_static; }
|
's' => { return ast::sty_static; }
|
||||||
'r' => { return ast::sty_by_ref; }
|
|
||||||
'v' => { return ast::sty_value; }
|
'v' => { return ast::sty_value; }
|
||||||
'@' => { return ast::sty_box(get_mutability(string[1])); }
|
'@' => { return ast::sty_box(get_mutability(string[1])); }
|
||||||
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
|
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
|
||||||
|
|
|
@ -410,9 +410,6 @@ fn encode_self_type(ebml_w: writer::Encoder, self_type: ast::self_ty_) {
|
||||||
sty_static => {
|
sty_static => {
|
||||||
ebml_w.writer.write(&[ 's' as u8 ]);
|
ebml_w.writer.write(&[ 's' as u8 ]);
|
||||||
}
|
}
|
||||||
sty_by_ref => {
|
|
||||||
ebml_w.writer.write(&[ 'r' as u8 ]);
|
|
||||||
}
|
|
||||||
sty_value => {
|
sty_value => {
|
||||||
ebml_w.writer.write(&[ 'v' as u8 ]);
|
ebml_w.writer.write(&[ 'v' as u8 ]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@ fn drop_nested_items(blk: &ast::blk_, fld: @fold::ast_fold) -> ast::blk_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_ast(par_doc: ebml::Doc) -> 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);
|
let d = &reader::Decoder(chi_doc);
|
||||||
Decodable::decode(d)
|
Decodable::decode(d)
|
||||||
}
|
}
|
||||||
|
@ -1089,9 +1089,9 @@ fn convert_def_id(&self, xcx: @ExtendedDecodeContext,
|
||||||
fn decode_side_tables(xcx: @ExtendedDecodeContext,
|
fn decode_side_tables(xcx: @ExtendedDecodeContext,
|
||||||
ast_doc: ebml::Doc) {
|
ast_doc: ebml::Doc) {
|
||||||
let dcx = xcx.dcx;
|
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| {
|
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);
|
let id = xcx.tr_id(id0);
|
||||||
|
|
||||||
debug!(">> Side table document with tag 0x%x \
|
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) {
|
} else if tag == (c::tag_table_moves_map as uint) {
|
||||||
dcx.maps.moves_map.insert(id);
|
dcx.maps.moves_map.insert(id);
|
||||||
} else {
|
} 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);
|
let val_dsr = &reader::Decoder(val_doc);
|
||||||
if tag == (c::tag_table_def as uint) {
|
if tag == (c::tag_table_def as uint) {
|
||||||
let def = decode_def(xcx, val_doc);
|
let def = decode_def(xcx, val_doc);
|
||||||
|
@ -1172,7 +1172,7 @@ fn encode_item_ast(ebml_w: writer::Encoder, item: @ast::item) {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
|
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);
|
let d = &reader::Decoder(chi_doc);
|
||||||
@Decodable::decode(d)
|
@Decodable::decode(d)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
visit::visit_expr(ex, self, vt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -467,11 +467,6 @@ fn visit_fn(fk: &visit::fn_kind,
|
||||||
match *fk {
|
match *fk {
|
||||||
fk_method(_, _, method) => {
|
fk_method(_, _, method) => {
|
||||||
match method.self_ty.node {
|
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(_) => {
|
sty_value | sty_region(*) | sty_box(_) | sty_uniq(_) => {
|
||||||
fn_maps.add_variable(Arg(method.self_id,
|
fn_maps.add_variable(Arg(method.self_id,
|
||||||
special_idents::self_,
|
special_idents::self_,
|
||||||
|
|
|
@ -436,7 +436,7 @@ fn use_expr(&self,
|
||||||
|
|
||||||
expr_unary(deref, base) => { // *base
|
expr_unary(deref, base) => { // *base
|
||||||
if !self.use_overloaded_operator(
|
if !self.use_overloaded_operator(
|
||||||
expr, DontDerefArgs, base, [], visitor)
|
expr, base, [], visitor)
|
||||||
{
|
{
|
||||||
// Moving out of *base moves out of base.
|
// Moving out of *base moves out of base.
|
||||||
self.use_expr(base, comp_mode, visitor);
|
self.use_expr(base, comp_mode, visitor);
|
||||||
|
@ -450,7 +450,7 @@ fn use_expr(&self,
|
||||||
|
|
||||||
expr_index(lhs, rhs) => { // lhs[rhs]
|
expr_index(lhs, rhs) => { // lhs[rhs]
|
||||||
if !self.use_overloaded_operator(
|
if !self.use_overloaded_operator(
|
||||||
expr, DontDerefArgs, lhs, [rhs], visitor)
|
expr, lhs, [rhs], visitor)
|
||||||
{
|
{
|
||||||
self.use_expr(lhs, comp_mode, visitor);
|
self.use_expr(lhs, comp_mode, visitor);
|
||||||
self.consume_expr(rhs, visitor);
|
self.consume_expr(rhs, visitor);
|
||||||
|
@ -579,7 +579,7 @@ fn use_expr(&self,
|
||||||
|
|
||||||
expr_unary(_, lhs) => {
|
expr_unary(_, lhs) => {
|
||||||
if !self.use_overloaded_operator(
|
if !self.use_overloaded_operator(
|
||||||
expr, DontDerefArgs, lhs, [], visitor)
|
expr, lhs, [], visitor)
|
||||||
{
|
{
|
||||||
self.consume_expr(lhs, visitor);
|
self.consume_expr(lhs, visitor);
|
||||||
}
|
}
|
||||||
|
@ -587,7 +587,7 @@ fn use_expr(&self,
|
||||||
|
|
||||||
expr_binary(_, lhs, rhs) => {
|
expr_binary(_, lhs, rhs) => {
|
||||||
if !self.use_overloaded_operator(
|
if !self.use_overloaded_operator(
|
||||||
expr, DoDerefArgs, lhs, [rhs], visitor)
|
expr, lhs, [rhs], visitor)
|
||||||
{
|
{
|
||||||
self.consume_expr(lhs, visitor);
|
self.consume_expr(lhs, visitor);
|
||||||
self.consume_expr(rhs, visitor);
|
self.consume_expr(rhs, visitor);
|
||||||
|
@ -659,7 +659,6 @@ fn use_expr(&self,
|
||||||
|
|
||||||
fn use_overloaded_operator(&self,
|
fn use_overloaded_operator(&self,
|
||||||
expr: @expr,
|
expr: @expr,
|
||||||
deref_args: DerefArgs,
|
|
||||||
receiver_expr: @expr,
|
receiver_expr: @expr,
|
||||||
arg_exprs: &[@expr],
|
arg_exprs: &[@expr],
|
||||||
visitor: vt<VisitContext>) -> bool
|
visitor: vt<VisitContext>) -> bool
|
||||||
|
@ -670,21 +669,10 @@ fn use_overloaded_operator(&self,
|
||||||
|
|
||||||
self.use_receiver(expr.id, expr.span, receiver_expr, visitor);
|
self.use_receiver(expr.id, expr.span, receiver_expr, visitor);
|
||||||
|
|
||||||
// The deref_args stuff should eventually be converted into
|
// for overloaded operatrs, we are always passing in a
|
||||||
// adjustments. Moreover, it should eventually be applied
|
// borrowed pointer, so it's always read mode:
|
||||||
// consistently to all overloaded operators. But that's not
|
for arg_exprs.each |arg_expr| {
|
||||||
// how it is today.
|
self.use_expr(*arg_expr, Read, visitor);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -737,20 +725,7 @@ fn use_receiver(&self,
|
||||||
receiver_expr: @expr,
|
receiver_expr: @expr,
|
||||||
visitor: vt<VisitContext>)
|
visitor: vt<VisitContext>)
|
||||||
{
|
{
|
||||||
let callee_mode = match self.method_map.find(&expr_id) {
|
self.use_fn_arg(by_copy, receiver_expr, visitor);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_fn_args(&self,
|
fn use_fn_args(&self,
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
use syntax::ast::{path, pat_box, pat_lit, pat_range, pat_struct};
|
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::{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::{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::{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_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};
|
use syntax::ast::{ty_i16, ty_i32, ty_i64, ty_i8, ty_int, TyParam, ty_path};
|
||||||
|
@ -3792,7 +3792,6 @@ fn resolve_method(@mut self,
|
||||||
// we only have self ty if it is a non static method
|
// we only have self ty if it is a non static method
|
||||||
let self_binding = match method.self_ty.node {
|
let self_binding = match method.self_ty.node {
|
||||||
sty_static => { NoSelfBinding }
|
sty_static => { NoSelfBinding }
|
||||||
sty_by_ref => { HasSelfBinding(method.self_id, true) }
|
|
||||||
_ => { HasSelfBinding(method.self_id, false) }
|
_ => { HasSelfBinding(method.self_id, false) }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -766,18 +766,15 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
|
||||||
}
|
}
|
||||||
ast::expr_binary(_, lhs, rhs) => {
|
ast::expr_binary(_, lhs, rhs) => {
|
||||||
// if not overloaded, would be RvalueDatumExpr
|
// if not overloaded, would be RvalueDatumExpr
|
||||||
return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest,
|
return trans_overloaded_op(bcx, expr, lhs, ~[rhs], dest);
|
||||||
DoAutorefArg);
|
|
||||||
}
|
}
|
||||||
ast::expr_unary(_, subexpr) => {
|
ast::expr_unary(_, subexpr) => {
|
||||||
// if not overloaded, would be RvalueDatumExpr
|
// if not overloaded, would be RvalueDatumExpr
|
||||||
return trans_overloaded_op(bcx, expr, subexpr, ~[], dest,
|
return trans_overloaded_op(bcx, expr, subexpr, ~[], dest);
|
||||||
DontAutorefArg);
|
|
||||||
}
|
}
|
||||||
ast::expr_index(base, idx) => {
|
ast::expr_index(base, idx) => {
|
||||||
// if not overloaded, would be RvalueDatumExpr
|
// if not overloaded, would be RvalueDatumExpr
|
||||||
return trans_overloaded_op(bcx, expr, base, ~[idx], dest,
|
return trans_overloaded_op(bcx, expr, base, ~[idx], dest);
|
||||||
DontAutorefArg);
|
|
||||||
}
|
}
|
||||||
ast::expr_cast(val, _) => {
|
ast::expr_cast(val, _) => {
|
||||||
match ty::get(node_id_type(bcx, expr.id)).sty {
|
match ty::get(node_id_type(bcx, expr.id)).sty {
|
||||||
|
@ -1644,8 +1641,7 @@ fn trans_overloaded_op(bcx: block,
|
||||||
expr: @ast::expr,
|
expr: @ast::expr,
|
||||||
rcvr: @ast::expr,
|
rcvr: @ast::expr,
|
||||||
+args: ~[@ast::expr],
|
+args: ~[@ast::expr],
|
||||||
dest: Dest,
|
dest: Dest) -> block
|
||||||
+autoref_arg: AutorefArg) -> block
|
|
||||||
{
|
{
|
||||||
let origin = *bcx.ccx().maps.method_map.get(&expr.id);
|
let origin = *bcx.ccx().maps.method_map.get(&expr.id);
|
||||||
let fty = node_id_type(bcx, expr.callee_id);
|
let fty = node_id_type(bcx, expr.callee_id);
|
||||||
|
@ -1653,7 +1649,7 @@ fn trans_overloaded_op(bcx: block,
|
||||||
bcx, expr.info(), fty,
|
bcx, expr.info(), fty,
|
||||||
expr_ty(bcx, expr),
|
expr_ty(bcx, expr),
|
||||||
|bcx| meth::trans_method_callee(bcx, expr.callee_id, rcvr, origin),
|
|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,
|
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!!
|
// FIXME(#2528) evaluates the receiver twice!!
|
||||||
let scratch = scratch_datum(bcx, dst_datum.ty, false);
|
let scratch = scratch_datum(bcx, dst_datum.ty, false);
|
||||||
let bcx = trans_overloaded_op(bcx, expr, dst, ~[src],
|
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);
|
return scratch.move_to_datum(bcx, DROP_EXISTING, dst_datum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -596,7 +596,7 @@ pub fn trans_trait_callee(bcx: block,
|
||||||
|
|
||||||
let llpair = match explicit_self {
|
let llpair = match explicit_self {
|
||||||
ast::sty_region(*) => Load(bcx, llpair),
|
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
|
ast::sty_box(_) | ast::sty_uniq(_) => llpair
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -645,21 +645,6 @@ pub fn trans_trait_callee_from_llval(bcx: block,
|
||||||
ast::sty_static => {
|
ast::sty_static => {
|
||||||
bcx.tcx().sess.bug(~"shouldn't see static method here");
|
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 => {
|
ast::sty_value => {
|
||||||
bcx.tcx().sess.bug(~"methods with by-value self should not be \
|
bcx.tcx().sess.bug(~"methods with by-value self should not be \
|
||||||
called on objects");
|
called on objects");
|
||||||
|
|
|
@ -99,7 +99,7 @@ trait `ToStr` imported, and I call `to_str()` on a value of type `T`,
|
||||||
use core::result;
|
use core::result;
|
||||||
use core::uint;
|
use core::uint;
|
||||||
use core::vec;
|
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::{sty_uniq, sty_static, node_id, by_copy, by_ref};
|
||||||
use syntax::ast::{m_const, m_mutbl, m_imm};
|
use syntax::ast::{m_const, m_mutbl, m_imm};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -527,7 +527,7 @@ fn push_inherent_candidates_from_trait(&self,
|
||||||
ast::sty_region(_) => {
|
ast::sty_region(_) => {
|
||||||
return; // inapplicable
|
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_box(_) => vstore_box, // XXX NDM mutability
|
||||||
ast::sty_uniq(_) => vstore_uniq
|
ast::sty_uniq(_) => vstore_uniq
|
||||||
}
|
}
|
||||||
|
@ -741,7 +741,7 @@ fn create_rcvr_ty_and_substs_for_method(&self,
|
||||||
// shouldn't really have to be.
|
// shouldn't really have to be.
|
||||||
let rcvr_substs = {
|
let rcvr_substs = {
|
||||||
match self_decl {
|
match self_decl {
|
||||||
sty_static | sty_value | sty_by_ref |
|
sty_static | sty_value |
|
||||||
sty_box(_) | sty_uniq(_) => {
|
sty_box(_) | sty_uniq(_) => {
|
||||||
self_substs
|
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 \
|
tcx.sess.bug(~"calling transform_self_type_for_method on \
|
||||||
static method");
|
static method");
|
||||||
}
|
}
|
||||||
sty_by_ref | sty_value => {
|
sty_value => {
|
||||||
impl_ty
|
impl_ty
|
||||||
}
|
}
|
||||||
sty_region(_, mutability) => {
|
sty_region(_, mutability) => {
|
||||||
|
|
|
@ -1064,44 +1064,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
|
||||||
-> ty_param_substs_and_ty {
|
-> ty_param_substs_and_ty {
|
||||||
let tcx = vcx.tcx();
|
let tcx = vcx.tcx();
|
||||||
|
|
||||||
let (n_tps, region_param, raw_ty) = if did.crate == ast::local_crate {
|
let (n_tps, region_param, raw_ty) = {
|
||||||
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 ity = ty::lookup_item_type(tcx, did);
|
let ity = ty::lookup_item_type(tcx, did);
|
||||||
(vec::len(*ity.bounds), ity.region_param, ity.ty)
|
(vec::len(*ity.bounds), ity.region_param, ity.ty)
|
||||||
};
|
};
|
||||||
|
@ -1586,7 +1549,7 @@ fn check_user_unop(fcx: @mut FnCtxt,
|
||||||
lookup_op_method(
|
lookup_op_method(
|
||||||
fcx, ex, rhs_expr, rhs_t,
|
fcx, ex, rhs_expr, rhs_t,
|
||||||
fcx.tcx().sess.ident_of(mname), ~[],
|
fcx.tcx().sess.ident_of(mname), ~[],
|
||||||
DontDerefArgs, DontAutoderefReceiver,
|
DoDerefArgs, DontAutoderefReceiver,
|
||||||
|| {
|
|| {
|
||||||
fcx.type_error_message(ex.span, |actual| {
|
fcx.type_error_message(ex.span, |actual| {
|
||||||
fmt!("cannot apply unary operator `%s` to type `%s`",
|
fmt!("cannot apply unary operator `%s` to type `%s`",
|
||||||
|
@ -2795,7 +2758,7 @@ fn types_compatible(fcx: @mut FnCtxt, sp: span,
|
||||||
expr.span, raw_base_t);
|
expr.span, raw_base_t);
|
||||||
let ret_ty = lookup_op_method(fcx, expr, base, resolved,
|
let ret_ty = lookup_op_method(fcx, expr, base, resolved,
|
||||||
tcx.sess.ident_of(~"index"),
|
tcx.sess.ident_of(~"index"),
|
||||||
~[idx], DontDerefArgs, AutoderefReceiver,
|
~[idx], DoDerefArgs, AutoderefReceiver,
|
||||||
|| {
|
|| {
|
||||||
fcx.type_error_message(expr.span, |actual|
|
fcx.type_error_message(expr.span, |actual|
|
||||||
fmt!("cannot index a value \
|
fmt!("cannot index a value \
|
||||||
|
|
|
@ -437,7 +437,8 @@ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
|
||||||
if offset >= bitv.nbits {
|
if offset >= bitv.nbits {
|
||||||
0
|
0
|
||||||
} else {
|
} 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 @@ fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
|
||||||
* Transform self into a [bool] by turning each bit into a bool
|
* Transform self into a [bool] by turning each bit into a bool
|
||||||
*/
|
*/
|
||||||
fn to_bools(&self) -> ~[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<uint,bool> for Bitv {
|
impl ops::Index<uint,bool> for Bitv {
|
||||||
fn index(&self, i: uint) -> bool {
|
fn index(&self, i: &uint) -> bool {
|
||||||
self.get(i)
|
self.get(*i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,11 +68,9 @@ pub mod reader {
|
||||||
|
|
||||||
// ebml reading
|
// ebml reading
|
||||||
|
|
||||||
impl ops::Index<uint,Doc> for Doc {
|
pub impl Doc {
|
||||||
fn index(&self, tag: uint) -> Doc {
|
fn get(&self, tag: uint) -> Doc {
|
||||||
unsafe {
|
get_doc(*self, tag)
|
||||||
get_doc(*self, tag)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1004,7 +1004,6 @@ fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) {
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
pub enum self_ty_ {
|
pub enum self_ty_ {
|
||||||
sty_static, // no self
|
sty_static, // no self
|
||||||
sty_by_ref, // ``
|
|
||||||
sty_value, // `self`
|
sty_value, // `self`
|
||||||
sty_region(Option<@Lifetime>, mutability), // `&'lt self`
|
sty_region(Option<@Lifetime>, mutability), // `&'lt self`
|
||||||
sty_box(mutability), // `@self`
|
sty_box(mutability), // `@self`
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
use ast::{m_imm, meta_item, method};
|
use ast::{m_imm, meta_item, method};
|
||||||
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
||||||
use ast::{stmt, struct_def, struct_variant_kind};
|
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 ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
|
||||||
use ext::base::ext_ctxt;
|
use ext::base::ext_ctxt;
|
||||||
use ext::build;
|
use ext::build;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
use ast::{m_imm, meta_item, method};
|
use ast::{m_imm, meta_item, method};
|
||||||
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
||||||
use ast::{stmt, struct_def, struct_variant_kind};
|
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 ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
|
||||||
use ext::base::ext_ctxt;
|
use ext::base::ext_ctxt;
|
||||||
use ext::build;
|
use ext::build;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
use ast::{m_imm, meta_item, method};
|
use ast::{m_imm, meta_item, method};
|
||||||
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
||||||
use ast::{stmt, struct_def, struct_variant_kind};
|
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 ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
|
||||||
use ext::base::ext_ctxt;
|
use ext::base::ext_ctxt;
|
||||||
use ext::build;
|
use ext::build;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
use ast::{m_imm, meta_item, method};
|
use ast::{m_imm, meta_item, method};
|
||||||
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
|
||||||
use ast::{stmt, struct_def, struct_variant_kind};
|
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 ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
|
||||||
use ext::base::ext_ctxt;
|
use ext::base::ext_ctxt;
|
||||||
use ext::build;
|
use ext::build;
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl};
|
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::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field};
|
||||||
use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract};
|
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::{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::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
|
||||||
use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn};
|
use ast::{ty_field, ty_fixed_length_vec, ty_closure, ty_bare_fn};
|
||||||
|
@ -472,8 +472,6 @@ fn parse_trait_methods(&self) -> ~[trait_method] {
|
||||||
) |p| {
|
) |p| {
|
||||||
let attrs = p.parse_outer_attributes();
|
let attrs = p.parse_outer_attributes();
|
||||||
let lo = p.span.lo;
|
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 vis = p.parse_visibility();
|
||||||
let pur = p.parse_fn_purity();
|
let pur = p.parse_fn_purity();
|
||||||
|
@ -488,12 +486,6 @@ fn parse_trait_methods(&self) -> ~[trait_method] {
|
||||||
// names to be left off if there is a definition...
|
// names to be left off if there is a definition...
|
||||||
either::Left(p.parse_arg_general(false))
|
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;
|
let hi = p.last_span.hi;
|
||||||
debug!("parse_trait_methods(): trait method signature ends in \
|
debug!("parse_trait_methods(): trait method signature ends in \
|
||||||
|
@ -2878,7 +2870,7 @@ fn maybe_parse_self_ty(
|
||||||
p.expect_self_ident();
|
p.expect_self_ident();
|
||||||
cnstr(mutability)
|
cnstr(mutability)
|
||||||
} else {
|
} else {
|
||||||
sty_by_ref
|
sty_static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2927,7 +2919,7 @@ fn maybe_parse_borrowed_self_ty(
|
||||||
self.expect_self_ident();
|
self.expect_self_ident();
|
||||||
sty_region(Some(lifetime), mutability)
|
sty_region(Some(lifetime), mutability)
|
||||||
} else {
|
} else {
|
||||||
sty_by_ref
|
sty_static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2951,13 +2943,13 @@ fn maybe_parse_borrowed_self_ty(
|
||||||
sty_value
|
sty_value
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
sty_by_ref
|
sty_static
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we parsed a self type, expect a comma before the argument list.
|
// If we parsed a self type, expect a comma before the argument list.
|
||||||
let args_or_capture_items;
|
let args_or_capture_items;
|
||||||
if self_ty != sty_by_ref {
|
if self_ty != sty_static {
|
||||||
match *self.token {
|
match *self.token {
|
||||||
token::COMMA => {
|
token::COMMA => {
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -3059,9 +3051,6 @@ fn parse_method(&self) -> @method {
|
||||||
let attrs = self.parse_outer_attributes();
|
let attrs = self.parse_outer_attributes();
|
||||||
let lo = self.span.lo;
|
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();
|
let visa = self.parse_visibility();
|
||||||
let pur = self.parse_fn_purity();
|
let pur = self.parse_fn_purity();
|
||||||
let ident = self.parse_ident();
|
let ident = self.parse_ident();
|
||||||
|
@ -3069,12 +3058,6 @@ fn parse_method(&self) -> @method {
|
||||||
let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| {
|
let (self_ty, decl) = do self.parse_fn_decl_with_self() |p| {
|
||||||
p.parse_arg()
|
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 (inner_attrs, body) = self.parse_inner_attrs_and_block(true);
|
||||||
let hi = body.span.hi;
|
let hi = body.span.hi;
|
||||||
|
|
|
@ -1648,7 +1648,7 @@ fn print_field(s: @ps, f: ast::field_pat, refutable: bool) {
|
||||||
// Returns whether it printed anything
|
// Returns whether it printed anything
|
||||||
pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool {
|
pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool {
|
||||||
match self_ty {
|
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_value => { word(s.s, ~"self"); }
|
||||||
ast::sty_region(lt, m) => {
|
ast::sty_region(lt, m) => {
|
||||||
word(s.s, ~"&");
|
word(s.s, ~"&");
|
||||||
|
@ -1674,7 +1674,7 @@ pub fn print_fn(s: @ps,
|
||||||
opt_self_ty: Option<ast::self_ty_>,
|
opt_self_ty: Option<ast::self_ty_>,
|
||||||
vis: ast::visibility) {
|
vis: ast::visibility) {
|
||||||
head(s, ~"");
|
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);
|
nbsp(s);
|
||||||
print_ident(s, name);
|
print_ident(s, name);
|
||||||
print_generics(s, generics);
|
print_generics(s, generics);
|
||||||
|
@ -2181,7 +2181,6 @@ pub fn print_opt_sigil(s: @ps, opt_sigil: Option<ast::Sigil>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_fn_header_info(s: @ps,
|
pub fn print_fn_header_info(s: @ps,
|
||||||
opt_sty: Option<ast::self_ty_>,
|
|
||||||
purity: ast::purity,
|
purity: ast::purity,
|
||||||
onceness: ast::Onceness,
|
onceness: ast::Onceness,
|
||||||
opt_sigil: Option<ast::Sigil>,
|
opt_sigil: Option<ast::Sigil>,
|
||||||
|
|
|
@ -40,8 +40,8 @@ fn not(&self) -> Point {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Index<bool,int> for Point {
|
impl ops::Index<bool,int> for Point {
|
||||||
fn index(&self, +x: bool) -> int {
|
fn index(&self, +x: &bool) -> int {
|
||||||
if x { self.x } else { self.y }
|
if *x { self.x } else { self.y }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
55
src/test/run-pass/overload-index-operator.rs
Normal file
55
src/test/run-pass/overload-index-operator.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<K,V> {
|
||||||
|
pairs: ~[AssociationPair<K,V>]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AssociationPair<K,V> {
|
||||||
|
key: K,
|
||||||
|
value: V
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K,V> AssociationList<K,V> {
|
||||||
|
fn push(&mut self, key: K, value: V) {
|
||||||
|
self.pairs.push(AssociationPair {key: key, value: value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K:Eq,V:Copy> Index<K,V> for AssociationList<K,V> {
|
||||||
|
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)
|
||||||
|
}
|
Loading…
Reference in a new issue