rollup merge of #23601: nikomatsakis/by-value-index

This is a [breaking-change]. When indexing a generic map (hashmap, etc) using the `[]` operator, it is now necessary to borrow explicitly, so change `map[key]` to `map[&key]` (consistent with the `get` routine). However, indexing of string-valued maps with constant strings can now be written `map["abc"]`.

r? @japaric
cc @aturon @Gankro
This commit is contained in:
Alex Crichton 2015-03-23 15:10:50 -07:00
commit 753efb5042
72 changed files with 953 additions and 177 deletions

View file

@ -19,6 +19,6 @@ pub type header_map = HashMap<String, Rc<RefCell<Vec<Rc<String>>>>>;
// the unused ty param is necessary so this gets monomorphized
pub fn request<T>(req: &header_map) {
let data = req["METHOD".to_string()].clone();
let data = req[&"METHOD".to_string()].clone();
let _x = data.borrow().clone()[0].clone();
}

View file

@ -33,7 +33,7 @@ fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
let mac_expr = match TokenTree::parse(cx, &mbe_matcher[..], args) {
Success(map) => {
match (&*map[str_to_ident("matched")], &*map[str_to_ident("pat")]) {
match (&*map[&str_to_ident("matched")], &*map[&str_to_ident("pat")]) {
(&MatchedNonterminal(NtExpr(ref matched_expr)),
&MatchedSeq(ref pats, seq_sp)) => {
let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt|

View file

@ -19,7 +19,7 @@ struct MyVec<T> { x: T }
impl<T> Index<usize> for MyVec<T> {
type Output = T;
fn index(&self, _: &usize) -> &T {
fn index(&self, _: usize) -> &T {
&self.x
}
}

View file

@ -18,6 +18,7 @@ struct Foo {
y: isize,
}
#[cfg(stage0)]
impl Index<String> for Foo {
type Output = isize;
@ -30,8 +31,20 @@ impl Index<String> for Foo {
}
}
impl IndexMut<String> for Foo {
fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
impl<'a> Index<&'a String> for Foo {
type Output = isize;
fn index(&self, z: &String) -> &isize {
if *z == "x" {
&self.x
} else {
&self.y
}
}
}
impl<'a> IndexMut<&'a String> for Foo {
fn index_mut(&mut self, z: &String) -> &mut isize {
if *z == "x" {
&mut self.x
} else {
@ -41,13 +54,13 @@ impl IndexMut<String> for Foo {
}
fn test1(mut f: Box<Foo>, s: String) {
let _p = &mut f[s];
let _q = &f[s]; //~ ERROR cannot borrow
let _p = &mut f[&s];
let _q = &f[&s]; //~ ERROR cannot borrow
}
fn test2(mut f: Box<Foo>, s: String) {
let _p = &mut f[s];
let _q = &mut f[s]; //~ ERROR cannot borrow
let _p = &mut f[&s];
let _q = &mut f[&s]; //~ ERROR cannot borrow
}
struct Bar {
@ -55,37 +68,37 @@ struct Bar {
}
fn test3(mut f: Box<Bar>, s: String) {
let _p = &mut f.foo[s];
let _q = &mut f.foo[s]; //~ ERROR cannot borrow
let _p = &mut f.foo[&s];
let _q = &mut f.foo[&s]; //~ ERROR cannot borrow
}
fn test4(mut f: Box<Bar>, s: String) {
let _p = &f.foo[s];
let _q = &f.foo[s];
let _p = &f.foo[&s];
let _q = &f.foo[&s];
}
fn test5(mut f: Box<Bar>, s: String) {
let _p = &f.foo[s];
let _q = &mut f.foo[s]; //~ ERROR cannot borrow
let _p = &f.foo[&s];
let _q = &mut f.foo[&s]; //~ ERROR cannot borrow
}
fn test6(mut f: Box<Bar>, g: Foo, s: String) {
let _p = &f.foo[s];
let _p = &f.foo[&s];
f.foo = g; //~ ERROR cannot assign
}
fn test7(mut f: Box<Bar>, g: Bar, s: String) {
let _p = &f.foo[s];
let _p = &f.foo[&s];
*f = g; //~ ERROR cannot assign
}
fn test8(mut f: Box<Bar>, g: Foo, s: String) {
let _p = &mut f.foo[s];
let _p = &mut f.foo[&s];
f.foo = g; //~ ERROR cannot assign
}
fn test9(mut f: Box<Bar>, g: Bar, s: String) {
let _p = &mut f.foo[s];
let _p = &mut f.foo[&s];
*f = g; //~ ERROR cannot assign
}

View file

@ -19,7 +19,7 @@ struct MyVec<T> {
impl<T> Index<usize> for MyVec<T> {
type Output = T;
fn index(&self, &i: &usize) -> &T {
fn index(&self, i: usize) -> &T {
&self.data[i]
}
}

View file

@ -0,0 +1,74 @@
// Copyright 2014 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.
use std::ops::{Index, IndexMut};
struct Foo {
x: isize,
y: isize,
}
impl Index<String> for Foo {
type Output = isize;
fn index(&self, z: String) -> &isize {
if z == "x" {
&self.x
} else {
&self.y
}
}
}
impl IndexMut<String> for Foo {
fn index_mut(&mut self, z: String) -> &mut isize {
if z == "x" {
&mut self.x
} else {
&mut self.y
}
}
}
struct Bar {
x: isize,
}
impl Index<isize> for Bar {
type Output = isize;
fn index<'a>(&'a self, z: isize) -> &'a isize {
&self.x
}
}
fn main() {
let mut f = Foo {
x: 1,
y: 2,
};
let mut s = "hello".to_string();
let rs = &mut s;
println!("{}", f[s]);
//~^ ERROR cannot move out of `s` because it is borrowed
f[s] = 10;
//~^ ERROR cannot move out of `s` because it is borrowed
//~| ERROR use of moved value: `s`
let s = Bar {
x: 1,
};
let i = 2;
let _j = &i;
println!("{}", s[i]); // no error, i is copy
println!("{}", s[i]);
}

View file

@ -15,10 +15,10 @@ struct Foo {
y: isize,
}
impl Index<String> for Foo {
impl<'a> Index<&'a String> for Foo {
type Output = isize;
fn index<'a>(&'a self, z: &String) -> &'a isize {
fn index(&self, z: &String) -> &isize {
if *z == "x" {
&self.x
} else {
@ -27,8 +27,8 @@ impl Index<String> for Foo {
}
}
impl IndexMut<String> for Foo {
fn index_mut<'a>(&'a mut self, z: &String) -> &'a mut isize {
impl<'a> IndexMut<&'a String> for Foo {
fn index_mut(&mut self, z: &String) -> &mut isize {
if *z == "x" {
&mut self.x
} else {
@ -44,7 +44,7 @@ struct Bar {
impl Index<isize> for Bar {
type Output = isize;
fn index<'a>(&'a self, z: &isize) -> &'a isize {
fn index<'a>(&'a self, z: isize) -> &'a isize {
&self.x
}
}
@ -56,9 +56,9 @@ fn main() {
};
let mut s = "hello".to_string();
let rs = &mut s;
println!("{}", f[s]);
println!("{}", f[&s]);
//~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
f[s] = 10;
f[&s] = 10;
//~^ ERROR cannot borrow `s` as immutable because it is also borrowed as mutable
let s = Bar {
x: 1,

View file

@ -20,7 +20,7 @@ struct S;
impl Index<usize> for S {
type Output = str;
fn index<'a>(&'a self, _: &usize) -> &'a str {
fn index(&self, _: usize) -> &str {
"hello"
}
}
@ -31,7 +31,7 @@ struct T;
impl Index<usize> for T {
type Output = Debug + 'static;
fn index<'a>(&'a self, idx: &usize) -> &'a (Debug + 'static) {
fn index<'a>(&'a self, idx: usize) -> &'a (Debug + 'static) {
static x: usize = 42;
&x
}

View file

@ -19,7 +19,7 @@ struct S;
impl Index<uint> for S {
type Output = str;
fn index<'a>(&'a self, _: &uint) -> &'a str {
fn index<'a>(&'a self, _: uint) -> &'a str {
"hello"
}
}
@ -29,7 +29,7 @@ struct T;
impl Index<uint> for T {
type Output = Debug + 'static;
fn index<'a>(&'a self, idx: &uint) -> &'a (Debug + 'static) {
fn index<'a>(&'a self, idx: uint) -> &'a (Debug + 'static) {
static X: uint = 42;
&X as &(Debug + 'static)
}

View file

@ -29,7 +29,7 @@ impl<T> Mat<T> {
impl<T> Index<(uint, uint)> for Mat<T> {
type Output = T;
fn index<'a>(&'a self, &(row, col): &(uint, uint)) -> &'a T {
fn index<'a>(&'a self, (row, col): (uint, uint)) -> &'a T {
&self.data[row * self.cols + col]
}
}
@ -37,7 +37,7 @@ impl<T> Index<(uint, uint)> for Mat<T> {
impl<'a, T> Index<(uint, uint)> for &'a Mat<T> {
type Output = T;
fn index<'b>(&'b self, index: &(uint, uint)) -> &'b T {
fn index<'b>(&'b self, index: (uint, uint)) -> &'b T {
(*self).index(index)
}
}
@ -47,8 +47,8 @@ struct Row<M> { mat: M, row: uint, }
impl<T, M: Index<(uint, uint), Output=T>> Index<uint> for Row<M> {
type Output = T;
fn index<'a>(&'a self, col: &uint) -> &'a T {
&self.mat[(self.row, *col)]
fn index<'a>(&'a self, col: uint) -> &'a T {
&self.mat[(self.row, col)]
}
}
@ -56,7 +56,7 @@ fn main() {
let m = Mat::new(vec!(1, 2, 3, 4, 5, 6), 3);
let r = m.row(1);
assert!(r.index(&2) == &6);
assert!(r.index(2) == &6);
assert!(r[2] == 6);
assert!(r[2] == 6);
assert!(6 == r[2]);

View file

@ -16,7 +16,7 @@ extern crate collections;
use std::collections::HashMap;
fn add_interfaces(managed_ip: String, device: HashMap<String, int>) {
println!("{}, {}", managed_ip, device["interfaces".to_string()]);
println!("{}, {}", managed_ip, device["interfaces"]);
}
pub fn main() {}

View file

@ -56,8 +56,7 @@ fn add_interface(_store: int, managed_ip: String, data: json::Json) -> (String,
fn add_interfaces(store: int, managed_ip: String, device: HashMap<String, json::Json>)
-> Vec<(String, object)> {
match device["interfaces".to_string()]
{
match device["interfaces"] {
Json::Array(ref interfaces) =>
{
interfaces.iter().map(|interface| {
@ -67,7 +66,7 @@ fn add_interfaces(store: int, managed_ip: String, device: HashMap<String, json::
_ =>
{
println!("Expected list for {} interfaces, found {}", managed_ip,
device["interfaces".to_string()]);
device["interfaces"]);
Vec::new()
}
}

View file

@ -17,7 +17,7 @@ fn bar(a: foo::map) {
if false {
panic!();
} else {
let _b = &(*a)[2];
let _b = &(*a)[&2];
}
}

View file

@ -21,6 +21,6 @@ pub fn main() {
let mut m: HashMap<int, A> = HashMap::new();
m.insert(1, A(0, 0));
let A(ref _a, ref _b) = m[1];
let (a, b) = match m[1] { A(ref _a, ref _b) => (_a, _b) };
let A(ref _a, ref _b) = m[&1];
let (a, b) = match m[&1] { A(ref _a, ref _b) => (_a, _b) };
}

View file

@ -52,8 +52,8 @@ impl ops::Not for Point {
impl ops::Index<bool> for Point {
type Output = int;
fn index(&self, x: &bool) -> &int {
if *x {
fn index(&self, x: bool) -> &int {
if x {
&self.x
} else {
&self.y

View file

@ -28,7 +28,7 @@ impl<K,V> AssociationList<K,V> {
}
}
impl<K: PartialEq + std::fmt::Debug, V:Clone> Index<K> for AssociationList<K,V> {
impl<'a, K: PartialEq + std::fmt::Debug, V:Clone> Index<&'a K> for AssociationList<K,V> {
type Output = V;
fn index<'a>(&'a self, index: &K) -> &'a V {
@ -49,9 +49,9 @@ pub fn main() {
list.push(foo.clone(), 22);
list.push(bar.clone(), 44);
assert!(list[foo] == 22);
assert!(list[bar] == 44);
assert!(list[&foo] == 22);
assert!(list[&bar] == 44);
assert!(list[foo] == 22);
assert!(list[bar] == 44);
assert!(list[&foo] == 22);
assert!(list[&bar] == 44);
}

View file

@ -23,8 +23,8 @@ struct Foo {
impl Index<int> for Foo {
type Output = int;
fn index(&self, z: &int) -> &int {
if *z == 0 {
fn index(&self, z: int) -> &int {
if z == 0 {
&self.x
} else {
&self.y
@ -33,8 +33,8 @@ impl Index<int> for Foo {
}
impl IndexMut<int> for Foo {
fn index_mut(&mut self, z: &int) -> &mut int {
if *z == 0 {
fn index_mut(&mut self, z: int) -> &mut int {
if z == 0 {
&mut self.x
} else {
&mut self.y

View file

@ -25,8 +25,8 @@ struct Bar {
impl Index<int> for Foo {
type Output = int;
fn index(&self, z: &int) -> &int {
if *z == 0 {
fn index(&self, z: int) -> &int {
if z == 0 {
&self.x
} else {
&self.y

View file

@ -18,8 +18,8 @@ struct Foo {
impl Index<int> for Foo {
type Output = int;
fn index(&self, z: &int) -> &int {
if *z == 0 {
fn index(&self, z: int) -> &int {
if z == 0 {
&self.x
} else {
&self.y
@ -28,8 +28,8 @@ impl Index<int> for Foo {
}
impl IndexMut<int> for Foo {
fn index_mut(&mut self, z: &int) -> &mut int {
if *z == 0 {
fn index_mut(&mut self, z: int) -> &mut int {
if z == 0 {
&mut self.x
} else {
&mut self.y

View file

@ -21,53 +21,53 @@ struct Foo;
impl Index<Range<Foo>> for Foo {
type Output = Foo;
fn index(&self, index: &Range<Foo>) -> &Foo {
fn index(&self, index: Range<Foo>) -> &Foo {
unsafe { COUNT += 1; }
self
}
}
impl Index<RangeTo<Foo>> for Foo {
type Output = Foo;
fn index(&self, index: &RangeTo<Foo>) -> &Foo {
fn index(&self, index: RangeTo<Foo>) -> &Foo {
unsafe { COUNT += 1; }
self
}
}
impl Index<RangeFrom<Foo>> for Foo {
type Output = Foo;
fn index(&self, index: &RangeFrom<Foo>) -> &Foo {
fn index(&self, index: RangeFrom<Foo>) -> &Foo {
unsafe { COUNT += 1; }
self
}
}
impl Index<RangeFull> for Foo {
type Output = Foo;
fn index(&self, _index: &RangeFull) -> &Foo {
fn index(&self, _index: RangeFull) -> &Foo {
unsafe { COUNT += 1; }
self
}
}
impl IndexMut<Range<Foo>> for Foo {
fn index_mut(&mut self, index: &Range<Foo>) -> &mut Foo {
fn index_mut(&mut self, index: Range<Foo>) -> &mut Foo {
unsafe { COUNT += 1; }
self
}
}
impl IndexMut<RangeTo<Foo>> for Foo {
fn index_mut(&mut self, index: &RangeTo<Foo>) -> &mut Foo {
fn index_mut(&mut self, index: RangeTo<Foo>) -> &mut Foo {
unsafe { COUNT += 1; }
self
}
}
impl IndexMut<RangeFrom<Foo>> for Foo {
fn index_mut(&mut self, index: &RangeFrom<Foo>) -> &mut Foo {
fn index_mut(&mut self, index: RangeFrom<Foo>) -> &mut Foo {
unsafe { COUNT += 1; }
self
}
}
impl IndexMut<RangeFull> for Foo {
fn index_mut(&mut self, _index: &RangeFull) -> &mut Foo {
fn index_mut(&mut self, _index: RangeFull) -> &mut Foo {
unsafe { COUNT += 1; }
self
}