From 69988539da0ecb4b1bb02f6367a1b36267ddd6cb Mon Sep 17 00:00:00 2001 From: Jakub Bukaj Date: Mon, 3 Nov 2014 00:58:00 +0100 Subject: [PATCH 01/37] Add tests for E-needstest issues --- src/test/compile-fail/issue-11382.rs | 16 ++++++++ src/test/compile-fail/issue-11771.rs | 21 ++++++++++ src/test/compile-fail/issue-13058.rs | 39 +++++++++++++++++++ src/test/compile-fail/issue-2718-a.rs | 7 +--- src/test/run-pass/issue-10396.rs | 22 +++++++++++ src/test/run-pass/issue-10501.rs | 14 +++++++ src/test/run-pass/issue-12741.rs | 35 +++++++++++++++++ src/test/run-pass/issue-15063.rs | 19 +++++++++ src/test/run-pass/issue-15734.rs | 56 +++++++++++++++++++++++++++ src/test/run-pass/issue-16774.rs | 50 ++++++++++++++++++++++++ src/test/run-pass/issue-18110.rs | 13 +++++++ src/test/run-pass/issue-7268.rs | 16 ++++++++ 12 files changed, 303 insertions(+), 5 deletions(-) create mode 100644 src/test/compile-fail/issue-11382.rs create mode 100644 src/test/compile-fail/issue-11771.rs create mode 100644 src/test/compile-fail/issue-13058.rs create mode 100644 src/test/run-pass/issue-10396.rs create mode 100644 src/test/run-pass/issue-10501.rs create mode 100644 src/test/run-pass/issue-12741.rs create mode 100644 src/test/run-pass/issue-15063.rs create mode 100644 src/test/run-pass/issue-15734.rs create mode 100644 src/test/run-pass/issue-16774.rs create mode 100644 src/test/run-pass/issue-18110.rs create mode 100644 src/test/run-pass/issue-7268.rs diff --git a/src/test/compile-fail/issue-11382.rs b/src/test/compile-fail/issue-11382.rs new file mode 100644 index 000000000000..44f6cd7719d1 --- /dev/null +++ b/src/test/compile-fail/issue-11382.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { +panic!( + 1.2 +//~^ ERROR cannot determine the type of this number; add a suffix to specify the type explicitly +); +} diff --git a/src/test/compile-fail/issue-11771.rs b/src/test/compile-fail/issue-11771.rs new file mode 100644 index 000000000000..7ce23e1f6ac7 --- /dev/null +++ b/src/test/compile-fail/issue-11771.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let x = (); + 1 + + x //~ ERROR mismatched types: expected `_`, found `()` (expected integral variable, found ()) + ; + + let x: () = (); + 1 + + x //~ ERROR mismatched types: expected `_`, found `()` (expected integral variable, found ()) + ; +} diff --git a/src/test/compile-fail/issue-13058.rs b/src/test/compile-fail/issue-13058.rs new file mode 100644 index 000000000000..5203c91237be --- /dev/null +++ b/src/test/compile-fail/issue-13058.rs @@ -0,0 +1,39 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::iter::{Range,range}; + +trait Itble<'r, T, I: Iterator> { fn iter(&'r self) -> I; } + +impl<'r> Itble<'r, uint, Range> for (uint, uint) { + fn iter(&'r self) -> Range { + let &(min, max) = self; + range(min, max) + } +} + +fn check<'r, I: Iterator, T: Itble<'r, uint, I>>(cont: &T) -> bool +//~^ HELP as shown: fn check<'r, I: Iterator, T: Itble<'r, uint, I>>(cont: &'r T) -> bool +{ + let cont_iter = cont.iter(); +//~^ ERROR cannot infer an appropriate lifetime for autoref due to conflicting requirements + let result = cont_iter.fold(Some(0u16), |state, val| { + state.map_or(None, |mask| { + let bit = 1 << val; + if mask & bit == 0 {Some(mask|bit)} else {None} + }) + }); + result.is_some() +} + +fn main() { + check((3u, 5u)); +//~^ ERROR mismatched types: expected `&_`, found `(uint, uint)` (expected &-ptr, found tuple) +} diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs index 41bdab0941e6..3ba8dd4fefef 100644 --- a/src/test/compile-fail/issue-2718-a.rs +++ b/src/test/compile-fail/issue-2718-a.rs @@ -8,18 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-test - pub struct send_packet { - p: T + p: T } - mod pingpong { use send_packet; pub type ping = send_packet; pub struct pong(send_packet); - //~^ ERROR illegal recursive enum type; wrap the inner value in a box to make it representable + //~^ ERROR illegal recursive struct type; wrap the inner value in a box to make it representable } fn main() {} diff --git a/src/test/run-pass/issue-10396.rs b/src/test/run-pass/issue-10396.rs new file mode 100644 index 000000000000..ce04f188e341 --- /dev/null +++ b/src/test/run-pass/issue-10396.rs @@ -0,0 +1,22 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving(Show)] +enum Foo<'s> { + V(&'s str) +} + +fn f(arr: &[&Foo]) { + for &f in arr.iter() { + println!("{}", f); + } +} + +fn main() {} diff --git a/src/test/run-pass/issue-10501.rs b/src/test/run-pass/issue-10501.rs new file mode 100644 index 000000000000..78f125398edc --- /dev/null +++ b/src/test/run-pass/issue-10501.rs @@ -0,0 +1,14 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub type Foo = fn(&int) -> (); +#[deriving(Clone)] +enum Baz { Bar(Foo) } +fn main() {} diff --git a/src/test/run-pass/issue-12741.rs b/src/test/run-pass/issue-12741.rs new file mode 100644 index 000000000000..e41613b4ae30 --- /dev/null +++ b/src/test/run-pass/issue-12741.rs @@ -0,0 +1,35 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving(Clone)] +pub struct Foo { + f: fn(char, |char| -> char) -> char +} + +impl Foo { + fn bar(&self) -> char { + ((*self).f)('a', |c: char| c) + } +} + +fn bla(c: char, cb: |char| -> char) -> char { + cb(c) +} + +pub fn make_foo() -> Foo { + Foo { + f: bla + } +} + +fn main() { + let a = make_foo(); + assert_eq!(a.bar(), 'a'); +} diff --git a/src/test/run-pass/issue-15063.rs b/src/test/run-pass/issue-15063.rs new file mode 100644 index 000000000000..0b7eb41d2aac --- /dev/null +++ b/src/test/run-pass/issue-15063.rs @@ -0,0 +1,19 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Two { A, B} +impl Drop for Two { + fn drop(&mut self) { + println!("Dropping!"); + } +} +fn main() { + let k = A; +} diff --git a/src/test/run-pass/issue-15734.rs b/src/test/run-pass/issue-15734.rs new file mode 100644 index 000000000000..ea5bd550d53d --- /dev/null +++ b/src/test/run-pass/issue-15734.rs @@ -0,0 +1,56 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Mat { data: Vec, cols: uint, } + +impl Mat { + fn new(data: Vec, cols: uint) -> Mat { + Mat { data: data, cols: cols } + } + fn row<'a>(&'a self, row: uint) -> Row<&'a Mat> { + Row { mat: self, row: row, } + } +} + +impl Index<(uint, uint), T> for Mat { + fn index<'a>(&'a self, &(row, col): &(uint, uint)) -> &'a T { + &self.data[row * self.cols + col] + } +} + +impl<'a, T> Index<(uint, uint), T> for &'a Mat { + fn index<'b>(&'b self, index: &(uint, uint)) -> &'b T { + (*self).index(index) + } +} + +struct Row { mat: M, row: uint, } + +impl> Index for Row { + fn index<'a>(&'a self, col: &uint) -> &'a T { + &self.mat[(self.row, *col)] + } +} + +fn main() { + let m = Mat::new(vec!(1u, 2, 3, 4, 5, 6), 3); + let r = m.row(1); + + assert!(r.index(&2) == &6); + assert!(r[2] == 6); + assert!(r[2u] == 6u); + assert!(6 == r[2]); + + let e = r[2]; + assert!(e == 6); + + let e: uint = r[2]; + assert!(e == 6); +} diff --git a/src/test/run-pass/issue-16774.rs b/src/test/run-pass/issue-16774.rs new file mode 100644 index 000000000000..f996f9309c13 --- /dev/null +++ b/src/test/run-pass/issue-16774.rs @@ -0,0 +1,50 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(overloaded_calls, unboxed_closures)] + +struct X(Box); + +static mut DESTRUCTOR_RAN: bool = false; + +impl Drop for X { + fn drop(&mut self) { + unsafe { + assert!(!DESTRUCTOR_RAN); + DESTRUCTOR_RAN = true; + } + } +} + +impl Deref for X { + fn deref(&self) -> &int { + let &X(box ref x) = self; + x + } +} + +impl DerefMut for X { + fn deref_mut(&mut self) -> &mut int { + let &X(box ref mut x) = self; + x + } +} + +fn main() { + { + let mut test = X(box 5i); + { + let mut change = |&mut:| { *test = 10 }; + change(); + } + assert_eq!(*test, 10); + } + assert!(unsafe { DESTRUCTOR_RAN }); +} diff --git a/src/test/run-pass/issue-18110.rs b/src/test/run-pass/issue-18110.rs new file mode 100644 index 000000000000..3d6b23c8805f --- /dev/null +++ b/src/test/run-pass/issue-18110.rs @@ -0,0 +1,13 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + ({return},); +} diff --git a/src/test/run-pass/issue-7268.rs b/src/test/run-pass/issue-7268.rs new file mode 100644 index 000000000000..8aa959273123 --- /dev/null +++ b/src/test/run-pass/issue-7268.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo(_: T) {} + +fn bar(x: &'static T) { + foo(x); +} +fn main() {} From 071c4110457358f5b91287a63fb782201f5eb7ad Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 4 Nov 2014 20:59:00 +1100 Subject: [PATCH 02/37] Translate SIMD construction as `insertelement`s and a single store. This almost completely avoids GEPi's and pointer manipulation, postponing it until the end with one big write of the whole vector. This leads to a small speed-up in compilation, and makes it easier for LLVM to work with the values, e.g. with `--opt-level=0`, pub fn foo() -> f32x4 { f32x4(0.,0.,0.,0.) } was previously compiled to define <4 x float> @_ZN3foo20h74913e8b13d89666eaaE() unnamed_addr #0 { entry-block: %sret_slot = alloca <4 x float> %0 = getelementptr inbounds <4 x float>* %sret_slot, i32 0, i32 0 store float 0.000000e+00, float* %0 %1 = getelementptr inbounds <4 x float>* %sret_slot, i32 0, i32 1 store float 0.000000e+00, float* %1 %2 = getelementptr inbounds <4 x float>* %sret_slot, i32 0, i32 2 store float 0.000000e+00, float* %2 %3 = getelementptr inbounds <4 x float>* %sret_slot, i32 0, i32 3 store float 0.000000e+00, float* %3 %4 = load <4 x float>* %sret_slot ret <4 x float> %4 } but now becomes define <4 x float> @_ZN3foo20h74913e8b13d89666eaaE() unnamed_addr #0 { entry-block: ret <4 x float> zeroinitializer } --- src/librustc/middle/trans/expr.rs | 37 ++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index f516c6106a99..dca6e10f04de 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1455,14 +1455,35 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, None => {} }; - // Now, we just overwrite the fields we've explicitly specified - for &(i, ref e) in fields.iter() { - let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i); - let e_ty = expr_ty_adjusted(bcx, &**e); - bcx = trans_into(bcx, &**e, SaveIn(dest)); - let scope = cleanup::CustomScope(custom_cleanup_scope); - fcx.schedule_lifetime_end(scope, dest); - fcx.schedule_drop_mem(scope, dest, e_ty); + if ty::type_is_simd(bcx.tcx(), ty) { + // This is the constructor of a SIMD type, such types are + // always primitive machine types and so do not have a + // destructor or require any clean-up. + let llty = type_of::type_of(bcx.ccx(), ty); + + // keep a vector as a register, and running through the field + // `insertelement`ing them directly into that register + // (i.e. avoid GEPi and `store`s to an alloca) . + let mut vec_val = C_undef(llty); + + for &(i, ref e) in fields.iter() { + let block_datum = trans(bcx, &**e); + bcx = block_datum.bcx; + let position = C_uint(bcx.ccx(), i); + let value = block_datum.datum.to_llscalarish(bcx); + vec_val = InsertElement(bcx, vec_val, value, position); + } + Store(bcx, vec_val, addr); + } else { + // Now, we just overwrite the fields we've explicitly specified + for &(i, ref e) in fields.iter() { + let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i); + let e_ty = expr_ty_adjusted(bcx, &**e); + bcx = trans_into(bcx, &**e, SaveIn(dest)); + let scope = cleanup::CustomScope(custom_cleanup_scope); + fcx.schedule_lifetime_end(scope, dest); + fcx.schedule_drop_mem(scope, dest, e_ty); + } } adt::trans_set_discr(bcx, &*repr, addr, discr); From 0514e54b97c75c7cabd5a3b04f2a6b19990a9d66 Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Tue, 4 Nov 2014 12:43:35 -0800 Subject: [PATCH 03/37] std::error: fix stray doc comment --- src/libstd/error.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 6bb9f4b473bc..b048ab13968d 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -33,9 +33,6 @@ //! particular implementation, but also reveal some of its implementation for //! debugging via `cause` chains. //! -//! The trait inherits from `Any` to allow *downcasting*: converting from a -//! trait object to a specific concrete type when applicable. -//! //! # The `FromError` trait //! //! `FromError` is a simple trait that expresses conversions between different From 769fa48a1c8fe0e9bd1b065b01bb3966e0313f4a Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 5 Nov 2014 09:27:37 +1100 Subject: [PATCH 04/37] test: correct spelling error & inverted match. --- src/test/run-make/target-specs/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make/target-specs/Makefile b/src/test/run-make/target-specs/Makefile index 746870d201f2..a352bc3a8cce 100644 --- a/src/test/run-make/target-specs/Makefile +++ b/src/test/run-make/target-specs/Makefile @@ -2,7 +2,7 @@ all: $(RUSTC) foo.rs --target=my-awesome-platform.json --crate-type=lib --emit=asm grep --quiet --invert-match morestack < $(TMPDIR)/foo.s - $(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | grep --quiet --invert-match "Error loading taget specification" + $(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | grep --quiet "Error loading target specification" $(RUSTC) foo.rs --target=my-incomplete-platform.json 2>&1 | grep 'Field llvm-target' RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-awesome-platform --crate-type=lib --emit=asm RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=x86_64-unknown-linux-gnu --crate-type=lib --emit=asm From 2c09da7d1ee079ae5a462267dd51a3ad5c4d6853 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Tue, 4 Nov 2014 18:13:37 -0500 Subject: [PATCH 05/37] librustc_back: Fix triple for linux armhf. --- src/librustc_back/target/arm_unknown_linux_gnueabihf.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs b/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs index 32d183d6254e..305862d357a4 100644 --- a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs @@ -18,7 +18,7 @@ pub fn target() -> Target { -f32:32:32-f64:64:64\ -v64:64:64-v128:64:128\ -a0:0:64-n32".to_string(), - llvm_target: "arm-unknown-linux-gnueabi".to_string(), + llvm_target: "arm-unknown-linux-gnueabihf".to_string(), target_endian: "little".to_string(), target_word_size: "32".to_string(), arch: "arm".to_string(), From 20c1945c51e6ece5dd2cbab1cb06abd93b8778b4 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Tue, 4 Nov 2014 22:31:20 -0500 Subject: [PATCH 06/37] librustc: Call return_type only for functions. --- src/librustc/middle/trans/build.rs | 2 +- src/test/run-fail/issue-18576.rs | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/test/run-fail/issue-18576.rs diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 895f03ec2c79..3ae4fdf0838e 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -655,7 +655,7 @@ pub fn _UndefReturn(cx: Block, fn_: ValueRef) -> ValueRef { unsafe { let ccx = cx.fcx.ccx; let ty = val_ty(fn_); - let retty = if ty.kind() == llvm::Integer { + let retty = if ty.kind() == llvm::Function { ty.return_type() } else { ccx.int_type() diff --git a/src/test/run-fail/issue-18576.rs b/src/test/run-fail/issue-18576.rs new file mode 100644 index 000000000000..0b82a0d8d837 --- /dev/null +++ b/src/test/run-fail/issue-18576.rs @@ -0,0 +1,23 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern:stop + +// #18576 +// Make sure that an calling extern function pointer in an unreachable +// context doesn't cause an LLVM assertion + +#[allow(unreachable_code)] +fn main() { + panic!("stop"); + let pointer = other; + pointer(); +} +extern fn other() {} From 04dd61d1ecb0675cb0f9cd548ef3870e1e071822 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 4 Nov 2014 11:37:18 +1300 Subject: [PATCH 07/37] Make trans::adt know that some structs are unsized --- src/librustc/middle/trans/adt.rs | 45 +++++++++++--------------- src/librustc/middle/trans/debuginfo.rs | 2 +- src/librustc_back/abi.rs | 3 ++ 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index d3658e89a2a5..1359a66d5511 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -49,6 +49,7 @@ use std::num::Int; use std::rc::Rc; use llvm::{ValueRef, True, IntEQ, IntNE}; +use back::abi::slice_elt_base; use middle::subst; use middle::subst::Subst; use middle::trans::_match; @@ -235,7 +236,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr { if cases[1 - discr].is_zerolen(cx, t) { let st = mk_struct(cx, cases[discr].tys.as_slice(), false, t); - match cases[discr].find_ptr() { + match cases[discr].find_ptr(cx) { Some(ThinPointer(_)) if st.fields.len() == 1 => { return RawNullablePointer { nndiscr: discr as Disr, @@ -290,7 +291,7 @@ struct Case { #[deriving(Eq, PartialEq, Show)] pub enum PointerField { ThinPointer(uint), - FatPointer(uint, uint) + FatPointer(uint) } impl Case { @@ -298,31 +299,22 @@ impl Case { mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0 } - fn find_ptr(&self) -> Option { - use back::abi::{fn_field_code, slice_elt_base, trt_field_box}; - + fn find_ptr(&self, cx: &CrateContext) -> Option { for (i, &ty) in self.tys.iter().enumerate() { match ty::get(ty).sty { - // &T/&mut T could either be a thin or fat pointer depending on T - ty::ty_rptr(_, ty::mt { ty, .. }) => match ty::get(ty).sty { + // &T/&mut T/Box could either be a thin or fat pointer depending on T + ty::ty_rptr(_, ty::mt { ty, .. }) | ty::ty_uniq(ty) => match ty::get(ty).sty { // &[T] and &str are a pointer and length pair - ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i, slice_elt_base)), + ty::ty_vec(_, None) | ty::ty_str => return Some(FatPointer(i)), - // &Trait/&mut Trait are a pair of pointers: the actual object and a vtable - ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)), + // &Trait is a pair of pointers: the actual object and a vtable + ty::ty_trait(..) => return Some(FatPointer(i)), - // Any other &T/&mut T is just a pointer - _ => return Some(ThinPointer(i)) - }, + ty::ty_struct(..) if !ty::type_is_sized(cx.tcx(), ty) => { + return Some(FatPointer(i)) + } - // Box could either be a thin or fat pointer depending on T - ty::ty_uniq(t) => match ty::get(t).sty { - ty::ty_vec(_, None) => return Some(FatPointer(i, slice_elt_base)), - - // Box is a pair of pointers: the actual object and a vtable - ty::ty_trait(..) => return Some(FatPointer(i, trt_field_box)), - - // Any other Box is just a pointer + // Any other &T is just a pointer _ => return Some(ThinPointer(i)) }, @@ -330,7 +322,7 @@ impl Case { ty::ty_bare_fn(..) => return Some(ThinPointer(i)), // Closures are a pair of pointers: the code and environment - ty::ty_closure(..) => return Some(FatPointer(i, fn_field_code)), + ty::ty_closure(..) => return Some(FatPointer(i)), // Anything else is not a pointer _ => continue @@ -636,6 +628,7 @@ pub fn trans_get_discr(bcx: Block, r: &Repr, scrutinee: ValueRef, cast_to: Optio -> ValueRef { let signed; let val; + debug!("trans_get_discr r: {}", r); match *r { CEnum(ity, min, max) => { val = load_discr(bcx, ity, scrutinee, min, max); @@ -671,7 +664,7 @@ fn struct_wrapped_nullable_bitdiscr(bcx: Block, nndiscr: Disr, ptrfield: Pointer scrutinee: ValueRef) -> ValueRef { let llptrptr = match ptrfield { ThinPointer(field) => GEPi(bcx, scrutinee, [0, field]), - FatPointer(field, pair) => GEPi(bcx, scrutinee, [0, field, pair]) + FatPointer(field) => GEPi(bcx, scrutinee, [0, field, slice_elt_base]) }; let llptr = Load(bcx, llptrptr); let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; @@ -767,8 +760,8 @@ pub fn trans_set_discr(bcx: Block, r: &Repr, val: ValueRef, discr: Disr) { ThinPointer(field) => (GEPi(bcx, val, [0, field]), type_of::type_of(bcx.ccx(), nonnull.fields[field])), - FatPointer(field, pair) => { - let v = GEPi(bcx, val, [0, field, pair]); + FatPointer(field) => { + let v = GEPi(bcx, val, [0, field, slice_elt_base]); (v, val_ty(v).element_type()) } }; @@ -1102,7 +1095,7 @@ pub fn const_get_discrim(ccx: &CrateContext, r: &Repr, val: ValueRef) StructWrappedNullablePointer { nndiscr, ptrfield, .. } => { let (idx, sub_idx) = match ptrfield { ThinPointer(field) => (field, None), - FatPointer(field, pair) => (field, Some(pair)) + FatPointer(field) => (field, Some(slice_elt_base)) }; if is_null(const_struct_field(ccx, val, idx, sub_idx)) { /* subtraction as uint is ok because nndiscr is either 0 or 1 */ diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ea7f28796f03..0e752b797442 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2255,7 +2255,7 @@ impl EnumMemberDescriptionFactory { let null_variant_name = token::get_name((*self.variants)[null_variant_index].name); let discrfield = match ptrfield { adt::ThinPointer(field) => format!("{}", field), - adt::FatPointer(field, pair) => format!("{}${}", field, pair) + adt::FatPointer(field) => format!("{}", field) }; let union_member_name = format!("RUST$ENCODED$ENUM${}${}", discrfield, diff --git a/src/librustc_back/abi.rs b/src/librustc_back/abi.rs index 19dd6b8459f0..335317be4b41 100644 --- a/src/librustc_back/abi.rs +++ b/src/librustc_back/abi.rs @@ -14,6 +14,9 @@ pub const box_field_refcnt: uint = 0u; pub const box_field_drop_glue: uint = 1u; pub const box_field_body: uint = 4u; +// FIXME(18590) although we have three different layouts here, the compiler relies on +// them being the same. We should replace them with one set of constants. + // The two halves of a closure: code and environment. pub const fn_field_code: uint = 0u; pub const fn_field_box: uint = 1u; From 9af15e3a6b38ce5f44764476b521ab52dea07975 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 4 Nov 2014 11:52:57 +1300 Subject: [PATCH 08/37] Test --- src/test/run-pass/issue-18353.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/test/run-pass/issue-18353.rs diff --git a/src/test/run-pass/issue-18353.rs b/src/test/run-pass/issue-18353.rs new file mode 100644 index 000000000000..c734c1a32224 --- /dev/null +++ b/src/test/run-pass/issue-18353.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that wrapping an unsized struct in an enum which gets optimised does +// not ICE. + +struct Str { + f: [u8] +} + +fn main() { + let str: Option<&Str> = None; + str.is_some(); +} From 2f215f644f3c0d5dc02859a125c4c060736bd250 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 5 Nov 2014 10:53:07 +0100 Subject: [PATCH 09/37] debuginfo: Make LLDB test make targets dependent on lldb python scripts. --- mk/tests.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mk/tests.mk b/mk/tests.mk index 45b618cb7584..4433d780dedf 100644 --- a/mk/tests.mk +++ b/mk/tests.mk @@ -677,7 +677,9 @@ CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS) CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS) CTEST_DEPS_perf_$(1)-T-$(2)-H-$(3) = $$(PERF_TESTS) CTEST_DEPS_debuginfo-gdb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_GDB_TESTS) -CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) +CTEST_DEPS_debuginfo-lldb_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_LLDB_TESTS) \ + $(S)src/etc/lldb_batchmode.py \ + $(S)src/etc/lldb_rust_formatters.py CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS) endef From 37a823b223007da79da5c067782f6494b4771c4a Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 5 Nov 2014 10:54:16 +0100 Subject: [PATCH 10/37] debuginfo: Add timeout before running executable in LLDB tests. This should help with a potential race condition. --- src/etc/lldb_batchmode.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index 467463a39c64..94c7af5e1065 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -30,6 +30,7 @@ import sys import threading import re import atexit +import time # Set this to True for additional output DEBUG_OUTPUT = False @@ -175,6 +176,10 @@ try: for line in script_file: command = line.strip() + if command == "run" or command == "r" or re.match("^process\s+launch.*", command): + # Before starting to run the program, let the thread sleep a bit, so all + # breakpoint added events can be processed + time.sleep(0.5) if command != '': execute_command(command_interpreter, command) From 23913ec713e3af6db48438a3a7f0bdf55685ca28 Mon Sep 17 00:00:00 2001 From: thiagopnts Date: Wed, 5 Nov 2014 12:04:26 -0200 Subject: [PATCH 11/37] rename deprecated non_uppercase_statics to non_upper_case_globals --- src/etc/unicode.py | 2 +- ...lint-non-camel-case-types-non-uppercase-statics-unicode.rs | 2 +- .../lint-non-uppercase-statics-lowercase-mut-statics.rs | 2 +- src/test/run-pass/match-static-const-rename.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/etc/unicode.py b/src/etc/unicode.py index 52e02febd96c..587ebaae22c4 100755 --- a/src/etc/unicode.py +++ b/src/etc/unicode.py @@ -34,7 +34,7 @@ preamble = '''// Copyright 2012-2014 The Rust Project Developers. See the COPYRI // NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly -#![allow(missing_docs, non_uppercase_statics, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case)] ''' # Mapping taken from Table 12 from: diff --git a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs index 36c663fc8474..061f70255275 100644 --- a/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs +++ b/src/test/run-pass/lint-non-camel-case-types-non-uppercase-statics-unicode.rs @@ -12,7 +12,7 @@ #![forbid(non_camel_case_types)] -#![forbid(non_uppercase_statics)] +#![forbid(non_upper_case_globals)] #![feature(non_ascii_idents)] // Some scripts (e.g. hiragana) don't have a concept of diff --git a/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs index 0dae07d31e4d..ce3518618d0b 100644 --- a/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs +++ b/src/test/run-pass/lint-non-uppercase-statics-lowercase-mut-statics.rs @@ -10,7 +10,7 @@ #![forbid(non_camel_case_types)] -#![forbid(non_uppercase_statics)] +#![forbid(non_upper_case_globals)] static mut bar: int = 2; diff --git a/src/test/run-pass/match-static-const-rename.rs b/src/test/run-pass/match-static-const-rename.rs index f3fe93650af5..164cc99e188e 100644 --- a/src/test/run-pass/match-static-const-rename.rs +++ b/src/test/run-pass/match-static-const-rename.rs @@ -16,7 +16,7 @@ // around this problem locally by renaming the constant in the `use` // form to an uppercase identifier that placates the lint. -#![deny(non_uppercase_statics)] +#![deny(non_upper_case_globals)] pub const A : int = 97; @@ -34,7 +34,7 @@ fn f() { } mod m { - #[allow(non_uppercase_statics)] + #[allow(non_upper_case_globals)] pub const aha : int = 7; } From a31e3d6de3202ddcf6750f5d97671cc7dbd64661 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Tue, 4 Nov 2014 23:18:30 -0500 Subject: [PATCH 12/37] Rename misspelled module reference. --- src/librustc_back/target/i686_unknown_dragonfly.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_back/target/i686_unknown_dragonfly.rs b/src/librustc_back/target/i686_unknown_dragonfly.rs index 296d7117efab..a12657ff4dcd 100644 --- a/src/librustc_back/target/i686_unknown_dragonfly.rs +++ b/src/librustc_back/target/i686_unknown_dragonfly.rs @@ -11,7 +11,7 @@ use target::Target; pub fn target() -> Target { - let mut base = super::draginfly_base::opts(); + let mut base = super::dragonfly_base::opts(); base.pre_link_args.push("-m32".to_string()); Target { From 1d4b0245428718651857efde8bf68b07b6ac521e Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Wed, 5 Nov 2014 10:36:09 -0500 Subject: [PATCH 13/37] Add missing dragonfly module. --- src/librustc_back/target/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 0978fba2a213..2801682239bb 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -63,6 +63,7 @@ mod arm_unknown_linux_gnueabihf; mod i686_apple_darwin; mod i386_apple_ios; mod i686_pc_windows_gnu; +mod i686_unknown_dragonfly; mod i686_unknown_linux_gnu; mod mips_unknown_linux_gnu; mod mipsel_unknown_linux_gnu; @@ -338,6 +339,7 @@ impl Target { x86_64_unknown_freebsd, + i686_unknown_dragonfly, x86_64_unknown_dragonfly, x86_64_apple_darwin, From 36088ab21fe0eb0f2c3d5e7636959d24ee6e8a41 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 5 Nov 2014 11:44:46 +0100 Subject: [PATCH 14/37] debuginfo: Add a timeout for LLDB tests. Fixes #18649. --- src/etc/lldb_batchmode.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py index 94c7af5e1065..25e5661ca49d 100644 --- a/src/etc/lldb_batchmode.py +++ b/src/etc/lldb_batchmode.py @@ -28,6 +28,7 @@ import lldb import os import sys import threading +import thread import re import atexit import time @@ -131,6 +132,22 @@ def start_breakpoint_listener(target): target.GetBroadcaster().AddListener(listener, lldb.SBTarget.eBroadcastBitBreakpointChanged) +def start_watchdog(): + "Starts a watchdog thread that will terminate the process after a certain period of time" + watchdog_start_time = time.clock() + watchdog_max_time = watchdog_start_time + 30 + + def watchdog(): + while time.clock() < watchdog_max_time: + time.sleep(1) + print("TIMEOUT: lldb_batchmode.py has been running for too long. Aborting!") + thread.interrupt_main() + + # Start the listener and let it run as a daemon + watchdog_thread = threading.Thread(target = watchdog) + watchdog_thread.daemon = True + watchdog_thread.start() + #################################################################################################### # ~main #################################################################################################### @@ -148,6 +165,9 @@ print("Debugger commands script is '%s'." % script_path) print("Target executable is '%s'." % target_path) print("Current working directory is '%s'" % os.getcwd()) +# Start the timeout watchdog +start_watchdog() + # Create a new debugger instance debugger = lldb.SBDebugger.Create() From e4794250c89e2594f12c0d0d1ae25c9ff5b10803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=20Burc=C4=83?= Date: Wed, 5 Nov 2014 22:11:52 +0200 Subject: [PATCH 15/37] Fix example in HashMap::new() docs --- src/libstd/collections/hash/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 596e483c2f6d..e7256a022fc1 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -477,7 +477,7 @@ impl HashMap { /// /// ``` /// use std::collections::HashMap; - /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10); + /// let mut map: HashMap<&str, int> = HashMap::new(); /// ``` #[inline] pub fn new() -> HashMap { From f383ce62e80592b1c46d0c259733efc38f695352 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Wed, 5 Nov 2014 15:49:37 -0800 Subject: [PATCH 16/37] rustc: Add some more checks to the stability lint This catches uses of unstable traits in ``` trait Foo: UnstableTrait { } ``` and ``` impl UnstableTrait for Foo { } ``` --- src/librustc/lint/builtin.rs | 81 ++++++++++++++++--------- src/test/auxiliary/lint_stability.rs | 3 + src/test/compile-fail/lint-stability.rs | 15 +++++ 3 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index f084c8caea54..ec522d707849 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1581,6 +1581,36 @@ impl Stability { cx.span_lint(lint, span, msg.as_slice()); } + + fn is_internal(&self, cx: &Context, span: Span) -> bool { + // first, check if the given expression was generated by a macro or not + // we need to go back the expn_info tree to check only the arguments + // of the initial macro call, not the nested ones. + let mut expnid = span.expn_id; + let mut is_internal = false; + while cx.tcx.sess.codemap().with_expn_info(expnid, |expninfo| { + match expninfo { + Some(ref info) => { + // save the parent expn_id for next loop iteration + expnid = info.call_site.expn_id; + if info.callee.span.is_none() { + // it's a compiler built-in, we *really* don't want to mess with it + // so we skip it, unless it was called by a regular macro, in which case + // we will handle the caller macro next turn + is_internal = true; + true // continue looping + } else { + // was this expression from the current macro arguments ? + is_internal = !( span.lo > info.call_site.lo && + span.hi < info.call_site.hi ); + true // continue looping + } + }, + _ => false // stop looping + } + }) { /* empty while loop body */ } + return is_internal; + } } impl LintPass for Stability { @@ -1605,33 +1635,7 @@ impl LintPass for Stability { } fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { - // first, check if the given expression was generated by a macro or not - // we need to go back the expn_info tree to check only the arguments - // of the initial macro call, not the nested ones. - let mut expnid = e.span.expn_id; - let mut is_internal = false; - while cx.tcx.sess.codemap().with_expn_info(expnid, |expninfo| { - match expninfo { - Some(ref info) => { - // save the parent expn_id for next loop iteration - expnid = info.call_site.expn_id; - if info.callee.span.is_none() { - // it's a compiler built-in, we *really* don't want to mess with it - // so we skip it, unless it was called by a regular macro, in which case - // we will handle the caller macro next turn - is_internal = true; - true // continue looping - } else { - // was this expression from the current macro arguments ? - is_internal = !( e.span.lo > info.call_site.lo && - e.span.hi < info.call_site.hi ); - true // continue looping - } - }, - _ => false // stop looping - } - }) { /* empty while loop body */ } - if is_internal { return; } + if self.is_internal(cx, e.span) { return; } let mut span = e.span; @@ -1677,6 +1681,29 @@ impl LintPass for Stability { }; self.lint(cx, id, span); } + + fn check_item(&mut self, cx: &Context, item: &ast::Item) { + if self.is_internal(cx, item.span) { return } + + match item.node { + ast::ItemTrait(_, _, ref supertraits, _) => { + for t in supertraits.iter() { + match *t { + ast::TraitTyParamBound(ref t) => { + let id = ty::trait_ref_to_def_id(cx.tcx, t); + self.lint(cx, id, t.path.span); + } + _ => (/* pass */) + } + } + } + ast::ItemImpl(_, Some(ref t), _, _) => { + let id = ty::trait_ref_to_def_id(cx.tcx, t); + self.lint(cx, id, t.path.span); + } + _ => (/* pass */) + } + } } declare_lint!(pub UNUSED_IMPORTS, Warn, diff --git a/src/test/auxiliary/lint_stability.rs b/src/test/auxiliary/lint_stability.rs index 06031eb6c6cc..0be2f31e2827 100644 --- a/src/test/auxiliary/lint_stability.rs +++ b/src/test/auxiliary/lint_stability.rs @@ -118,6 +118,9 @@ pub trait Trait { impl Trait for MethodTester {} +#[experimental] +pub trait ExperimentalTrait {} + #[deprecated] pub struct DeprecatedStruct { pub i: int } #[experimental] diff --git a/src/test/compile-fail/lint-stability.rs b/src/test/compile-fail/lint-stability.rs index babf12e97f2a..2074d0075023 100644 --- a/src/test/compile-fail/lint-stability.rs +++ b/src/test/compile-fail/lint-stability.rs @@ -141,6 +141,12 @@ mod cross_crate { foo.trait_unmarked(); //~ ERROR use of unmarked item foo.trait_stable(); } + + struct S; + + impl ExperimentalTrait for S { } //~ ERROR use of experimental item + + trait LocalTrait : ExperimentalTrait { } //~ ERROR use of experimental item } mod inheritance { @@ -444,6 +450,15 @@ mod this_crate { foo.trait_unmarked(); foo.trait_stable(); } + + #[deprecated] + pub trait DeprecatedTrait {} + + struct S; + + impl DeprecatedTrait for S { } //~ ERROR use of deprecated item + + trait LocalTrait : DeprecatedTrait { } //~ ERROR use of deprecated item } fn main() {} From cfae691e46952c7582e052297420a0ad732143f1 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Thu, 6 Nov 2014 00:17:56 -0500 Subject: [PATCH 17/37] fix typo in librustc target spec --- src/librustc/back/link.rs | 2 +- src/librustc_back/target/arm_linux_androideabi.rs | 2 +- src/librustc_back/target/linux_base.rs | 2 +- src/librustc_back/target/mod.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 81f856c29d5d..a0123e28e7d0 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -920,7 +920,7 @@ fn link_args(cmd: &mut Command, let used_link_args = sess.cstore.get_used_link_args().borrow(); - if t.options.position_independant_executables { + if t.options.position_independent_executables { let empty_vec = Vec::new(); let empty_str = String::new(); let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec); diff --git a/src/librustc_back/target/arm_linux_androideabi.rs b/src/librustc_back/target/arm_linux_androideabi.rs index b47e3d0b237c..97bc747916d0 100644 --- a/src/librustc_back/target/arm_linux_androideabi.rs +++ b/src/librustc_back/target/arm_linux_androideabi.rs @@ -17,7 +17,7 @@ pub fn target() -> Target { // linker doesn't like that by default. base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string()); // FIXME #17437 (and #17448): Android doesn't support position dependant executables anymore. - base.position_independant_executables = false; + base.position_independent_executables = false; Target { data_layout: "e-p:32:32:32\ diff --git a/src/librustc_back/target/linux_base.rs b/src/librustc_back/target/linux_base.rs index 51b817a6175e..d267bc77e497 100644 --- a/src/librustc_back/target/linux_base.rs +++ b/src/librustc_back/target/linux_base.rs @@ -25,7 +25,7 @@ pub fn opts() -> TargetOptions { // follow this flag. Thus, use it before specifying libraries to link to. "-Wl,--as-needed".to_string(), ), - position_independant_executables: true, + position_independent_executables: true, .. Default::default() } } diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 0978fba2a213..adb7eed5d928 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -158,7 +158,7 @@ pub struct TargetOptions { /// relocation model of position independent code is not changed. This is a requirement to take /// advantage of ASLR, as otherwise the functions in the executable are not randomized and can /// be used during an exploit of a vulnerability in any code. - pub position_independant_executables: bool, + pub position_independent_executables: bool, } impl Default for TargetOptions { @@ -189,7 +189,7 @@ impl Default for TargetOptions { linker_is_gnu: false, has_rpath: false, no_compiler_rt: false, - position_independant_executables: false, + position_independent_executables: false, } } } From dddef44a6b3cbc0047e55242b6fdc002d5355a80 Mon Sep 17 00:00:00 2001 From: Nathan Zadoks Date: Thu, 6 Nov 2014 06:37:40 +0100 Subject: [PATCH 18/37] Make x86_64-unknown-linux-gnu.json true to its name --- .../run-make/target-specs/x86_64-unknown-linux-gnu.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/run-make/target-specs/x86_64-unknown-linux-gnu.json b/src/test/run-make/target-specs/x86_64-unknown-linux-gnu.json index f5f622bbcdaa..5e0f0f40e67b 100644 --- a/src/test/run-make/target-specs/x86_64-unknown-linux-gnu.json +++ b/src/test/run-make/target-specs/x86_64-unknown-linux-gnu.json @@ -1,9 +1,10 @@ { - "data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32", - "llvm-target": "i686-unknown-linux-gnu", + "pre-link-args": ["-m64"], + "data-layout": "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128", + "llvm-target": "x86_64-unknown-linux-gnu", "target-endian": "little", - "target-word-size": "32", - "arch": "x86", + "target-word-size": "64", + "arch": "x86_64", "os": "linux", "morestack": false } From 4e352892c8ca76f49332fb74d9903677dea2c5fe Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 29 Oct 2014 18:03:40 -0400 Subject: [PATCH 19/37] Restructure parsing of paths, which is quite tortured --- src/libsyntax/parse/parser.rs | 150 ++++++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 42 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 10bb9ef36250..fd244a443a8a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1706,50 +1706,18 @@ impl<'a> Parser<'a> { // Parse any number of segments and bound sets. A segment is an // identifier followed by an optional lifetime and a set of types. // A bound set is a set of type parameter bounds. - let mut segments = Vec::new(); - loop { - // First, parse an identifier. - let identifier = self.parse_ident(); - - // Parse the '::' before type parameters if it's required. If - // it is required and wasn't present, then we're done. - if mode == LifetimeAndTypesWithColons && - !self.eat(&token::ModSep) { - segments.push(ast::PathSegment { - identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), - }); - break + let segments = match mode { + LifetimeAndTypesWithoutColons | + LifetimeAndTypesAndBounds => { + self.parse_path_segments_without_colons() } - - // Parse the `<` before the lifetime and types, if applicable. - let (any_lifetime_or_types, lifetimes, types) = { - if mode != NoTypesAllowed && self.eat_lt(false) { - let (lifetimes, types) = - self.parse_generic_values_after_lt(); - (true, lifetimes, OwnedSlice::from_vec(types)) - } else { - (false, Vec::new(), OwnedSlice::empty()) - } - }; - - // Assemble and push the result. - segments.push(ast::PathSegment { - identifier: identifier, - lifetimes: lifetimes, - types: types, - }); - - // We're done if we don't see a '::', unless the mode required - // a double colon to get here in the first place. - if !(mode == LifetimeAndTypesWithColons && - !any_lifetime_or_types) { - if !self.eat(&token::ModSep) { - break - } + LifetimeAndTypesWithColons => { + self.parse_path_segments_with_colons() } - } + NoTypesAllowed => { + self.parse_path_segments_without_types() + } + }; // Next, parse a plus and bounded type parameters, if // applicable. We need to remember whether the separate was @@ -1792,6 +1760,104 @@ impl<'a> Parser<'a> { } } + /// Examples: + /// - `a::b::c` + /// - `a::b::c(V) -> W` + /// - `a::b::c(V)` + pub fn parse_path_segments_without_colons(&mut self) -> Vec { + let mut segments = Vec::new(); + loop { + // First, parse an identifier. + let identifier = self.parse_ident(); + + // Parse types, optionally. + let (lifetimes, types) = if self.eat_lt(false) { + self.parse_generic_values_after_lt() + } else if false && self.eat(&token::LParen) { + let mut types = self.parse_seq_to_end( + &token::RParen, + seq_sep_trailing_allowed(token::Comma), + |p| p.parse_ty(true)); + + if self.eat(&token::RArrow) { + types.push(self.parse_ty(true)) + } + + (Vec::new(), types) + } else { + (Vec::new(), Vec::new()) + }; + + // Assemble and push the result. + segments.push(ast::PathSegment { identifier: identifier, + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), }); + + // Continue only if we see a `::` + if !self.eat(&token::ModSep) { + return segments; + } + } + } + + /// Examples: + /// - `a::b::::c` + pub fn parse_path_segments_with_colons(&mut self) -> Vec { + let mut segments = Vec::new(); + loop { + // First, parse an identifier. + let identifier = self.parse_ident(); + + // If we do not see a `::`, stop. + if !self.eat(&token::ModSep) { + segments.push(ast::PathSegment { identifier: identifier, + lifetimes: Vec::new(), + types: OwnedSlice::empty() }); + return segments; + } + + // Check for a type segment. + if self.eat_lt(false) { + // Consumed `a::b::<`, go look for types + let (lifetimes, types) = self.parse_generic_values_after_lt(); + segments.push(ast::PathSegment { identifier: identifier, + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types) }); + + // Consumed `a::b::`, check for `::` before proceeding + if !self.eat(&token::ModSep) { + return segments; + } + } else { + // Consumed `a::`, go look for `b` + segments.push(ast::PathSegment { identifier: identifier, + lifetimes: Vec::new(), + types: OwnedSlice::empty() }); + } + } + } + + + /// Examples: + /// - `a::b::c` + pub fn parse_path_segments_without_types(&mut self) -> Vec { + let mut segments = Vec::new(); + loop { + // First, parse an identifier. + let identifier = self.parse_ident(); + + // Assemble and push the result. + segments.push(ast::PathSegment { identifier: identifier, + lifetimes: Vec::new(), + types: OwnedSlice::empty(), }); + + // If we do not see a `::`, stop. + if !self.eat(&token::ModSep) { + return segments; + } + } + } + /// parses 0 or 1 lifetime pub fn parse_opt_lifetime(&mut self) -> Option { match self.token { From 221edbae3843848047825701e25b6f9d8b096075 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 3 Nov 2014 21:52:52 -0500 Subject: [PATCH 20/37] Support parenthesized paths `Foo(A,B) -> C` that expand to `Foo<(A,B),C>`. These paths also bind anonymous regions (or will, once HRTB is fully working). Fixes #18423. --- src/librustc/diagnostics.rs | 5 +- src/librustc/middle/check_const.rs | 2 +- src/librustc/middle/pat_util.rs | 4 +- src/librustc/middle/privacy.rs | 4 +- src/librustc/middle/resolve.rs | 8 +- src/librustc/middle/trans/base.rs | 6 +- src/librustc/middle/trans/consts.rs | 2 +- src/librustc/middle/ty.rs | 8 + src/librustc/middle/typeck/astconv.rs | 230 +++++++++++------- src/librustc/middle/typeck/check/mod.rs | 90 ++++++- src/librustc/middle/typeck/collect.rs | 3 +- .../middle/typeck/infer/error_reporting.rs | 73 +++--- src/librustdoc/clean/mod.rs | 17 +- src/libsyntax/ast.rs | 97 +++++++- src/libsyntax/ast_util.rs | 18 +- src/libsyntax/ext/build.rs | 9 +- src/libsyntax/ext/concat_idents.rs | 4 +- src/libsyntax/fold.rs | 50 +++- src/libsyntax/parse/mod.rs | 24 +- src/libsyntax/parse/parser.rs | 98 ++++---- src/libsyntax/print/pprust.rs | 56 ++++- src/libsyntax/std_inject.rs | 7 +- src/libsyntax/test.rs | 3 +- src/libsyntax/visit.rs | 22 +- src/test/compile-fail/issue-14092.rs | 2 +- src/test/compile-fail/issue-18423.rs | 18 ++ .../unboxed-closure-sugar-default.rs | 37 +++ .../unboxed-closure-sugar-equiv.rs | 39 +++ ...unboxed-closure-sugar-nonexistent-trait.rs | 2 +- .../unboxed-closure-sugar-region.rs | 45 ++++ ...r-wrong-number-number-type-parameters-1.rs | 16 ++ ...r-wrong-number-number-type-parameters-3.rs | 16 ++ ...gar-wrong-number-number-type-parameters.rs | 16 ++ .../unboxed-closure-sugar-wrong-trait.rs | 2 +- src/test/run-pass/unboxed-closures-prelude.rs | 2 +- src/test/run-pass/unboxed-closures-sugar-1.rs | 34 +++ .../run-pass/unboxed-closures-sugar-object.rs | 34 +++ .../unboxed-closures-unboxing-shim.rs | 2 +- 38 files changed, 841 insertions(+), 264 deletions(-) create mode 100644 src/test/compile-fail/issue-18423.rs create mode 100644 src/test/compile-fail/unboxed-closure-sugar-default.rs create mode 100644 src/test/compile-fail/unboxed-closure-sugar-equiv.rs create mode 100644 src/test/compile-fail/unboxed-closure-sugar-region.rs create mode 100644 src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs create mode 100644 src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs create mode 100644 src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs create mode 100644 src/test/run-pass/unboxed-closures-sugar-1.rs create mode 100644 src/test/run-pass/unboxed-closures-sugar-object.rs diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index c4e213790880..d5e9c1ef99f1 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -57,7 +57,6 @@ register_diagnostics!( E0044, E0045, E0046, - E0047, E0049, E0050, E0051, @@ -111,7 +110,6 @@ register_diagnostics!( E0108, E0109, E0110, - E0113, E0116, E0117, E0118, @@ -145,5 +143,6 @@ register_diagnostics!( E0163, E0164, E0165, - E0166 + E0166, + E0167 ) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 6cf1a93b40b7..283845663036 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -138,7 +138,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool { // to handle on-demand instantiation of functions via // foo:: in a const. Currently that is only done on // a path in trans::callee that only works in block contexts. - if !pth.segments.iter().all(|segment| segment.types.is_empty()) { + if !pth.segments.iter().all(|segment| segment.parameters.is_empty()) { span_err!(v.tcx.sess, e.span, E0013, "paths in constants may only refer to items without \ type parameters"); diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 357f4cdf0ebc..f1d8c550d04f 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -16,7 +16,6 @@ use std::collections::HashMap; use syntax::ast::*; use syntax::ast_util::{walk_pat}; use syntax::codemap::{Span, DUMMY_SP}; -use syntax::owned_slice::OwnedSlice; pub type PatIdMap = HashMap; @@ -133,8 +132,7 @@ pub fn def_to_path(tcx: &ty::ctxt, id: DefId) -> Path { global: false, segments: path.last().map(|elem| PathSegment { identifier: Ident::new(elem.name()), - lifetimes: vec!(), - types: OwnedSlice::empty() + parameters: PathParameters::none(), }).into_iter().collect(), span: DUMMY_SP, }) diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 4fbffa2a819d..7124488f7c16 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -27,7 +27,6 @@ use syntax::ast_map; use syntax::ast_util::{is_local, local_def, PostExpansionMethod}; use syntax::codemap::Span; use syntax::parse::token; -use syntax::owned_slice::OwnedSlice; use syntax::visit; use syntax::visit::Visitor; @@ -945,8 +944,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { debug!("privacy - ident item {}", id); let seg = ast::PathSegment { identifier: name, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }; let segs = vec![seg]; let path = ast::Path { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ed7d9296c701..34f0cb7c1982 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -4951,12 +4951,12 @@ impl<'a> Resolver<'a> { if path.segments .iter() - .any(|s| !s.lifetimes.is_empty()) { + .any(|s| s.parameters.has_lifetimes()) { span_err!(self.session, path.span, E0157, "lifetime parameters are not allowed on this type"); } else if path.segments .iter() - .any(|s| s.types.len() > 0) { + .any(|s| !s.parameters.is_empty()) { span_err!(self.session, path.span, E0153, "type parameters are not allowed on this type"); } @@ -5234,7 +5234,7 @@ impl<'a> Resolver<'a> { // Check the types in the path pattern. for ty in path.segments .iter() - .flat_map(|s| s.types.iter()) { + .flat_map(|s| s.parameters.types().into_iter()) { self.resolve_type(&**ty); } } @@ -5340,7 +5340,7 @@ impl<'a> Resolver<'a> { namespace: Namespace, check_ribs: bool) -> Option<(Def, LastPrivate)> { // First, resolve the types. - for ty in path.segments.iter().flat_map(|s| s.types.iter()) { + for ty in path.segments.iter().flat_map(|s| s.parameters.types().into_iter()) { self.resolve_type(&**ty); } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b80425e7ac85..c73268317bdc 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1836,11 +1836,7 @@ pub fn trans_closure(ccx: &CrateContext, NotUnboxedClosure => monomorphized_arg_types, // Tuple up closure argument types for the "rust-call" ABI. - IsUnboxedClosure => vec![if monomorphized_arg_types.is_empty() { - ty::mk_nil() - } else { - ty::mk_tup(ccx.tcx(), monomorphized_arg_types) - }] + IsUnboxedClosure => vec![ty::mk_tup_or_nil(ccx.tcx(), monomorphized_arg_types)] }; for monomorphized_arg_type in monomorphized_arg_types.iter() { debug!("trans_closure: monomorphized_arg_type: {}", diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 6ba6ff6fb211..bd43aa47906e 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -625,7 +625,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { } ast::ExprPath(ref pth) => { // Assert that there are no type parameters in this path. - assert!(pth.segments.iter().all(|seg| seg.types.is_empty())); + assert!(pth.segments.iter().all(|seg| !seg.parameters.has_types())); let opt_def = cx.tcx().def_map.borrow().find_copy(&e.id); match opt_def { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 76caa42b8502..9c717b98f35d 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1838,6 +1838,14 @@ pub fn mk_slice(cx: &ctxt, r: Region, tm: mt) -> t { pub fn mk_tup(cx: &ctxt, ts: Vec) -> t { mk_t(cx, ty_tup(ts)) } +pub fn mk_tup_or_nil(cx: &ctxt, ts: Vec) -> t { + if ts.len() == 0 { + ty::mk_nil() + } else { + mk_t(cx, ty_tup(ts)) + } +} + pub fn mk_closure(cx: &ctxt, fty: ClosureTy) -> t { mk_t(cx, ty_closure(box fty)) } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 7c8d9309df3b..f2cc3bfd29b9 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -59,7 +59,7 @@ use middle::subst::{VecPerParamSpace}; use middle::ty; use middle::typeck::lookup_def_tcx; use middle::typeck::infer; -use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope}; +use middle::typeck::rscope::{UnelidableRscope, RegionScope, SpecificRscope, BindingRscope}; use middle::typeck::rscope; use middle::typeck::TypeAndSubsts; use middle::typeck; @@ -207,15 +207,16 @@ pub fn opt_ast_region_to_region<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( } fn ast_path_substs<'tcx,AC,RS>( - this: &AC, - rscope: &RS, - decl_def_id: ast::DefId, - decl_generics: &ty::Generics, - self_ty: Option, - associated_ty: Option, - path: &ast::Path) - -> Substs - where AC: AstConv<'tcx>, RS: RegionScope + this: &AC, + rscope: &RS, + decl_def_id: ast::DefId, + decl_generics: &ty::Generics, + self_ty: Option, + associated_ty: Option, + path: &ast::Path, + binder_id: ast::NodeId) + -> Substs + where AC: AstConv<'tcx>, RS: RegionScope { /*! * Given a path `path` that refers to an item `I` with the @@ -236,45 +237,51 @@ fn ast_path_substs<'tcx,AC,RS>( assert!(decl_generics.regions.all(|d| d.space == TypeSpace)); assert!(decl_generics.types.all(|d| d.space != FnSpace)); + let (regions, types) = match path.segments.last().unwrap().parameters { + ast::AngleBracketedParameters(ref data) => + angle_bracketed_parameters(this, rscope, data), + ast::ParenthesizedParameters(ref data) => + parenthesized_parameters(this, binder_id, data), + }; + // If the type is parameterized by the this region, then replace this // region with the current anon region binding (in other words, // whatever & would get replaced with). let expected_num_region_params = decl_generics.regions.len(TypeSpace); - let supplied_num_region_params = path.segments.last().unwrap().lifetimes.len(); + let supplied_num_region_params = regions.len(); let regions = if expected_num_region_params == supplied_num_region_params { - path.segments.last().unwrap().lifetimes.iter().map( - |l| ast_region_to_region(this.tcx(), l)).collect::>() + regions } else { let anon_regions = rscope.anon_regions(path.span, expected_num_region_params); if supplied_num_region_params != 0 || anon_regions.is_err() { span_err!(tcx.sess, path.span, E0107, - "wrong number of lifetime parameters: expected {}, found {}", - expected_num_region_params, supplied_num_region_params); + "wrong number of lifetime parameters: expected {}, found {}", + expected_num_region_params, supplied_num_region_params); } match anon_regions { Ok(v) => v.into_iter().collect(), Err(_) => Vec::from_fn(expected_num_region_params, - |_| ty::ReStatic) // hokey + |_| ty::ReStatic) // hokey } }; // Convert the type parameters supplied by the user. let ty_param_defs = decl_generics.types.get_slice(TypeSpace); - let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).count(); + let supplied_ty_param_count = types.len(); let formal_ty_param_count = ty_param_defs.iter() - .take_while(|x| !ty::is_associated_type(tcx, x.def_id)) - .count(); + .take_while(|x| !ty::is_associated_type(tcx, x.def_id)) + .count(); let required_ty_param_count = ty_param_defs.iter() - .take_while(|x| { - x.default.is_none() && - !ty::is_associated_type(tcx, x.def_id) - }) - .count(); + .take_while(|x| { + x.default.is_none() && + !ty::is_associated_type(tcx, x.def_id) + }) + .count(); if supplied_ty_param_count < required_ty_param_count { let expected = if required_ty_param_count < formal_ty_param_count { "expected at least" @@ -282,10 +289,10 @@ fn ast_path_substs<'tcx,AC,RS>( "expected" }; this.tcx().sess.span_fatal(path.span, - format!("wrong number of type arguments: {} {}, found {}", - expected, - required_ty_param_count, - supplied_ty_param_count).as_slice()); + format!("wrong number of type arguments: {} {}, found {}", + expected, + required_ty_param_count, + supplied_ty_param_count).as_slice()); } else if supplied_ty_param_count > formal_ty_param_count { let expected = if required_ty_param_count < formal_ty_param_count { "expected at most" @@ -293,10 +300,10 @@ fn ast_path_substs<'tcx,AC,RS>( "expected" }; this.tcx().sess.span_fatal(path.span, - format!("wrong number of type arguments: {} {}, found {}", - expected, - formal_ty_param_count, - supplied_ty_param_count).as_slice()); + format!("wrong number of type arguments: {} {}, found {}", + expected, + formal_ty_param_count, + supplied_ty_param_count).as_slice()); } if supplied_ty_param_count > required_ty_param_count @@ -307,13 +314,7 @@ fn ast_path_substs<'tcx,AC,RS>( "add #![feature(default_type_params)] to the crate attributes to enable"); } - let tps = path.segments - .iter() - .flat_map(|s| s.types.iter()) - .map(|a_t| ast_ty_to_ty(this, rscope, &**a_t)) - .collect(); - - let mut substs = Substs::new_type(tps, regions); + let mut substs = Substs::new_type(types, regions); match self_ty { None => { @@ -354,7 +355,47 @@ fn ast_path_substs<'tcx,AC,RS>( param.def_id)) } - substs + return substs; + + fn angle_bracketed_parameters<'tcx, AC, RS>(this: &AC, + rscope: &RS, + data: &ast::AngleBracketedParameterData) + -> (Vec, Vec) + where AC: AstConv<'tcx>, RS: RegionScope + { + let regions: Vec<_> = + data.lifetimes.iter() + .map(|l| ast_region_to_region(this.tcx(), l)) + .collect(); + + let types: Vec<_> = + data.types.iter() + .map(|t| ast_ty_to_ty(this, rscope, &**t)) + .collect(); + + (regions, types) + } + + fn parenthesized_parameters<'tcx,AC>(this: &AC, + binder_id: ast::NodeId, + data: &ast::ParenthesizedParameterData) + -> (Vec, Vec) + where AC: AstConv<'tcx> + { + let binding_rscope = BindingRscope::new(binder_id); + + let inputs = data.inputs.iter() + .map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t)) + .collect(); + let input_ty = ty::mk_tup_or_nil(this.tcx(), inputs); + + let output = match data.output { + Some(ref output_ty) => ast_ty_to_ty(this, &binding_rscope, &**output_ty), + None => ty::mk_nil() + }; + + (Vec::new(), vec![input_ty, output]) + } } pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC, @@ -362,7 +403,8 @@ pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC, trait_def_id: ast::DefId, self_ty: Option, associated_type: Option, - path: &ast::Path) + path: &ast::Path, + binder_id: ast::NodeId) -> Rc where AC: AstConv<'tcx>, RS: RegionScope { @@ -375,7 +417,8 @@ pub fn ast_path_to_trait_ref<'tcx,AC,RS>(this: &AC, &trait_def.generics, self_ty, associated_type, - path) + path, + binder_id) }) } @@ -383,8 +426,10 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( this: &AC, rscope: &RS, did: ast::DefId, - path: &ast::Path) - -> TypeAndSubsts { + path: &ast::Path, + binder_id: ast::NodeId) + -> TypeAndSubsts +{ let tcx = this.tcx(); let ty::Polytype { generics, @@ -397,7 +442,8 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( &generics, None, None, - path); + path, + binder_id); let ty = decl_ty.subst(tcx, &substs); TypeAndSubsts { substs: substs, ty: ty } } @@ -407,24 +453,29 @@ pub fn ast_path_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( /// and/or region variables are substituted. /// /// This is used when checking the constructor in struct literals. -pub fn ast_path_to_ty_relaxed<'tcx, AC: AstConv<'tcx>, - RS:RegionScope>( - this: &AC, - rscope: &RS, - did: ast::DefId, - path: &ast::Path) - -> TypeAndSubsts { +pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>( + this: &AC, + rscope: &RS, + did: ast::DefId, + path: &ast::Path, + binder_id: ast::NodeId) + -> TypeAndSubsts + where AC : AstConv<'tcx>, RS : RegionScope +{ let tcx = this.tcx(); let ty::Polytype { generics, ty: decl_ty } = this.get_item_ty(did); - let substs = if (generics.has_type_params(TypeSpace) || - generics.has_region_params(TypeSpace)) && - path.segments.iter().all(|s| { - s.lifetimes.len() == 0 && s.types.len() == 0 - }) { + let wants_params = + generics.has_type_params(TypeSpace) || generics.has_region_params(TypeSpace); + + let needs_defaults = + wants_params && + path.segments.iter().all(|s| s.parameters.is_empty()); + + let substs = if needs_defaults { let type_params = Vec::from_fn(generics.types.len(TypeSpace), |_| this.ty_infer(path.span)); let region_params = @@ -433,7 +484,7 @@ pub fn ast_path_to_ty_relaxed<'tcx, AC: AstConv<'tcx>, Substs::new(VecPerParamSpace::params_from_type(type_params), VecPerParamSpace::params_from_type(region_params)) } else { - ast_path_substs(this, rscope, did, &generics, None, None, path) + ast_path_substs(this, rscope, did, &generics, None, None, path, binder_id) }; let ty = decl_ty.subst(tcx, &substs); @@ -450,14 +501,14 @@ fn check_path_args(tcx: &ty::ctxt, path: &ast::Path, flags: uint) { if (flags & NO_TPS) != 0u { - if !path.segments.iter().all(|s| s.types.is_empty()) { + if path.segments.iter().any(|s| s.parameters.has_types()) { span_err!(tcx.sess, path.span, E0109, "type parameters are not allowed on this type"); } } if (flags & NO_REGIONS) != 0u { - if !path.segments.last().unwrap().lifetimes.is_empty() { + if path.segments.iter().any(|s| s.parameters.has_lifetimes()) { span_err!(tcx.sess, path.span, E0110, "region parameters are not allowed on this type"); } @@ -538,29 +589,23 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( // FIXME(#12938): This is a hack until we have full support for // DST. match a_def { - def::DefTy(did, _) | def::DefStruct(did) - if Some(did) == this.tcx().lang_items.owned_box() => { - if path.segments - .iter() - .flat_map(|s| s.types.iter()) - .count() > 1 { - span_err!(this.tcx().sess, path.span, E0047, - "`Box` has only one type parameter"); + def::DefTy(did, _) | + def::DefStruct(did) if Some(did) == this.tcx().lang_items.owned_box() => { + let ty = ast_path_to_ty(this, rscope, did, path, id).ty; + match ty::get(ty).sty { + ty::ty_struct(struct_def_id, ref substs) => { + assert_eq!(struct_def_id, did); + assert_eq!(substs.types.len(TypeSpace), 1); + let referent_ty = *substs.types.get(TypeSpace, 0); + Some(ty::mk_uniq(this.tcx(), referent_ty)) + } + _ => { + this.tcx().sess.span_bug( + path.span, + format!("converting `Box` to `{}`", + ty.repr(this.tcx()))[]); + } } - - for inner_ast_type in path.segments - .iter() - .flat_map(|s| s.types.iter()) { - return Some(mk_pointer(this, - rscope, - ast::MutImmutable, - &**inner_ast_type, - Uniq, - |typ| ty::mk_uniq(this.tcx(), typ))); - } - span_err!(this.tcx().sess, path.span, E0113, - "not enough type parameters supplied to `Box`"); - Some(ty::mk_err()) } _ => None } @@ -603,11 +648,7 @@ pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>, .map(|input| { ast_ty_to_ty(this, rscope, &*input.ty) }).collect::>(); - let input_tuple = if input_types.len() == 0 { - ty::mk_nil() - } else { - ty::mk_tup(this.tcx(), input_types) - }; + let input_tuple = ty::mk_tup_or_nil(this.tcx(), input_types); let output_type = ast_ty_to_ty(this, rscope, &*decl.output); let mut substs = Substs::new_type(vec!(input_tuple, output_type), Vec::new()); @@ -693,7 +734,8 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( trait_def_id, None, None, - path); + path, + id); let bounds = match *opt_bounds { None => { conv_existential_bounds(this, @@ -771,7 +813,12 @@ fn associated_ty_to_ty<'tcx,AC,RS>(this: &AC, trait_did, None, Some(for_type), - trait_path); + trait_path, + ast::DUMMY_NODE_ID); // *see below + + // * The trait in a qualified path cannot be "higher-ranked" and + // hence cannot use the parenthetical sugar, so the binder-id is + // irrelevant. debug!("associated_ty_to_ty(trait_ref={})", trait_ref.repr(this.tcx())); @@ -925,7 +972,8 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( trait_def_id, None, None, - path); + path, + id); let empty_bounds: &[ast::TyParamBound] = &[]; let ast_bounds = match *bounds { Some(ref b) => b.as_slice(), @@ -942,7 +990,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( bounds) } def::DefTy(did, _) | def::DefStruct(did) => { - ast_path_to_ty(this, rscope, did, path).ty + ast_path_to_ty(this, rscope, did, path, id).ty } def::DefTyParam(space, id, n) => { check_path_args(tcx, path, NO_TPS | NO_REGIONS); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index bcb875a6aa83..322275218e1b 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3481,11 +3481,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, // Tuple up the arguments and insert the resulting function type into // the `unboxed_closures` table. - fn_ty.sig.inputs = if fn_ty.sig.inputs.len() == 0 { - vec![ty::mk_nil()] - } else { - vec![ty::mk_tup(fcx.tcx(), fn_ty.sig.inputs)] - }; + fn_ty.sig.inputs = vec![ty::mk_tup_or_nil(fcx.tcx(), fn_ty.sig.inputs)]; let kind = match kind { ast::FnUnboxedClosureKind => ty::FnUnboxedClosureKind, @@ -4478,7 +4474,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt, let type_and_substs = astconv::ast_path_to_ty_relaxed(fcx, fcx.infcx(), struct_id, - path); + path, + expr.id); match fcx.mk_subty(false, infer::Misc(path.span), actual_structure_type, @@ -5339,6 +5336,7 @@ pub fn instantiate_path(fcx: &FnCtxt, Some(space) => { push_explicit_parameters_from_segment_to_substs(fcx, space, + path.span, type_defs, region_defs, segment, @@ -5374,13 +5372,13 @@ pub fn instantiate_path(fcx: &FnCtxt, fcx: &FnCtxt, segment: &ast::PathSegment) { - for typ in segment.types.iter() { + for typ in segment.parameters.types().iter() { span_err!(fcx.tcx().sess, typ.span, E0085, "type parameters may not appear here"); break; } - for lifetime in segment.lifetimes.iter() { + for lifetime in segment.parameters.lifetimes().iter() { span_err!(fcx.tcx().sess, lifetime.span, E0086, "lifetime parameters may not appear here"); break; @@ -5390,6 +5388,7 @@ pub fn instantiate_path(fcx: &FnCtxt, fn push_explicit_parameters_from_segment_to_substs( fcx: &FnCtxt, space: subst::ParamSpace, + span: Span, type_defs: &VecPerParamSpace, region_defs: &VecPerParamSpace, segment: &ast::PathSegment, @@ -5412,10 +5411,31 @@ pub fn instantiate_path(fcx: &FnCtxt, * span of the N+1'th parameter. */ + match segment.parameters { + ast::AngleBracketedParameters(ref data) => { + push_explicit_angle_bracketed_parameters_from_segment_to_substs( + fcx, space, type_defs, region_defs, data, substs); + } + + ast::ParenthesizedParameters(ref data) => { + push_explicit_parenthesized_parameters_from_segment_to_substs( + fcx, space, span, type_defs, data, substs); + } + } + } + + fn push_explicit_angle_bracketed_parameters_from_segment_to_substs( + fcx: &FnCtxt, + space: subst::ParamSpace, + type_defs: &VecPerParamSpace, + region_defs: &VecPerParamSpace, + data: &ast::AngleBracketedParameterData, + substs: &mut Substs) + { { let type_count = type_defs.len(space); assert_eq!(substs.types.len(space), 0); - for (i, typ) in segment.types.iter().enumerate() { + for (i, typ) in data.types.iter().enumerate() { let t = fcx.to_ty(&**typ); if i < type_count { substs.types.push(space, t); @@ -5424,7 +5444,7 @@ pub fn instantiate_path(fcx: &FnCtxt, "too many type parameters provided: \ expected at most {} parameter(s), \ found {} parameter(s)", - type_count, segment.types.len()); + type_count, data.types.len()); substs.types.truncate(space, 0); } } @@ -5433,7 +5453,7 @@ pub fn instantiate_path(fcx: &FnCtxt, { let region_count = region_defs.len(space); assert_eq!(substs.regions().len(space), 0); - for (i, lifetime) in segment.lifetimes.iter().enumerate() { + for (i, lifetime) in data.lifetimes.iter().enumerate() { let r = ast_region_to_region(fcx.tcx(), lifetime); if i < region_count { substs.mut_regions().push(space, r); @@ -5442,13 +5462,59 @@ pub fn instantiate_path(fcx: &FnCtxt, "too many lifetime parameters provided: \ expected {} parameter(s), found {} parameter(s)", region_count, - segment.lifetimes.len()); + data.lifetimes.len()); substs.mut_regions().truncate(space, 0); } } } } + fn push_explicit_parenthesized_parameters_from_segment_to_substs( + fcx: &FnCtxt, + space: subst::ParamSpace, + span: Span, + type_defs: &VecPerParamSpace, + data: &ast::ParenthesizedParameterData, + substs: &mut Substs) + { + /*! + * As with + * `push_explicit_angle_bracketed_parameters_from_segment_to_substs`, + * but intended for `Foo(A,B) -> C` form. This expands to + * roughly the same thing as `Foo<(A,B),C>`. One important + * difference has to do with the treatment of anonymous + * regions, which are translated into bound regions (NYI). + */ + + let type_count = type_defs.len(space); + if type_count < 2 { + span_err!(fcx.tcx().sess, span, E0167, + "parenthesized form always supplies 2 type parameters, \ + but only {} parameter(s) were expected", + type_count); + } + + let input_tys: Vec = + data.inputs.iter().map(|ty| fcx.to_ty(&**ty)).collect(); + + let tuple_ty = + ty::mk_tup_or_nil(fcx.tcx(), input_tys); + + if type_count >= 1 { + substs.types.push(space, tuple_ty); + } + + let output_ty: Option = + data.output.as_ref().map(|ty| fcx.to_ty(&**ty)); + + let output_ty = + output_ty.unwrap_or(ty::mk_nil()); + + if type_count >= 2 { + substs.types.push(space, output_ty); + } + } + fn adjust_type_parameters( fcx: &FnCtxt, span: Span, diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 0374a64261f0..7a26cc511145 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1340,7 +1340,8 @@ pub fn instantiate_trait_ref<'tcx,AC>(this: &AC, trait_did, Some(self_ty), associated_type, - &ast_trait_ref.path); + &ast_trait_ref.path, + ast_trait_ref.ref_id); this.tcx().trait_refs.borrow_mut().insert(ast_trait_ref.ref_id, trait_ref.clone()); diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index bfa0f94a7475..64efae486b7e 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -1108,7 +1108,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { &ast::TraitTyParamBound(ref tr) => { let last_seg = tr.path.segments.last().unwrap(); let mut insert = Vec::new(); - for (i, lt) in last_seg.lifetimes.iter().enumerate() { + let lifetimes = last_seg.parameters.lifetimes(); + for (i, lt) in lifetimes.iter().enumerate() { if region_names.contains(<.name) { insert.push(i); } @@ -1116,7 +1117,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { let rebuild_info = RebuildPathInfo { path: &tr.path, indexes: insert, - expected: last_seg.lifetimes.len(), + expected: lifetimes.len(), anon_nums: &HashSet::new(), region_names: region_names }; @@ -1257,7 +1258,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { let expected = generics.regions.len(subst::TypeSpace); let lifetimes = - &path.segments.last().unwrap().lifetimes; + path.segments.last().unwrap().parameters.lifetimes(); let mut insert = Vec::new(); if lifetimes.len() == 0 { let anon = self.cur_anon.get(); @@ -1357,7 +1358,8 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { fn rebuild_path(&self, rebuild_info: RebuildPathInfo, lifetime: ast::Lifetime) - -> ast::Path { + -> ast::Path + { let RebuildPathInfo { path, indexes, @@ -1367,37 +1369,48 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { } = rebuild_info; let last_seg = path.segments.last().unwrap(); - let mut new_lts = Vec::new(); - if last_seg.lifetimes.len() == 0 { - // traverse once to see if there's a need to insert lifetime - let need_insert = range(0, expected).any(|i| { - indexes.contains(&i) - }); - if need_insert { - for i in range(0, expected) { - if indexes.contains(&i) { - new_lts.push(lifetime); - } else { - new_lts.push(self.life_giver.give_lifetime()); + let new_parameters = match last_seg.parameters { + ast::ParenthesizedParameters(..) => { + last_seg.parameters.clone() + } + + ast::AngleBracketedParameters(ref data) => { + let mut new_lts = Vec::new(); + if data.lifetimes.len() == 0 { + // traverse once to see if there's a need to insert lifetime + let need_insert = range(0, expected).any(|i| { + indexes.contains(&i) + }); + if need_insert { + for i in range(0, expected) { + if indexes.contains(&i) { + new_lts.push(lifetime); + } else { + new_lts.push(self.life_giver.give_lifetime()); + } + } + } + } else { + for (i, lt) in data.lifetimes.iter().enumerate() { + if indexes.contains(&i) { + new_lts.push(lifetime); + } else { + new_lts.push(*lt); + } } } + let new_types = data.types.map(|t| { + self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names) + }); + ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: new_lts, + types: new_types + }) } - } else { - for (i, lt) in last_seg.lifetimes.iter().enumerate() { - if indexes.contains(&i) { - new_lts.push(lifetime); - } else { - new_lts.push(*lt); - } - } - } - let new_types = last_seg.types.map(|t| { - self.rebuild_arg_ty_or_output(&**t, lifetime, anon_nums, region_names) - }); + }; let new_seg = ast::PathSegment { identifier: last_seg.identifier, - lifetimes: new_lts, - types: new_types, + parameters: new_parameters }; let mut new_segs = Vec::new(); new_segs.push_all(path.segments.init()); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f96b3916f06d..cfd183b4c453 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1641,10 +1641,23 @@ pub struct PathSegment { impl Clean for ast::PathSegment { fn clean(&self, cx: &DocContext) -> PathSegment { + let (lifetimes, types) = match self.parameters { + ast::AngleBracketedParameters(ref data) => { + (data.lifetimes.clean(cx), data.types.clean(cx)) + } + + ast::ParenthesizedParameters(ref data) => { + // FIXME -- rustdoc should be taught about Foo() notation + let inputs = Tuple(data.inputs.clean(cx)); + let output = data.output.as_ref().map(|t| t.clean(cx)).unwrap_or(Tuple(Vec::new())); + (Vec::new(), vec![inputs, output]) + } + }; + PathSegment { name: self.identifier.clean(cx), - lifetimes: self.lifetimes.clean(cx), - types: self.types.clean(cx), + lifetimes: lifetimes, + types: types, } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 078e393eb28e..a2089a3e2a35 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -171,7 +171,7 @@ pub struct Path { /// module (like paths in an import). pub global: bool, /// The segments in the path: the things separated by `::`. - pub segments: Vec , + pub segments: Vec, } /// A segment of a path: an identifier, an optional lifetime, and a set of @@ -180,12 +180,107 @@ pub struct Path { pub struct PathSegment { /// The identifier portion of this path segment. pub identifier: Ident, + + /// Type/lifetime parameters attached to this path. They come in + /// two flavors: `Path` and `Path(A,B) -> C`. Note that + /// this is more than just simple syntactic sugar; the use of + /// parens affects the region binding rules, so we preserve the + /// distinction. + pub parameters: PathParameters, +} + +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub enum PathParameters { + AngleBracketedParameters(AngleBracketedParameterData), + ParenthesizedParameters(ParenthesizedParameterData), +} + +impl PathParameters { + pub fn none() -> PathParameters { + AngleBracketedParameters(AngleBracketedParameterData { + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }) + } + + pub fn is_empty(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => data.is_empty(), + + // Even if the user supplied no types, something like + // `X()` is equivalent to `X<(),()>`. + ParenthesizedParameters(..) => false, + } + } + + pub fn has_lifetimes(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), + ParenthesizedParameters(_) => false, + } + } + + pub fn has_types(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => !data.types.is_empty(), + ParenthesizedParameters(..) => true, + } + } + + pub fn types(&self) -> Vec<&P> { + /*! + * Returns the types that the user wrote. Note that these do not + * necessarily map to the type parameters in the parenthesized case. + */ + match *self { + AngleBracketedParameters(ref data) => { + data.types.iter().collect() + } + ParenthesizedParameters(ref data) => { + data.inputs.iter() + .chain(data.output.iter()) + .collect() + } + } + } + + pub fn lifetimes(&self) -> Vec<&Lifetime> { + match *self { + AngleBracketedParameters(ref data) => { + data.lifetimes.iter().collect() + } + ParenthesizedParameters(_) => { + Vec::new() + } + } + } +} + +/// A path like `Foo<'a, T>` +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub struct AngleBracketedParameterData { /// The lifetime parameters for this path segment. pub lifetimes: Vec, /// The type parameters for this path segment, if present. pub types: OwnedSlice>, } +impl AngleBracketedParameterData { + fn is_empty(&self) -> bool { + self.lifetimes.is_empty() && self.types.is_empty() + } +} + +/// A path like `Foo(A,B) -> C` +#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] +pub struct ParenthesizedParameterData { + /// `(A,B)` + pub inputs: Vec>, + + /// `C` + pub output: Option>, +} + pub type CrateNum = u32; pub type NodeId = u32; diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 3aa60236d709..2e3a15bfd4b4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -171,8 +171,10 @@ pub fn ident_to_path(s: Span, identifier: Ident) -> Path { segments: vec!( ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }) } ), } @@ -681,11 +683,11 @@ pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> boo false } else { for (idx,seg) in a.iter().enumerate() { - if (seg.identifier.name != b[idx].identifier.name) + if seg.identifier.name != b[idx].identifier.name // FIXME #7743: ident -> name problems in lifetime comparison? - || (seg.lifetimes != b[idx].lifetimes) // can types contain idents? - || (seg.types != b[idx].types) { + || seg.parameters != b[idx].parameters + { return false; } } @@ -747,12 +749,10 @@ impl PostExpansionMethod for Method { mod test { use ast::*; use super::*; - use owned_slice::OwnedSlice; fn ident_to_segment(id : &Ident) -> PathSegment { - PathSegment {identifier:id.clone(), - lifetimes: Vec::new(), - types: OwnedSlice::empty()} + PathSegment {identifier: id.clone(), + parameters: PathParameters::none()} } #[test] fn idents_name_eq_test() { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index dc4eaf7d7ade..5921d630b897 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -313,14 +313,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> { .map(|ident| { ast::PathSegment { identifier: ident, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect(); segments.push(ast::PathSegment { identifier: last_identifier, - lifetimes: lifetimes, - types: OwnedSlice::from_vec(types), + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + }) }); ast::Path { span: sp, diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index e5e93a7d8b3b..aa18b1be31ac 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -12,7 +12,6 @@ use ast; use codemap::Span; use ext::base::*; use ext::base; -use owned_slice::OwnedSlice; use parse::token; use parse::token::{str_to_ident}; use ptr::P; @@ -52,8 +51,7 @@ pub fn expand_syntax_ext<'cx>(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree] segments: vec!( ast::PathSegment { identifier: res, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6535c8e89fd4..79e2c656e41f 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -166,6 +166,22 @@ pub trait Folder { noop_fold_path(p, self) } + fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters { + noop_fold_path_parameters(p, self) + } + + fn fold_angle_bracketed_parameter_data(&mut self, p: AngleBracketedParameterData) + -> AngleBracketedParameterData + { + noop_fold_angle_bracketed_parameter_data(p, self) + } + + fn fold_parenthesized_parameter_data(&mut self, p: ParenthesizedParameterData) + -> ParenthesizedParameterData + { + noop_fold_parenthesized_parameter_data(p, self) + } + fn fold_local(&mut self, l: P) -> P { noop_fold_local(l, self) } @@ -480,15 +496,43 @@ pub fn noop_fold_uint(i: uint, _: &mut T) -> uint { pub fn noop_fold_path(Path {global, segments, span}: Path, fld: &mut T) -> Path { Path { global: global, - segments: segments.move_map(|PathSegment {identifier, lifetimes, types}| PathSegment { + segments: segments.move_map(|PathSegment {identifier, parameters}| PathSegment { identifier: fld.fold_ident(identifier), - lifetimes: fld.fold_lifetimes(lifetimes), - types: types.move_map(|typ| fld.fold_ty(typ)), + parameters: fld.fold_path_parameters(parameters), }), span: fld.new_span(span) } } +pub fn noop_fold_path_parameters(path_parameters: PathParameters, fld: &mut T) + -> PathParameters +{ + match path_parameters { + AngleBracketedParameters(data) => + AngleBracketedParameters(fld.fold_angle_bracketed_parameter_data(data)), + ParenthesizedParameters(data) => + ParenthesizedParameters(fld.fold_parenthesized_parameter_data(data)), + } +} + +pub fn noop_fold_angle_bracketed_parameter_data(data: AngleBracketedParameterData, + fld: &mut T) + -> AngleBracketedParameterData +{ + let AngleBracketedParameterData { lifetimes, types } = data; + AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes), + types: types.move_map(|ty| fld.fold_ty(ty)) } +} + +pub fn noop_fold_parenthesized_parameter_data(data: ParenthesizedParameterData, + fld: &mut T) + -> ParenthesizedParameterData +{ + let ParenthesizedParameterData { inputs, output } = data; + ParenthesizedParameterData { inputs: inputs.move_map(|ty| fld.fold_ty(ty)), + output: output.map(|ty| fld.fold_ty(ty)) } +} + pub fn noop_fold_local(l: P, fld: &mut T) -> P { l.map(|Local {id, pat, ty, init, source, span}| Local { id: fld.new_id(id), diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 83499ec54c67..996708b21742 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -749,8 +749,7 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("a"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }), @@ -768,13 +767,11 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("a"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }, ast::PathSegment { identifier: str_to_ident("b"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ) }), @@ -952,8 +949,7 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("d"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }), @@ -974,8 +970,7 @@ mod test { segments: vec!( ast::PathSegment { identifier: str_to_ident("b"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }), @@ -1022,8 +1017,7 @@ mod test { ast::PathSegment { identifier: str_to_ident("int"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } ), }, None, ast::DUMMY_NODE_ID), @@ -1072,10 +1066,8 @@ mod test { identifier: str_to_ident( "b"), - lifetimes: - Vec::new(), - types: - OwnedSlice::empty() + parameters: + ast::PathParameters::none(), } ), }), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fd244a443a8a..1c65a47350ea 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1487,9 +1487,9 @@ impl<'a> Parser<'a> { trait_name: trait_name.path, item_name: item_name, })) - } else if self.token == token::ModSep - || self.token.is_ident() - || self.token.is_path() { + } else if self.token == token::ModSep || + self.token.is_ident() || + self.token.is_path() { // NAMED TYPE let mode = if plus_allowed { LifetimeAndTypesAndBounds @@ -1771,27 +1771,36 @@ impl<'a> Parser<'a> { let identifier = self.parse_ident(); // Parse types, optionally. - let (lifetimes, types) = if self.eat_lt(false) { - self.parse_generic_values_after_lt() - } else if false && self.eat(&token::LParen) { - let mut types = self.parse_seq_to_end( - &token::RParen, + let parameters = if self.eat_lt(false) { + let (lifetimes, types) = self.parse_generic_values_after_lt(); + + ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + }) + } else if self.eat(&token::OpenDelim(token::Paren)) { + let inputs = self.parse_seq_to_end( + &token::CloseDelim(token::Paren), seq_sep_trailing_allowed(token::Comma), |p| p.parse_ty(true)); - if self.eat(&token::RArrow) { - types.push(self.parse_ty(true)) - } + let output_ty = if self.eat(&token::RArrow) { + Some(self.parse_ty(true)) + } else { + None + }; - (Vec::new(), types) + ast::ParenthesizedParameters(ast::ParenthesizedParameterData { + inputs: inputs, + output: output_ty + }) } else { - (Vec::new(), Vec::new()) + ast::PathParameters::none() }; // Assemble and push the result. segments.push(ast::PathSegment { identifier: identifier, - lifetimes: lifetimes, - types: OwnedSlice::from_vec(types), }); + parameters: parameters }); // Continue only if we see a `::` if !self.eat(&token::ModSep) { @@ -1810,9 +1819,13 @@ impl<'a> Parser<'a> { // If we do not see a `::`, stop. if !self.eat(&token::ModSep) { - segments.push(ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty() }); + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: Vec::new(), + types: OwnedSlice::empty(), + }) + }); return segments; } @@ -1820,9 +1833,13 @@ impl<'a> Parser<'a> { if self.eat_lt(false) { // Consumed `a::b::<`, go look for types let (lifetimes, types) = self.parse_generic_values_after_lt(); - segments.push(ast::PathSegment { identifier: identifier, - lifetimes: lifetimes, - types: OwnedSlice::from_vec(types) }); + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::AngleBracketedParameters(ast::AngleBracketedParameterData { + lifetimes: lifetimes, + types: OwnedSlice::from_vec(types), + }), + }); // Consumed `a::b::`, check for `::` before proceeding if !self.eat(&token::ModSep) { @@ -1830,9 +1847,10 @@ impl<'a> Parser<'a> { } } else { // Consumed `a::`, go look for `b` - segments.push(ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty() }); + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::PathParameters::none(), + }); } } } @@ -1847,9 +1865,10 @@ impl<'a> Parser<'a> { let identifier = self.parse_ident(); // Assemble and push the result. - segments.push(ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), }); + segments.push(ast::PathSegment { + identifier: identifier, + parameters: ast::PathParameters::none() + }); // If we do not see a `::`, stop. if !self.eat(&token::ModSep) { @@ -3455,13 +3474,9 @@ impl<'a> Parser<'a> { }, _ => { if !enum_path.global && - enum_path.segments.len() == 1 && - enum_path.segments[0] - .lifetimes - .len() == 0 && - enum_path.segments[0] - .types - .len() == 0 { + enum_path.segments.len() == 1 && + enum_path.segments[0].parameters.is_empty() + { // it could still be either an enum // or an identifier pattern, resolve // will sort it out: @@ -3960,8 +3975,7 @@ impl<'a> Parser<'a> { fn trait_ref_from_ident(ident: Ident, span: Span) -> ast::TraitRef { let segment = ast::PathSegment { identifier: ident, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none() }; let path = ast::Path { span: span, @@ -5677,8 +5691,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; @@ -5712,8 +5725,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; @@ -5730,8 +5742,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; @@ -5752,8 +5763,7 @@ impl<'a> Parser<'a> { segments: path.into_iter().map(|identifier| { ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), } }).collect() }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 106e3f1faae8..d83ea5f76b1f 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1995,14 +1995,34 @@ impl<'a> State<'a> { try!(self.print_ident(segment.identifier)); - if !segment.lifetimes.is_empty() || !segment.types.is_empty() { - if colons_before_params { - try!(word(&mut self.s, "::")) - } + try!(self.print_path_parameters(&segment.parameters, colons_before_params)); + } + + match *opt_bounds { + None => Ok(()), + Some(ref bounds) => self.print_bounds("+", bounds) + } + } + + fn print_path_parameters(&mut self, + parameters: &ast::PathParameters, + colons_before_params: bool) + -> IoResult<()> + { + if parameters.is_empty() { + return Ok(()); + } + + if colons_before_params { + try!(word(&mut self.s, "::")) + } + + match *parameters { + ast::AngleBracketedParameters(ref data) => { try!(word(&mut self.s, "<")); let mut comma = false; - for lifetime in segment.lifetimes.iter() { + for lifetime in data.lifetimes.iter() { if comma { try!(self.word_space(",")) } @@ -2010,24 +2030,38 @@ impl<'a> State<'a> { comma = true; } - if !segment.types.is_empty() { + if !data.types.is_empty() { if comma { try!(self.word_space(",")) } try!(self.commasep( Inconsistent, - segment.types.as_slice(), + data.types.as_slice(), |s, ty| s.print_type(&**ty))); } try!(word(&mut self.s, ">")) } + + ast::ParenthesizedParameters(ref data) => { + try!(word(&mut self.s, "(")); + try!(self.commasep( + Inconsistent, + data.inputs.as_slice(), + |s, ty| s.print_type(&**ty))); + try!(word(&mut self.s, ")")); + + match data.output { + None => { } + Some(ref ty) => { + try!(self.word_space("->")); + try!(self.print_type(&**ty)); + } + } + } } - match *opt_bounds { - None => Ok(()), - Some(ref bounds) => self.print_bounds("+", bounds) - } + Ok(()) } fn print_path(&mut self, path: &ast::Path, diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 0f86fb751dae..6a4ab365a50b 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -14,7 +14,6 @@ use codemap::DUMMY_SP; use codemap; use fold::Folder; use fold; -use owned_slice::OwnedSlice; use parse::token::InternedString; use parse::token::special_idents; use parse::token; @@ -181,13 +180,11 @@ impl<'a> fold::Folder for PreludeInjector<'a> { segments: vec!( ast::PathSegment { identifier: token::str_to_ident("std"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }, ast::PathSegment { identifier: token::str_to_ident("prelude"), - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }), }; diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 37586f6abd7d..a7db8e800a9d 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -453,8 +453,7 @@ fn path_node(ids: Vec ) -> ast::Path { global: false, segments: ids.into_iter().map(|identifier| ast::PathSegment { identifier: identifier, - lifetimes: Vec::new(), - types: OwnedSlice::empty(), + parameters: ast::PathParameters::none(), }).collect() } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 86ee23d71a6b..b4141af07336 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -407,11 +407,23 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { for segment in path.segments.iter() { visitor.visit_ident(path.span, segment.identifier); - for typ in segment.types.iter() { - visitor.visit_ty(&**typ); - } - for lifetime in segment.lifetimes.iter() { - visitor.visit_lifetime_ref(lifetime); + match segment.parameters { + ast::AngleBracketedParameters(ref data) => { + for typ in data.types.iter() { + visitor.visit_ty(&**typ); + } + for lifetime in data.lifetimes.iter() { + visitor.visit_lifetime_ref(lifetime); + } + } + ast::ParenthesizedParameters(ref data) => { + for typ in data.inputs.iter() { + visitor.visit_ty(&**typ); + } + for typ in data.output.iter() { + visitor.visit_ty(&**typ); + } + } } } } diff --git a/src/test/compile-fail/issue-14092.rs b/src/test/compile-fail/issue-14092.rs index 4d663d00fb29..0ab37a888267 100644 --- a/src/test/compile-fail/issue-14092.rs +++ b/src/test/compile-fail/issue-14092.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn fn1(0: Box) {} //~ ERROR: not enough type parameters supplied to `Box` +fn fn1(0: Box) {} //~ ERROR: wrong number of type arguments: expected 1, found 0 fn main() {} diff --git a/src/test/compile-fail/issue-18423.rs b/src/test/compile-fail/issue-18423.rs new file mode 100644 index 000000000000..63b110b55793 --- /dev/null +++ b/src/test/compile-fail/issue-18423.rs @@ -0,0 +1,18 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that `Box` cannot be used with a lifetime parameter. + +struct Foo<'a> { + x: Box<'a, int> //~ ERROR wrong number of lifetime parameters +} + +pub fn main() { +} diff --git a/src/test/compile-fail/unboxed-closure-sugar-default.rs b/src/test/compile-fail/unboxed-closure-sugar-default.rs new file mode 100644 index 000000000000..9866a2000452 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-default.rs @@ -0,0 +1,37 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test interaction between unboxed closure sugar and default type +// parameters (should be exactly as if angle brackets were used). + +#![feature(default_type_params)] +#![allow(dead_code)] + +struct Foo { + t: T, u: U +} + +trait Eq { } +impl Eq for X { } +fn eq>() { } + +fn test<'a,'b>() { + // Parens are equivalent to omitting default in angle. + eq::< Foo<(int,),()>, Foo(int) >(); + + // In angle version, we supply something other than the default + eq::< Foo<(int,),(),int>, Foo(int) >(); + //~^ ERROR not implemented + + // Supply default explicitly. + eq::< Foo<(int,),(),(int,)>, Foo(int) >(); +} + +fn main() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-equiv.rs b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs new file mode 100644 index 000000000000..c38010c1ee26 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-equiv.rs @@ -0,0 +1,39 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the unboxed closure sugar can be used with an arbitrary +// struct type and that it is equivalent to the same syntax using +// angle brackets. This test covers only simple types and in +// particular doesn't test bound regions. + +#![allow(dead_code)] + +struct Foo { + t: T, u: U +} + +trait Eq { } +impl Eq for X { } +fn eq>() { } + +fn test<'a,'b>() { + // No errors expected: + eq::< Foo<(),()>, Foo() >(); + eq::< Foo<(int,),()>, Foo(int) >(); + eq::< Foo<(int,uint),()>, Foo(int,uint) >(); + eq::< Foo<(int,uint),uint>, Foo(int,uint) -> uint >(); + eq::< Foo<(&'a int,&'b uint),uint>, Foo(&'a int,&'b uint) -> uint >(); + + // Errors expected: + eq::< Foo<(),()>, Foo(char) >(); + //~^ ERROR not implemented +} + +fn main() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs index f51160a1b233..d89c3802508c 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-nonexistent-trait.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn f int>(x: F) {} //~ ERROR unresolved trait +fn f int>(x: F) {} //~ ERROR nonexistent trait `Nonexist` type Typedef = int; diff --git a/src/test/compile-fail/unboxed-closure-sugar-region.rs b/src/test/compile-fail/unboxed-closure-sugar-region.rs new file mode 100644 index 000000000000..962e233dea69 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-region.rs @@ -0,0 +1,45 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test interaction between unboxed closure sugar and region +// parameters (should be exactly as if angle brackets were used +// and regions omitted). + +#![feature(default_type_params)] +#![allow(dead_code)] + +use std::kinds::marker; + +struct Foo<'a,T,U> { + t: T, + u: U, + m: marker::InvariantLifetime<'a> +} + +trait Eq { } +impl Eq for X { } +fn eq>() { } +fn same_type>(a: A, b: B) { } + +fn test<'a,'b>() { + // Parens are equivalent to omitting default in angle. + eq::< Foo<(int,),()>, Foo(int) >(); + + // Here we specify 'static explicitly in angle-bracket version. + // Parenthesized winds up getting inferred. + eq::< Foo<'static, (int,),()>, Foo(int) >(); +} + +fn test2(x: Foo<(int,),()>, y: Foo(int)) { + // Here, the omitted lifetimes are expanded to distinct things. + same_type(x, y) //~ ERROR cannot infer +} + +fn main() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs new file mode 100644 index 000000000000..e122b87b1e0f --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct One; + +fn foo(_: One()) //~ ERROR wrong number of type arguments +{} + +fn main() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs new file mode 100644 index 000000000000..7a66abb39df5 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Three; + +fn foo(_: Three()) //~ ERROR wrong number of type arguments +{} + +fn main() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs new file mode 100644 index 000000000000..e265a3d56b87 --- /dev/null +++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-number-number-type-parameters.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Zero; + +fn foo(_: Zero()) //~ ERROR wrong number of type arguments +{} + +fn main() { } diff --git a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs index a751ae1c518e..1394f8fa65fc 100644 --- a/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs +++ b/src/test/compile-fail/unboxed-closure-sugar-wrong-trait.rs @@ -11,7 +11,7 @@ trait Trait {} fn f int>(x: F) {} -//~^ ERROR unboxed function trait must be one of `Fn`, `FnMut`, or `FnOnce` +//~^ ERROR wrong number of type arguments: expected 0, found 2 fn main() {} diff --git a/src/test/run-pass/unboxed-closures-prelude.rs b/src/test/run-pass/unboxed-closures-prelude.rs index 4226ed427e72..f9d2ba02123c 100644 --- a/src/test/run-pass/unboxed-closures-prelude.rs +++ b/src/test/run-pass/unboxed-closures-prelude.rs @@ -13,7 +13,7 @@ #![feature(unboxed_closures, unboxed_closure_sugar)] fn main() { - let task: Box<|: int| -> int> = box |: x| x; + let task: Box int> = box |: x| x; task.call_once((0i, )); } diff --git a/src/test/run-pass/unboxed-closures-sugar-1.rs b/src/test/run-pass/unboxed-closures-sugar-1.rs new file mode 100644 index 000000000000..b358e7ce2883 --- /dev/null +++ b/src/test/run-pass/unboxed-closures-sugar-1.rs @@ -0,0 +1,34 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the unboxed closure sugar can be used with an arbitrary +// struct type and that it is equivalent to the same syntax using +// angle brackets. This test covers only simple types and in +// particular doesn't test bound regions. + +#![allow(dead_code)] + +struct Foo { + t: T, u: U +} + +trait Eq { } +impl Eq for X { } +fn eq>() { } + +fn test<'a,'b>() { + eq::< Foo<(),()>, Foo() >(); + eq::< Foo<(int,),()>, Foo(int) >(); + eq::< Foo<(int,uint),()>, Foo(int,uint) >(); + eq::< Foo<(int,uint),uint>, Foo(int,uint) -> uint >(); + eq::< Foo<(&'a int,&'b uint),uint>, Foo(&'a int,&'b uint) -> uint >(); +} + +fn main() { } diff --git a/src/test/run-pass/unboxed-closures-sugar-object.rs b/src/test/run-pass/unboxed-closures-sugar-object.rs new file mode 100644 index 000000000000..3b38f72432f1 --- /dev/null +++ b/src/test/run-pass/unboxed-closures-sugar-object.rs @@ -0,0 +1,34 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test unboxed closure sugar used in object types. + +#![allow(dead_code)] + +struct Foo { + t: T, u: U +} + +trait Getter { + fn get(&self, arg: A) -> R; +} + +struct Identity; +impl Getter for Identity { + fn get(&self, arg: X) -> X { + arg + } +} + +fn main() { + let x: &Getter(int) -> (int,) = &Identity; + let (y,) = x.get((22,)); + assert_eq!(y, 22); +} diff --git a/src/test/run-pass/unboxed-closures-unboxing-shim.rs b/src/test/run-pass/unboxed-closures-unboxing-shim.rs index 0a7baa3ba369..426352cadd87 100644 --- a/src/test/run-pass/unboxed-closures-unboxing-shim.rs +++ b/src/test/run-pass/unboxed-closures-unboxing-shim.rs @@ -13,7 +13,7 @@ use std::ops::FnOnce; fn main() { - let task: Box<|: int| -> int> = box |: x| x; + let task: Box int> = box |: x| x; assert!(task.call_once((1234i,)) == 1234i); } From d0fa4c6239accc08aae11d9db3e13d4153add432 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 4 Nov 2014 16:25:15 -0500 Subject: [PATCH 21/37] Remove the unboxed closure `|:|` notation from types and trait references completely. --- src/librustc/middle/resolve.rs | 37 +---------- src/librustc/middle/resolve_lifetime.rs | 15 ----- src/librustc/middle/save/mod.rs | 2 +- src/librustc/middle/typeck/astconv.rs | 55 +--------------- src/librustc/middle/typeck/collect.rs | 57 +--------------- .../middle/typeck/infer/error_reporting.rs | 3 - src/librustdoc/clean/inline.rs | 1 - src/librustdoc/clean/mod.rs | 17 ----- src/librustdoc/html/format.rs | 6 +- src/libsyntax/ast.rs | 16 ----- src/libsyntax/ast_map/mod.rs | 3 - src/libsyntax/feature_gate.rs | 5 -- src/libsyntax/fold.rs | 23 ------- src/libsyntax/parse/parser.rs | 66 +++++-------------- src/libsyntax/print/pprust.rs | 56 ++-------------- src/libsyntax/visit.rs | 13 ---- .../run-pass/unboxed-closures-manual-impl.rs | 2 +- 17 files changed, 29 insertions(+), 348 deletions(-) diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 34f0cb7c1982..0420506d0017 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -40,7 +40,7 @@ use syntax::ast::{TupleVariantKind, Ty, TyBool, TyChar, TyClosure, TyF32}; use syntax::ast::{TyF64, TyFloat, TyI, TyI8, TyI16, TyI32, TyI64, TyInt}; use syntax::ast::{TyParam, TyParamBound, TyPath, TyPtr, TyProc, TyQPath}; use syntax::ast::{TyRptr, TyStr, TyU, TyU8, TyU16, TyU32, TyU64, TyUint}; -use syntax::ast::{TypeImplItem, UnboxedFnTyParamBound, UnnamedField}; +use syntax::ast::{TypeImplItem, UnnamedField}; use syntax::ast::{Variant, ViewItem, ViewItemExternCrate}; use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple}; use syntax::ast::{Visibility}; @@ -4523,41 +4523,6 @@ impl<'a> Resolver<'a> { TraitTyParamBound(ref tref) => { self.resolve_trait_reference(id, tref, reference_type) } - UnboxedFnTyParamBound(ref unboxed_function) => { - match self.resolve_path(unboxed_function.ref_id, - &unboxed_function.path, - TypeNS, - true) { - None => { - let path_str = self.path_names_to_string( - &unboxed_function.path); - self.resolve_error(unboxed_function.path.span, - format!("unresolved trait `{}`", - path_str).as_slice()) - } - Some(def) => { - match def { - (DefTrait(_), _) => { - self.record_def(unboxed_function.ref_id, def); - } - _ => { - let msg = - format!("`{}` is not a trait", - self.path_names_to_string( - &unboxed_function.path)); - self.resolve_error(unboxed_function.path.span, - msg.as_slice()); - } - } - } - } - - for argument in unboxed_function.decl.inputs.iter() { - self.resolve_type(&*argument.ty); - } - - self.resolve_type(&*unboxed_function.decl.output); - } RegionTyParamBound(..) => {} } } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index eda4c241f86c..8246970c24ad 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -204,9 +204,6 @@ impl<'a> LifetimeContext<'a> { ast::TraitTyParamBound(ref trait_ref) => { self.visit_trait_ref(trait_ref); } - ast::UnboxedFnTyParamBound(ref fn_decl) => { - self.visit_unboxed_fn_ty_param_bound(&**fn_decl); - } ast::RegionTyParamBound(ref lifetime) => { self.visit_lifetime_ref(lifetime); } @@ -226,18 +223,6 @@ impl<'a> LifetimeContext<'a> { }) } - fn visit_unboxed_fn_ty_param_bound(&mut self, - bound: &ast::UnboxedFnBound) { - self.with(|scope, f| { - f(LateScope(bound.ref_id, &bound.lifetimes, scope)) - }, |v| { - for argument in bound.decl.inputs.iter() { - v.visit_ty(&*argument.ty); - } - v.visit_ty(&*bound.decl.output); - }) - } - /// Visits self by adding a scope and handling recursive walk over the contents with `walk`. fn visit_fn_decl(&mut self, n: ast::NodeId, diff --git a/src/librustc/middle/save/mod.rs b/src/librustc/middle/save/mod.rs index 90a21d479037..b64a160ab1f2 100644 --- a/src/librustc/middle/save/mod.rs +++ b/src/librustc/middle/save/mod.rs @@ -705,7 +705,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { ast::TraitTyParamBound(ref trait_ref) => { trait_ref } - ast::UnboxedFnTyParamBound(..) | ast::RegionTyParamBound(..) => { + ast::RegionTyParamBound(..) => { continue; } }; diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index f2cc3bfd29b9..05d315e5fec3 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -620,15 +620,6 @@ enum PointerTy { Uniq } -impl PointerTy { - fn default_region(&self) -> ty::Region { - match *self { - Uniq => ty::ReStatic, - RPtr(r) => r, - } - } -} - pub fn trait_ref_for_unboxed_function<'tcx, AC: AstConv<'tcx>, RS:RegionScope>( this: &AC, @@ -687,31 +678,6 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( let ty = ast_ty_to_ty(this, rscope, &**ty); return constr(ty::mk_vec(tcx, ty, None)); } - ast::TyUnboxedFn(ref unboxed_function) => { - let ty::TraitRef { - def_id, - substs - } = trait_ref_for_unboxed_function(this, - rscope, - unboxed_function.kind, - &*unboxed_function.decl, - None); - let r = ptr_ty.default_region(); - let tr = ty::mk_trait(this.tcx(), - def_id, - substs, - ty::region_existential_bound(r)); - match ptr_ty { - Uniq => { - return ty::mk_uniq(this.tcx(), tr); - } - RPtr(r) => { - return ty::mk_rptr(this.tcx(), - r, - ty::mt {mutbl: a_seq_mutbl, ty: tr}); - } - } - } ast::TyPath(ref path, ref opt_bounds, id) => { // Note that the "bounds must be empty if path is not a trait" // restriction is enforced in the below case for ty_path, which @@ -941,11 +907,6 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( ty::mk_closure(tcx, fn_decl) } - ast::TyUnboxedFn(..) => { - tcx.sess.span_err(ast_ty.span, - "cannot use unboxed functions here"); - ty::mk_err() - } ast::TyPath(ref path, ref bounds, id) => { let a_def = match tcx.def_map.borrow().find(&id) { None => { @@ -1425,8 +1386,7 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>( let PartitionedBounds { builtin_bounds, trait_bounds, - region_bounds, - unboxed_fn_ty_bounds } = + region_bounds } = partition_bounds(this.tcx(), span, ast_bound_refs.as_slice()); if !trait_bounds.is_empty() { @@ -1437,13 +1397,6 @@ pub fn conv_existential_bounds<'tcx, AC: AstConv<'tcx>, RS:RegionScope>( as closure or object bounds").as_slice()); } - if !unboxed_fn_ty_bounds.is_empty() { - this.tcx().sess.span_err( - span, - format!("only the builtin traits can be used \ - as closure or object bounds").as_slice()); - } - // The "main trait refs", rather annoyingly, have no type // specified for the `Self` parameter of the trait. The reason for // this is that they are, after all, *existential* types, and @@ -1572,7 +1525,6 @@ fn compute_region_bound<'tcx, AC: AstConv<'tcx>, RS:RegionScope>( pub struct PartitionedBounds<'a> { pub builtin_bounds: ty::BuiltinBounds, pub trait_bounds: Vec<&'a ast::TraitRef>, - pub unboxed_fn_ty_bounds: Vec<&'a ast::UnboxedFnBound>, pub region_bounds: Vec<&'a ast::Lifetime>, } @@ -1590,7 +1542,6 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, let mut builtin_bounds = ty::empty_builtin_bounds(); let mut region_bounds = Vec::new(); let mut trait_bounds = Vec::new(); - let mut unboxed_fn_ty_bounds = Vec::new(); let mut trait_def_ids = HashMap::new(); for &ast_bound in ast_bounds.iter() { match *ast_bound { @@ -1635,9 +1586,6 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, ast::RegionTyParamBound(ref l) => { region_bounds.push(l); } - ast::UnboxedFnTyParamBound(ref unboxed_function) => { - unboxed_fn_ty_bounds.push(&**unboxed_function); - } } } @@ -1645,7 +1593,6 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, builtin_bounds: builtin_bounds, trait_bounds: trait_bounds, region_bounds: region_bounds, - unboxed_fn_ty_bounds: unboxed_fn_ty_bounds } } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 7a26cc511145..38de50f68318 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -638,7 +638,7 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, let mut bounds = bounds.chain(ty_param.unbound.iter()); for bound in bounds { match *bound { - ast::TraitTyParamBound(..) | ast::UnboxedFnTyParamBound(..) => { + ast::TraitTyParamBound(..) => { // According to accepted RFC #XXX, we should // eventually accept these, but it will not be // part of this PR. Still, convert to warning to @@ -1356,20 +1356,6 @@ pub fn instantiate_trait_ref<'tcx,AC>(this: &AC, } } -pub fn instantiate_unboxed_fn_ty<'tcx,AC>(this: &AC, - unboxed_function: &ast::UnboxedFnTy, - param_ty: ty::ParamTy) - -> Rc - where AC: AstConv<'tcx> { - let rscope = ExplicitRscope; - let param_ty = param_ty.to_ty(this.tcx()); - Rc::new(astconv::trait_ref_for_unboxed_function(this, - &rscope, - unboxed_function.kind, - &*unboxed_function.decl, - Some(param_ty))) -} - fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc { if trait_id.krate != ast::LOCAL_CRATE { return ty::lookup_trait_def(ccx.tcx, trait_id) @@ -1879,7 +1865,6 @@ fn ty_generics<'tcx,AC>(this: &AC, // In the above example, `ast_trait_ref` is `Iterator`. let ast_trait_ref = match *bound { ast::TraitTyParamBound(ref r) => r, - ast::UnboxedFnTyParamBound(..) => { continue; } ast::RegionTyParamBound(..) => { continue; } }; @@ -2057,45 +2042,8 @@ fn conv_param_bounds<'tcx,AC>(this: &AC, merge_param_bounds(this.tcx(), param_ty, ast_bounds, where_clause); let astconv::PartitionedBounds { builtin_bounds, trait_bounds, - region_bounds, - unboxed_fn_ty_bounds } = + region_bounds } = astconv::partition_bounds(this.tcx(), span, all_bounds.as_slice()); - - let unboxed_fn_ty_bounds = unboxed_fn_ty_bounds.into_iter().map(|b| { - let trait_id = (*this.tcx().def_map.borrow())[b.ref_id].def_id(); - let mut kind = None; - for &(lang_item, this_kind) in [ - (this.tcx().lang_items.fn_trait(), ast::FnUnboxedClosureKind), - (this.tcx().lang_items.fn_mut_trait(), - ast::FnMutUnboxedClosureKind), - (this.tcx().lang_items.fn_once_trait(), - ast::FnOnceUnboxedClosureKind) - ].iter() { - if Some(trait_id) == lang_item { - kind = Some(this_kind); - break - } - } - - let kind = match kind { - Some(kind) => kind, - None => { - this.tcx().sess.span_err(b.path.span, - "unboxed function trait must be one \ - of `Fn`, `FnMut`, or `FnOnce`"); - ast::FnMutUnboxedClosureKind - } - }; - - let rscope = ExplicitRscope; - let param_ty = param_ty.to_ty(this.tcx()); - Rc::new(astconv::trait_ref_for_unboxed_function(this, - &rscope, - kind, - &*b.decl, - Some(param_ty))) - }); - let trait_bounds: Vec> = trait_bounds.into_iter() .map(|b| { @@ -2104,7 +2052,6 @@ fn conv_param_bounds<'tcx,AC>(this: &AC, param_ty.to_ty(this.tcx()), Some(param_ty.to_ty(this.tcx()))) }) - .chain(unboxed_fn_ty_bounds) .collect(); let region_bounds: Vec = region_bounds.into_iter() diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index 64efae486b7e..4882059e91b6 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -1102,9 +1102,6 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { // be passing down a map. ast::RegionTyParamBound(lt) } - &ast::UnboxedFnTyParamBound(ref unboxed_function_type) => { - ast::UnboxedFnTyParamBound((*unboxed_function_type).clone()) - } &ast::TraitTyParamBound(ref tr) => { let last_seg = tr.path.segments.last().unwrap(); let mut insert = Vec::new(); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d87d8776d4a6..a3bf0160471e 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -323,7 +323,6 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt, trait_: associated_trait.clean(cx).map(|bound| { match bound { clean::TraitBound(ty) => ty, - clean::UnboxedFnBound(..) | clean::RegionBound(..) => unreachable!(), } }), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index cfd183b4c453..d3bfe42dcb21 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -476,7 +476,6 @@ impl Clean for ty::TypeParameterDef { #[deriving(Clone, Encodable, Decodable, PartialEq)] pub enum TyParamBound { RegionBound(Lifetime), - UnboxedFnBound(UnboxedFnType), TraitBound(Type) } @@ -484,7 +483,6 @@ impl Clean for ast::TyParamBound { fn clean(&self, cx: &DocContext) -> TyParamBound { match *self { ast::RegionTyParamBound(lt) => RegionBound(lt.clean(cx)), - ast::UnboxedFnTyParamBound(ref ty) => { UnboxedFnBound(ty.clean(cx)) }, ast::TraitTyParamBound(ref t) => TraitBound(t.clean(cx)), } } @@ -599,21 +597,6 @@ impl Clean>> for subst::Substs { } } -#[deriving(Clone, Encodable, Decodable, PartialEq)] -pub struct UnboxedFnType { - pub path: Path, - pub decl: FnDecl -} - -impl Clean for ast::UnboxedFnBound { - fn clean(&self, cx: &DocContext) -> UnboxedFnType { - UnboxedFnType { - path: self.path.clean(cx), - decl: self.decl.clean(cx) - } - } -} - #[deriving(Clone, Encodable, Decodable, PartialEq)] pub struct Lifetime(String); diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f9177c8d6157..ea6cbbb6b833 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -143,9 +143,6 @@ impl fmt::Show for clean::TyParamBound { clean::RegionBound(ref lt) => { write!(f, "{}", *lt) } - clean::UnboxedFnBound(ref ty) => { - write!(f, "{}{}", ty.path, ty.decl) - } clean::TraitBound(ref ty) => { write!(f, "{}", *ty) } @@ -404,8 +401,7 @@ impl fmt::Show for clean::Type { let mut ret = String::new(); for bound in decl.bounds.iter() { match *bound { - clean::RegionBound(..) | - clean::UnboxedFnBound(..) => {} + clean::RegionBound(..) => {} clean::TraitBound(ref t) => { if ret.len() == 0 { ret.push_str(": "); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a2089a3e2a35..6a354fa20e1b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -308,20 +308,11 @@ pub const DUMMY_NODE_ID: NodeId = -1; #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum TyParamBound { TraitTyParamBound(TraitRef), - UnboxedFnTyParamBound(P), RegionTyParamBound(Lifetime) } pub type TyParamBounds = OwnedSlice; -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub struct UnboxedFnBound { - pub path: Path, - pub decl: P, - pub lifetimes: Vec, - pub ref_id: NodeId, -} - #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub struct TyParam { pub ident: Ident, @@ -1089,12 +1080,6 @@ pub struct BareFnTy { pub decl: P } -#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] -pub struct UnboxedFnTy { - pub kind: UnboxedClosureKind, - pub decl: P, -} - #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)] pub enum Ty_ { TyNil, @@ -1107,7 +1092,6 @@ pub enum Ty_ { TyClosure(P), TyProc(P), TyBareFn(P), - TyUnboxedFn(P), TyTup(Vec> ), TyPath(Path, Option, NodeId), // for #7264; see above /// A "qualified path", e.g. ` as SomeTrait>::SomeType` diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index f049b964ff33..3adb062864e1 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -848,9 +848,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { TyBareFn(ref fd) => { self.visit_fn_decl(&*fd.decl); } - TyUnboxedFn(ref fd) => { - self.visit_fn_decl(&*fd.decl); - } _ => {} } visit::walk_ty(self, ty); diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 7701f495f726..80b158a54d36 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -313,11 +313,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { experimental and likely to be removed"); }, - ast::TyUnboxedFn(..) => { - self.gate_feature("unboxed_closure_sugar", - t.span, - "unboxed closure trait sugar is experimental"); - } _ => {} } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 79e2c656e41f..cd4a3d10c488 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -424,12 +424,6 @@ pub fn noop_fold_ty(t: P, fld: &mut T) -> P { decl: fld.fold_fn_decl(decl) })) } - TyUnboxedFn(f) => { - TyUnboxedFn(f.map(|UnboxedFnTy {decl, kind}| UnboxedFnTy { - decl: fld.fold_fn_decl(decl), - kind: kind, - })) - } TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))), TyParen(ty) => TyParen(fld.fold_ty(ty)), TyPath(path, bounds, id) => { @@ -715,23 +709,6 @@ pub fn noop_fold_ty_param_bound(tpb: TyParamBound, fld: &mut T) match tpb { TraitTyParamBound(ty) => TraitTyParamBound(fld.fold_trait_ref(ty)), RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), - UnboxedFnTyParamBound(bound) => { - match *bound { - UnboxedFnBound { - ref path, - ref decl, - ref lifetimes, - ref_id - } => { - UnboxedFnTyParamBound(P(UnboxedFnBound { - path: fld.fold_path(path.clone()), - decl: fld.fold_fn_decl(decl.clone()), - lifetimes: fld.fold_lifetime_defs(lifetimes.clone()), - ref_id: fld.new_id(ref_id), - })) - } - } - } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1c65a47350ea..18dd7074d28b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -53,9 +53,8 @@ use ast::{TtNonterminal, TupleVariantKind, Ty, Ty_, TyBot}; use ast::{TypeField, TyFixedLengthVec, TyClosure, TyProc, TyBareFn}; use ast::{TyTypeof, TyInfer, TypeMethod}; use ast::{TyNil, TyParam, TyParamBound, TyParen, TyPath, TyPtr, TyQPath}; -use ast::{TyRptr, TyTup, TyU32, TyUnboxedFn, TyUniq, TyVec, UnUniq}; +use ast::{TyRptr, TyTup, TyU32, TyUniq, TyVec, UnUniq}; use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind}; -use ast::{UnboxedFnBound, UnboxedFnTy, UnboxedFnTyParamBound}; use ast::{UnnamedField, UnsafeBlock}; use ast::{UnsafeFn, ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; @@ -1127,19 +1126,16 @@ impl<'a> Parser<'a> { Vec::new() }; - let (optional_unboxed_closure_kind, inputs) = if self.eat(&token::OrOr) { - (None, Vec::new()) + let inputs = if self.eat(&token::OrOr) { + Vec::new() } else { self.expect_or(); - let optional_unboxed_closure_kind = - self.parse_optional_unboxed_closure_kind(); - let inputs = self.parse_seq_to_before_or( &token::Comma, |p| p.parse_arg_general(false)); self.expect_or(); - (optional_unboxed_closure_kind, inputs) + inputs }; let bounds = self.parse_colon_then_ty_param_bounds(); @@ -1152,23 +1148,13 @@ impl<'a> Parser<'a> { variadic: false }); - match optional_unboxed_closure_kind { - Some(unboxed_closure_kind) => { - TyUnboxedFn(P(UnboxedFnTy { - kind: unboxed_closure_kind, - decl: decl, - })) - } - None => { - TyClosure(P(ClosureTy { - fn_style: fn_style, - onceness: onceness, - bounds: bounds, - decl: decl, - lifetimes: lifetime_defs, - })) - } - } + TyClosure(P(ClosureTy { + fn_style: fn_style, + onceness: onceness, + bounds: bounds, + decl: decl, + lifetimes: lifetime_defs, + })) } pub fn parse_unsafety(&mut self) -> FnStyle { @@ -3935,31 +3921,11 @@ impl<'a> Parser<'a> { token::ModSep | token::Ident(..) => { let path = self.parse_path(LifetimeAndTypesWithoutColons).path; - if self.token == token::OpenDelim(token::Paren) { - self.bump(); - let inputs = self.parse_seq_to_end( - &token::CloseDelim(token::Paren), - seq_sep_trailing_allowed(token::Comma), - |p| p.parse_arg_general(false)); - let (return_style, output) = self.parse_ret_ty(); - result.push(UnboxedFnTyParamBound(P(UnboxedFnBound { - path: path, - decl: P(FnDecl { - inputs: inputs, - output: output, - cf: return_style, - variadic: false, - }), - lifetimes: lifetime_defs, - ref_id: ast::DUMMY_NODE_ID, - }))); - } else { - result.push(TraitTyParamBound(ast::TraitRef { - path: path, - ref_id: ast::DUMMY_NODE_ID, - lifetimes: lifetime_defs, - })) - } + result.push(TraitTyParamBound(ast::TraitRef { + path: path, + ref_id: ast::DUMMY_NODE_ID, + lifetimes: lifetime_defs, + })) } _ => break, } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index d83ea5f76b1f..2448eacbb399 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -13,7 +13,7 @@ use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind}; use ast::{FnOnceUnboxedClosureKind}; use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound}; use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; -use ast::{UnboxedClosureKind, UnboxedFnTyParamBound}; +use ast::{UnboxedClosureKind}; use ast; use ast_util; use owned_slice::OwnedSlice; @@ -699,7 +699,6 @@ impl<'a> State<'a> { None, &OwnedSlice::empty(), Some(&generics), - None, None)); } ast::TyClosure(ref f) => { @@ -719,7 +718,6 @@ impl<'a> State<'a> { None, &f.bounds, Some(&generics), - None, None)); } ast::TyProc(ref f) => { @@ -739,21 +737,8 @@ impl<'a> State<'a> { None, &f.bounds, Some(&generics), - None, None)); } - ast::TyUnboxedFn(ref f) => { - try!(self.print_ty_fn(None, - None, - ast::NormalFn, - ast::Many, - &*f.decl, - None, - &OwnedSlice::empty(), - None, - None, - Some(f.kind))); - } ast::TyPath(ref path, ref bounds, _) => { try!(self.print_bounded_path(path, bounds)); } @@ -1212,8 +1197,7 @@ impl<'a> State<'a> { Some(m.ident), &OwnedSlice::empty(), Some(&m.generics), - Some(&m.explicit_self.node), - None)); + Some(&m.explicit_self.node))); word(&mut self.s, ";") } @@ -2407,15 +2391,6 @@ impl<'a> State<'a> { RegionTyParamBound(ref lt) => { self.print_lifetime(lt) } - UnboxedFnTyParamBound(ref unboxed_function_type) => { - try!(self.print_path(&unboxed_function_type.path, - false)); - try!(self.popen()); - try!(self.print_fn_args(&*unboxed_function_type.decl, - None)); - try!(self.pclose()); - self.print_fn_output(&*unboxed_function_type.decl) - } }) } Ok(()) @@ -2675,9 +2650,7 @@ impl<'a> State<'a> { id: Option, bounds: &OwnedSlice, generics: Option<&ast::Generics>, - opt_explicit_self: Option<&ast::ExplicitSelf_>, - opt_unboxed_closure_kind: - Option) + opt_explicit_self: Option<&ast::ExplicitSelf_>) -> IoResult<()> { try!(self.ibox(indent_unit)); @@ -2694,9 +2667,7 @@ impl<'a> State<'a> { try!(self.print_fn_style(fn_style)); try!(self.print_opt_abi_and_extern_if_nondefault(opt_abi)); try!(self.print_onceness(onceness)); - if opt_unboxed_closure_kind.is_none() { - try!(word(&mut self.s, "fn")); - } + try!(word(&mut self.s, "fn")); } match id { @@ -2710,30 +2681,15 @@ impl<'a> State<'a> { match generics { Some(g) => try!(self.print_generics(g)), _ => () } try!(zerobreak(&mut self.s)); - if opt_unboxed_closure_kind.is_some() || opt_sigil == Some('&') { + if opt_sigil == Some('&') { try!(word(&mut self.s, "|")); } else { try!(self.popen()); } - match opt_unboxed_closure_kind { - Some(ast::FnUnboxedClosureKind) => { - try!(word(&mut self.s, "&")); - try!(self.word_space(":")); - } - Some(ast::FnMutUnboxedClosureKind) => { - try!(word(&mut self.s, "&mut")); - try!(self.word_space(":")); - } - Some(ast::FnOnceUnboxedClosureKind) => { - try!(self.word_space(":")); - } - None => {} - } - try!(self.print_fn_args(decl, opt_explicit_self)); - if opt_unboxed_closure_kind.is_some() || opt_sigil == Some('&') { + if opt_sigil == Some('&') { try!(word(&mut self.s, "|")); } else { if decl.variadic { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index b4141af07336..9751abacbd3f 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -365,12 +365,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { visitor.visit_ty(&*function_declaration.decl.output); walk_lifetime_decls(visitor, &function_declaration.lifetimes); } - TyUnboxedFn(ref function_declaration) => { - for argument in function_declaration.decl.inputs.iter() { - visitor.visit_ty(&*argument.ty) - } - visitor.visit_ty(&*function_declaration.decl.output); - } TyPath(ref path, ref opt_bounds, id) => { visitor.visit_path(path, id); match *opt_bounds { @@ -505,13 +499,6 @@ pub fn walk_ty_param_bounds<'v, V: Visitor<'v>>(visitor: &mut V, TraitTyParamBound(ref typ) => { walk_trait_ref_helper(visitor, typ) } - UnboxedFnTyParamBound(ref function_declaration) => { - for argument in function_declaration.decl.inputs.iter() { - visitor.visit_ty(&*argument.ty) - } - visitor.visit_ty(&*function_declaration.decl.output); - walk_lifetime_decls(visitor, &function_declaration.lifetimes); - } RegionTyParamBound(ref lifetime) => { visitor.visit_lifetime_ref(lifetime); } diff --git a/src/test/run-pass/unboxed-closures-manual-impl.rs b/src/test/run-pass/unboxed-closures-manual-impl.rs index b0947f46a86a..8f6cfe049970 100644 --- a/src/test/run-pass/unboxed-closures-manual-impl.rs +++ b/src/test/run-pass/unboxed-closures-manual-impl.rs @@ -25,7 +25,7 @@ fn call_itint>(mut f: F, x: int) -> int { f.call_mut((x,)) + 3 } -fn call_box(f: &mut |&mut: int|->int, x: int) -> int { +fn call_box(f: &mut FnMut(int) -> int, x: int) -> int { f.call_mut((x,)) + 3 } From fdf5195f58971337ad46a9996613660279966120 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 6 Nov 2014 03:53:27 +0900 Subject: [PATCH 22/37] std::rand::OsRng: Use `getrandom` syscall on Linux `getrandom(2)` system call [1] has been added on Linux 3.17. This patch makes `OsRng` use `getrandom` if available, and use traditional `/dev/urandom` fallback if not. [1]: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895 --- src/libstd/rand/mod.rs | 8 ++- src/libstd/rand/os.rs | 124 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 12 deletions(-) diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs index 21e531d211a8..5ef2c2fe23d3 100644 --- a/src/libstd/rand/mod.rs +++ b/src/libstd/rand/mod.rs @@ -45,8 +45,12 @@ //! so the "quality" of `/dev/random` is not better than `/dev/urandom` in most cases. //! However, this means that `/dev/urandom` can yield somewhat predictable randomness //! if the entropy pool is very small, such as immediately after first booting. -//! If an application likely to be run soon after first booting, or on a system with very -//! few entropy sources, one should consider using `/dev/random` via `ReaderRng`. +//! Linux 3,17 added `getrandom(2)` system call which solves the issue: it blocks if entropy +//! pool is not initialized yet, but it does not block once initialized. +//! `OsRng` tries to use `getrandom(2)` if available, and use `/dev/urandom` fallback if not. +//! If an application does not have `getrandom` and likely to be run soon after first booting, +//! or on a system with very few entropy sources, one should consider using `/dev/random` via +//! `ReaderRng`. //! - On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference //! between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random` //! and `/dev/urandom` may block once if the CSPRNG has not seeded yet.) diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index b7b085812304..89e13f7650a3 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -15,45 +15,149 @@ pub use self::imp::OsRng; #[cfg(all(unix, not(target_os = "ios")))] mod imp { + extern crate libc; + use io::{IoResult, File}; use path::Path; use rand::Rng; use rand::reader::ReaderRng; use result::{Ok, Err}; + use slice::{ImmutableSlice, MutableSlice}; + use mem; + use os::errno; + + #[cfg(all(target_os = "linux", + any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))] + fn getrandom(buf: &mut [u8]) -> libc::c_long { + extern "C" { + fn syscall(number: libc::c_long, ...) -> libc::c_long; + } + + #[cfg(target_arch = "x86_64")] + const NR_GETRANDOM: libc::c_long = 318; + #[cfg(target_arch = "x86")] + const NR_GETRANDOM: libc::c_long = 355; + #[cfg(target_arch = "arm")] + const NR_GETRANDOM: libc::c_long = 384; + + unsafe { + syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0u) + } + } + + #[cfg(not(all(target_os = "linux", + any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))] + fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 } + + fn getrandom_fill_bytes(v: &mut [u8]) { + let mut read = 0; + let len = v.len(); + while read < len { + let result = getrandom(v[mut read..]); + if result == -1 { + let err = errno() as libc::c_int; + if err == libc::EINTR { + continue; + } else { + panic!("unexpected getrandom error: {}", err); + } + } else { + read += result as uint; + } + } + } + + fn getrandom_next_u32() -> u32 { + let mut buf: [u8, ..4] = [0u8, ..4]; + getrandom_fill_bytes(&mut buf); + unsafe { mem::transmute::<[u8, ..4], u32>(buf) } + } + + fn getrandom_next_u64() -> u64 { + let mut buf: [u8, ..8] = [0u8, ..8]; + getrandom_fill_bytes(&mut buf); + unsafe { mem::transmute::<[u8, ..8], u64>(buf) } + } + + #[cfg(all(target_os = "linux", + any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm")))] + fn is_getrandom_available() -> bool { + use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Relaxed}; + + static GETRANDOM_CHECKED: AtomicBool = INIT_ATOMIC_BOOL; + static GETRANDOM_AVAILABLE: AtomicBool = INIT_ATOMIC_BOOL; + + if !GETRANDOM_CHECKED.load(Relaxed) { + let mut buf: [u8, ..0] = []; + let result = getrandom(&mut buf); + let available = if result == -1 { + let err = errno() as libc::c_int; + err != libc::ENOSYS + } else { + true + }; + GETRANDOM_AVAILABLE.store(available, Relaxed); + GETRANDOM_CHECKED.store(true, Relaxed); + available + } else { + GETRANDOM_AVAILABLE.load(Relaxed) + } + } + + #[cfg(not(all(target_os = "linux", + any(target_arch = "x86_64", target_arch = "x86", target_arch = "arm"))))] + fn is_getrandom_available() -> bool { false } /// A random number generator that retrieves randomness straight from /// the operating system. Platform sources: /// /// - Unix-like systems (Linux, Android, Mac OSX): read directly from - /// `/dev/urandom`. + /// `/dev/urandom`, or from `getrandom(2)` system call if available. /// - Windows: calls `CryptGenRandom`, using the default cryptographic /// service provider with the `PROV_RSA_FULL` type. /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed /// This does not block. - #[cfg(unix)] pub struct OsRng { - inner: ReaderRng + inner: OsRngInner, + } + + enum OsRngInner { + OsGetrandomRng, + OsReaderRng(ReaderRng), } impl OsRng { /// Create a new `OsRng`. pub fn new() -> IoResult { + if is_getrandom_available() { + return Ok(OsRng { inner: OsGetrandomRng }); + } + let reader = try!(File::open(&Path::new("/dev/urandom"))); let reader_rng = ReaderRng::new(reader); - Ok(OsRng { inner: reader_rng }) + Ok(OsRng { inner: OsReaderRng(reader_rng) }) } } impl Rng for OsRng { fn next_u32(&mut self) -> u32 { - self.inner.next_u32() + match self.inner { + OsGetrandomRng => getrandom_next_u32(), + OsReaderRng(ref mut rng) => rng.next_u32(), + } } fn next_u64(&mut self) -> u64 { - self.inner.next_u64() + match self.inner { + OsGetrandomRng => getrandom_next_u64(), + OsReaderRng(ref mut rng) => rng.next_u64(), + } } fn fill_bytes(&mut self, v: &mut [u8]) { - self.inner.fill_bytes(v) + match self.inner { + OsGetrandomRng => getrandom_fill_bytes(v), + OsReaderRng(ref mut rng) => rng.fill_bytes(v) + } } } } @@ -75,7 +179,7 @@ mod imp { /// the operating system. Platform sources: /// /// - Unix-like systems (Linux, Android, Mac OSX): read directly from - /// `/dev/urandom`. + /// `/dev/urandom`, or from `getrandom(2)` system call if available. /// - Windows: calls `CryptGenRandom`, using the default cryptographic /// service provider with the `PROV_RSA_FULL` type. /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed @@ -145,10 +249,10 @@ mod imp { /// the operating system. Platform sources: /// /// - Unix-like systems (Linux, Android, Mac OSX): read directly from - /// `/dev/urandom`. + /// `/dev/urandom`, or from `getrandom(2)` system call if available. /// - Windows: calls `CryptGenRandom`, using the default cryptographic /// service provider with the `PROV_RSA_FULL` type. - /// + /// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed /// This does not block. pub struct OsRng { hcryptprov: HCRYPTPROV From 2cde618b1740ad9f50df82e1bcde169b356f51cb Mon Sep 17 00:00:00 2001 From: Subhash Bhushan Date: Wed, 5 Nov 2014 00:20:05 +0530 Subject: [PATCH 23/37] Make Filetype Clonable --- src/libstd/io/mod.rs | 2 +- src/test/run-pass/issue-18619.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issue-18619.rs diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index ebf541a63daf..0531563bcb35 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1737,7 +1737,7 @@ pub enum FileAccess { } /// Different kinds of files which can be identified by a call to stat -#[deriving(PartialEq, Show, Hash)] +#[deriving(PartialEq, Show, Hash, Clone)] pub enum FileType { /// This is a normal file, corresponding to `S_IFREG` TypeFile, diff --git a/src/test/run-pass/issue-18619.rs b/src/test/run-pass/issue-18619.rs new file mode 100644 index 000000000000..70ccc20e01a1 --- /dev/null +++ b/src/test/run-pass/issue-18619.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::io::FileType; + +pub fn main() { + let _ = FileType::TypeFile.clone(); +} From d108613ba00edea07ff7e233e3e9c0766132cd3e Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 27 Oct 2014 14:28:04 -0400 Subject: [PATCH 24/37] expand description of the link attribute Fixes #18288 --- src/doc/reference.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/doc/reference.md b/src/doc/reference.md index 11bf895341b9..ee069081881c 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1957,8 +1957,10 @@ On an `extern` block, the following attributes are interpreted: name and type. This is feature gated and the exact behavior is implementation-defined (due to variety of linker invocation syntax). - `link` - indicate that a native library should be linked to for the - declarations in this block to be linked correctly. See [external - blocks](#external-blocks) + declarations in this block to be linked correctly. `link` supports an optional `kind` + key with three possible values: `dylib`, `static`, and `framework`. See [external blocks](#external-blocks) for more about external blocks. Two + examples: `#[link(name = "readline")]` and + `#[link(name = "CoreFoundation", kind = "framework")]`. On declarations inside an `extern` block, the following attributes are interpreted: From 00ae7676097f9279e444f78bc3fa81a4d5f14bec Mon Sep 17 00:00:00 2001 From: tshakah Date: Thu, 6 Nov 2014 15:19:00 +0000 Subject: [PATCH 25/37] Update guide.md Corrected singular/plural reference to enums --- src/doc/guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/guide.md b/src/doc/guide.md index 9a1a42478d37..0fe1c6a08052 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -1149,7 +1149,7 @@ enum StringResult { } ``` Where a `StringResult` is either an `StringOK`, with the result of a computation, or an -`ErrorReason` with a `String` explaining what caused the computation to fail. This kind of +`ErrorReason` with a `String` explaining what caused the computation to fail. These kinds of `enum`s are actually very useful and are even part of the standard library. As you can see `enum`s with values are quite a powerful tool for data representation, From cf3b2e4fe6044cce018b723de9b21c500c6eac41 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Thu, 6 Nov 2014 12:24:47 -0500 Subject: [PATCH 26/37] Implement low-hanging fruit of collection conventions * Renames/deprecates the simplest and most obvious methods * Adds FIXME(conventions)s for outstanding work * Marks "handled" methods as unstable NOTE: the semantics of reserve and reserve_exact have changed! Other methods have had their semantics changed as well, but in a way that should obviously not typecheck if used incorrectly. Lots of work and breakage to come, but this handles most of the core APIs and most eggregious breakage. Future changes should *mostly* focus on niche collections, APIs, or simply back-compat additions. [breaking-change] --- src/libcollections/binary_heap.rs | 50 +++- src/libcollections/bit.rs | 28 ++- src/libcollections/btree/map.rs | 176 +++++++------- src/libcollections/btree/set.rs | 25 +- src/libcollections/dlist.rs | 147 +++++++----- src/libcollections/enum_set.rs | 190 ++++++++++------ src/libcollections/ring_buf.rs | 328 ++++++++++++++++++--------- src/libcollections/slice.rs | 6 +- src/libcollections/str.rs | 8 +- src/libcollections/string.rs | 58 +++-- src/libcollections/tree/map.rs | 315 ++++++++++++------------- src/libcollections/tree/set.rs | 24 +- src/libcollections/trie/map.rs | 208 ++++++++--------- src/libcollections/trie/set.rs | 21 +- src/libcollections/vec.rs | 151 ++++++------ src/libcollections/vec_map.rs | 266 +++++++++++----------- src/libstd/collections/hash/bench.rs | 10 +- src/libstd/collections/hash/map.rs | 253 +++++++++------------ src/libstd/collections/hash/set.rs | 30 ++- src/libstd/collections/lru_cache.rs | 150 +++++++----- src/libstd/collections/mod.rs | 2 +- 21 files changed, 1385 insertions(+), 1061 deletions(-) diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index 8481111ae91a..c9d600774494 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -162,6 +162,8 @@ use core::ptr; use slice; use vec::Vec; +// FIXME(conventions): implement into_iter + /// A priority queue implemented with a binary heap. /// /// This will be a max-heap. @@ -184,6 +186,7 @@ impl BinaryHeap { /// use std::collections::BinaryHeap; /// let pq: BinaryHeap = BinaryHeap::new(); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> BinaryHeap { BinaryHeap{data: vec!(),} } /// Creates an empty `BinaryHeap` with a specific capacity. @@ -197,6 +200,7 @@ impl BinaryHeap { /// use std::collections::BinaryHeap; /// let pq: BinaryHeap = BinaryHeap::with_capacity(10u); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(capacity: uint) -> BinaryHeap { BinaryHeap { data: Vec::with_capacity(capacity) } } @@ -234,6 +238,7 @@ impl BinaryHeap { /// println!("{}", x); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Items<'a, T> { Items { iter: self.data.iter() } } @@ -268,10 +273,19 @@ impl BinaryHeap { /// let pq: BinaryHeap = BinaryHeap::with_capacity(100u); /// assert!(pq.capacity() >= 100u); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn capacity(&self) -> uint { self.data.capacity() } - /// Reserves capacity for exactly `n` elements in the `BinaryHeap`. - /// Do nothing if the capacity is already sufficient. + /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the + /// given `BinaryHeap`. Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. /// /// # Example /// @@ -280,12 +294,17 @@ impl BinaryHeap { /// /// let mut pq: BinaryHeap = BinaryHeap::new(); /// pq.reserve_exact(100u); - /// assert!(pq.capacity() == 100u); + /// assert!(pq.capacity() >= 100u); /// ``` - pub fn reserve_exact(&mut self, n: uint) { self.data.reserve_exact(n) } + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_exact(&mut self, additional: uint) { self.data.reserve_exact(additional) } - /// Reserves capacity for at least `n` elements in the `BinaryHeap`. - /// Do nothing if the capacity is already sufficient. + /// Reserves capacity for at least `additional` more elements to be inserted in the + /// `BinaryHeap`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. /// /// # Example /// @@ -296,8 +315,15 @@ impl BinaryHeap { /// pq.reserve(100u); /// assert!(pq.capacity() >= 100u); /// ``` - pub fn reserve(&mut self, n: uint) { - self.data.reserve(n) + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve(&mut self, additional: uint) { + self.data.reserve(additional) + } + + /// Discards as much additional capacity as possible. + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn shrink_to_fit(&mut self) { + self.data.shrink_to_fit() } /// Removes the greatest item from a queue and returns it, or `None` if it @@ -314,6 +340,7 @@ impl BinaryHeap { /// assert_eq!(pq.pop(), Some(1i)); /// assert_eq!(pq.pop(), None); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn pop(&mut self) -> Option { match self.data.pop() { None => { None } @@ -342,6 +369,7 @@ impl BinaryHeap { /// assert_eq!(pq.len(), 3); /// assert_eq!(pq.top(), Some(&5i)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn push(&mut self, item: T) { self.data.push(item); let new_len = self.len() - 1; @@ -495,12 +523,15 @@ impl BinaryHeap { } /// Returns the length of the queue. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.data.len() } /// Returns true if the queue contains no elements + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Drops all items from the queue. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.data.truncate(0) } } @@ -528,8 +559,7 @@ impl Extendable for BinaryHeap { fn extend>(&mut self, mut iter: Iter) { let (lower, _) = iter.size_hint(); - let len = self.capacity(); - self.reserve(len + lower); + self.reserve(lower); for elem in iter { self.push(elem); diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index b7085c96aed1..833cfc04c552 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -75,6 +75,8 @@ use std::hash; use vec::Vec; +// FIXME(conventions): look, we just need to refactor this whole thing. Inside and out. + type MatchWords<'a> = Chain, Skip>>>>; // Take two BitV's, and return iterators of their words, where the shorter one // has been padded with 0's @@ -216,6 +218,7 @@ impl Bitv { /// use std::collections::Bitv; /// let mut bv = Bitv::new(); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> Bitv { Bitv { storage: Vec::new(), nbits: 0 } } @@ -613,6 +616,7 @@ impl Bitv { /// bv.truncate(2); /// assert!(bv.eq_vec([false, true])); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn truncate(&mut self, len: uint) { if len < self.len() { self.nbits = len; @@ -760,14 +764,17 @@ impl Bitv { /// Return the total number of bits in this vector #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.nbits } /// Returns true if there are no bits in this vector #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears all bits in this vector. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { for w in self.storage.iter_mut() { *w = 0u32; } } @@ -849,8 +856,7 @@ impl Clone for Bitv { #[inline] fn clone_from(&mut self, source: &Bitv) { self.nbits = source.nbits; - self.storage.reserve(source.storage.len()); - for (i, w) in self.storage.iter_mut().enumerate() { *w = source.storage[i]; } + self.storage.clone_from(&source.storage); } } @@ -1052,6 +1058,7 @@ impl BitvSet { /// let mut s = BitvSet::new(); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> BitvSet { BitvSet(Bitv::new()) } @@ -1067,6 +1074,7 @@ impl BitvSet { /// assert!(s.capacity() >= 100); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(nbits: uint) -> BitvSet { let bitv = Bitv::with_capacity(nbits, false); BitvSet::from_bitv(bitv) @@ -1106,6 +1114,7 @@ impl BitvSet { /// assert!(s.capacity() >= 100); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn capacity(&self) -> uint { let &BitvSet(ref bitv) = self; bitv.capacity() @@ -1212,6 +1221,7 @@ impl BitvSet { /// println!("new capacity: {}", s.capacity()); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn shrink_to_fit(&mut self) { let &BitvSet(ref mut bitv) = self; // Obtain original length @@ -1240,6 +1250,7 @@ impl BitvSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> BitPositions<'a> { BitPositions {set: self, next_idx: 0u} } @@ -1262,6 +1273,7 @@ impl BitvSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn union<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> { TwoBitPositions { set: self, @@ -1290,6 +1302,7 @@ impl BitvSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn intersection<'a>(&'a self, other: &'a BitvSet) -> Take> { let min = cmp::min(self.capacity(), other.capacity()); TwoBitPositions { @@ -1326,6 +1339,7 @@ impl BitvSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> { TwoBitPositions { set: self, @@ -1355,6 +1369,7 @@ impl BitvSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a BitvSet) -> TwoBitPositions<'a> { TwoBitPositions { set: self, @@ -1473,6 +1488,7 @@ impl BitvSet { /// Return the number of set bits in this set. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { let &BitvSet(ref bitv) = self; bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones()) @@ -1480,6 +1496,7 @@ impl BitvSet { /// Returns whether there are no bits set in this set #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { let &BitvSet(ref bitv) = self; bitv.storage.iter().all(|&n| n == 0) @@ -1487,6 +1504,7 @@ impl BitvSet { /// Clears all bits in this set #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { let &BitvSet(ref mut bitv) = self; bitv.clear(); @@ -1494,6 +1512,7 @@ impl BitvSet { /// Returns `true` if this set contains the specified integer. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains(&self, value: &uint) -> bool { let &BitvSet(ref bitv) = self; *value < bitv.nbits && bitv.get(*value) @@ -1502,12 +1521,14 @@ impl BitvSet { /// Returns `true` if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_disjoint(&self, other: &BitvSet) -> bool { self.intersection(other).next().is_none() } /// Returns `true` if the set is a subset of another. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &BitvSet) -> bool { let &BitvSet(ref self_bitv) = self; let &BitvSet(ref other_bitv) = other; @@ -1521,12 +1542,14 @@ impl BitvSet { /// Returns `true` if the set is a superset of another. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_superset(&self, other: &BitvSet) -> bool { other.is_subset(self) } /// Adds a value to the set. Returns `true` if the value was not already /// present in the set. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn insert(&mut self, value: uint) -> bool { if self.contains(&value) { return false; @@ -1545,6 +1568,7 @@ impl BitvSet { /// Removes a value from the set. Returns `true` if the value was /// present in the set. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn remove(&mut self, value: &uint) -> bool { if !self.contains(value) { return false; diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index e3dfabfa2954..9b644115f301 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -25,6 +25,8 @@ use core::fmt::Show; use ring_buf::RingBuf; +// FIXME(conventions): implement bounded iterators + /// A map based on a B-Tree. /// /// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing @@ -125,6 +127,7 @@ pub struct OccupiedEntry<'a, K:'a, V:'a> { impl BTreeMap { /// Makes a new empty BTreeMap with a reasonable choice for B. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> BTreeMap { //FIXME(Gankro): Tune this as a function of size_of? BTreeMap::with_b(6) @@ -155,12 +158,19 @@ impl BTreeMap { /// a.clear(); /// assert!(a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { let b = self.b; // avoid recursive destructors by manually traversing the tree for _ in mem::replace(self, BTreeMap::with_b(b)).into_iter() {}; } + /// Deprecated: renamed to `get`. + #[deprecated = "renamed to `get`"] + pub fn find(&self, key: &K) -> Option<&V> { + self.get(key) + } + // Searching in a B-Tree is pretty straightforward. // // Start at the root. Try to find the key in the current node. If we find it, return it. @@ -178,10 +188,11 @@ impl BTreeMap { /// /// let mut map = BTreeMap::new(); /// map.insert(1u, "a"); - /// assert_eq!(map.find(&1), Some(&"a")); - /// assert_eq!(map.find(&2), None); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); /// ``` - pub fn find(&self, key: &K) -> Option<&V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&self, key: &K) -> Option<&V> { let mut cur_node = &self.root; loop { match cur_node.search(key) { @@ -209,9 +220,15 @@ impl BTreeMap { /// assert_eq!(map.contains_key(&1), true); /// assert_eq!(map.contains_key(&2), false); /// ``` - #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains_key(&self, key: &K) -> bool { - self.find(key).is_some() + self.get(key).is_some() + } + + /// Deprecated: renamed to `get_mut`. + #[deprecated = "renamed to `get_mut`"] + pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { + self.get_mut(key) } /// Returns a mutable reference to the value corresponding to the key. @@ -223,14 +240,15 @@ impl BTreeMap { /// /// let mut map = BTreeMap::new(); /// map.insert(1u, "a"); - /// match map.find_mut(&1) { + /// match map.get_mut(&1) { /// Some(x) => *x = "b", /// None => (), /// } /// assert_eq!(map[1], "b"); /// ``` - // See `find` for implementation notes, this is basically a copy-paste with mut's added - pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { + // See `get` for implementation notes, this is basically a copy-paste with mut's added + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration let mut temp_node = &mut self.root; loop { @@ -248,6 +266,12 @@ impl BTreeMap { } } + /// Deprecated: renamed to `insert`. + #[deprecated = "renamed to `insert`"] + pub fn swap(&mut self, key: K, value: V) -> Option { + self.insert(key, value) + } + // Insertion in a B-Tree is a bit complicated. // // First we do the same kind of search described in `find`. But we need to maintain a stack of @@ -283,14 +307,15 @@ impl BTreeMap { /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); - /// assert_eq!(map.swap(37u, "a"), None); + /// assert_eq!(map.insert(37u, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); - /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[37], "c"); /// ``` - pub fn swap(&mut self, key: K, mut value: V) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, key: K, mut value: V) -> Option { // This is a stack of rawptrs to nodes paired with indices, respectively // representing the nodes and edges of our search path. We have to store rawptrs // because as far as Rust is concerned, we can mutate aliased data with such a @@ -338,25 +363,6 @@ impl BTreeMap { } } - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map = BTreeMap::new(); - /// assert_eq!(map.insert(2u, "value"), true); - /// assert_eq!(map.insert(2, "value2"), false); - /// assert_eq!(map[2], "value2"); - /// ``` - #[inline] - pub fn insert(&mut self, key: K, value: V) -> bool { - self.swap(key, value).is_none() - } - // Deletion is the most complicated operation for a B-Tree. // // First we do the same kind of search described in @@ -392,6 +398,12 @@ impl BTreeMap { // the underflow handling process on the parent. If merging merges the last two children // of the root, then we replace the root with the merged node. + /// Deprecated: renamed to `remove`. + #[deprecated = "renamed to `remove`"] + pub fn pop(&mut self, key: &K) -> Option { + self.remove(key) + } + /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// @@ -402,10 +414,11 @@ impl BTreeMap { /// /// let mut map = BTreeMap::new(); /// map.insert(1u, "a"); - /// assert_eq!(map.pop(&1), Some("a")); - /// assert_eq!(map.pop(&1), None); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); /// ``` - pub fn pop(&mut self, key: &K) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, key: &K) -> Option { // See `swap` for a more thorough description of the stuff going on in here let mut stack = stack::PartialSearchStack::new(self); loop { @@ -426,24 +439,6 @@ impl BTreeMap { } } } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::BTreeMap; - /// - /// let mut map = BTreeMap::new(); - /// assert_eq!(map.remove(&1u), false); - /// map.insert(1, "a"); - /// assert_eq!(map.remove(&1), true); - /// ``` - #[inline] - pub fn remove(&mut self, key: &K) -> bool { - self.pop(key).is_some() - } } /// The stack module provides a safe interface for constructing and manipulating a stack of ptrs @@ -793,13 +788,13 @@ impl Show for BTreeMap { impl Index for BTreeMap { fn index(&self, key: &K) -> &V { - self.find(key).expect("no entry found for key") + self.get(key).expect("no entry found for key") } } impl IndexMut for BTreeMap { fn index_mut(&mut self, key: &K) -> &mut V { - self.find_mut(key).expect("no entry found for key") + self.get_mut(key).expect("no entry found for key") } } @@ -891,8 +886,8 @@ impl + DoubleEndedIterator>> // Handle any operation on the left stack as necessary match op { - Push(item) => { self.left.push(item); }, - Pop => { self.left.pop(); }, + Push(item) => { self.left.push_back(item); }, + Pop => { self.left.pop_back(); }, } } } @@ -933,8 +928,8 @@ impl + DoubleEndedIterator>> }; match op { - Push(item) => { self.right.push(item); }, - Pop => { self.right.pop(); } + Push(item) => { self.right.push_back(item); }, + Pop => { self.right.pop_back(); } } } } @@ -1010,6 +1005,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> { impl BTreeMap { /// Gets an iterator over the entries of the map. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Entries<'a, K, V> { let len = self.len(); Entries { @@ -1023,6 +1019,7 @@ impl BTreeMap { } /// Gets a mutable iterator over the entries of the map. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, K, V> { let len = self.len(); MutEntries { @@ -1036,6 +1033,7 @@ impl BTreeMap { } /// Gets an owning iterator over the entries of the map. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveEntries { let len = self.len(); MoveEntries { @@ -1049,11 +1047,13 @@ impl BTreeMap { } /// Gets an iterator over the keys of the map. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { self.iter().map(|(k, _)| k) } /// Gets an iterator over the values of the map. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'a>(&'a self) -> Values<'a, K, V> { self.iter().map(|(_, v)| v) } @@ -1070,6 +1070,7 @@ impl BTreeMap { /// a.insert(1u, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.length } /// Return true if the map contains no elements. @@ -1084,6 +1085,7 @@ impl BTreeMap { /// a.insert(1u, "a"); /// assert!(!a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } } @@ -1137,40 +1139,40 @@ mod test { assert_eq!(map.len(), 0); for i in range(0, size) { - assert_eq!(map.swap(i, 10*i), None); + assert_eq!(map.insert(i, 10*i), None); assert_eq!(map.len(), i + 1); } for i in range(0, size) { - assert_eq!(map.find(&i).unwrap(), &(i*10)); + assert_eq!(map.get(&i).unwrap(), &(i*10)); } for i in range(size, size*2) { - assert_eq!(map.find(&i), None); + assert_eq!(map.get(&i), None); } for i in range(0, size) { - assert_eq!(map.swap(i, 100*i), Some(10*i)); + assert_eq!(map.insert(i, 100*i), Some(10*i)); assert_eq!(map.len(), size); } for i in range(0, size) { - assert_eq!(map.find(&i).unwrap(), &(i*100)); + assert_eq!(map.get(&i).unwrap(), &(i*100)); } for i in range(0, size/2) { - assert_eq!(map.pop(&(i*2)), Some(i*200)); + assert_eq!(map.remove(&(i*2)), Some(i*200)); assert_eq!(map.len(), size - i - 1); } for i in range(0, size/2) { - assert_eq!(map.find(&(2*i)), None); - assert_eq!(map.find(&(2*i+1)).unwrap(), &(i*200 + 100)); + assert_eq!(map.get(&(2*i)), None); + assert_eq!(map.get(&(2*i+1)).unwrap(), &(i*200 + 100)); } for i in range(0, size/2) { - assert_eq!(map.pop(&(2*i)), None); - assert_eq!(map.pop(&(2*i+1)), Some(i*200 + 100)); + assert_eq!(map.remove(&(2*i)), None); + assert_eq!(map.remove(&(2*i+1)), Some(i*200 + 100)); assert_eq!(map.len(), size/2 - i - 1); } } @@ -1178,17 +1180,17 @@ mod test { #[test] fn test_basic_small() { let mut map = BTreeMap::new(); - assert_eq!(map.pop(&1), None); - assert_eq!(map.find(&1), None); - assert_eq!(map.swap(1u, 1u), None); - assert_eq!(map.find(&1), Some(&1)); - assert_eq!(map.swap(1, 2), Some(1)); - assert_eq!(map.find(&1), Some(&2)); - assert_eq!(map.swap(2, 4), None); - assert_eq!(map.find(&2), Some(&4)); - assert_eq!(map.pop(&1), Some(2)); - assert_eq!(map.pop(&2), Some(4)); - assert_eq!(map.pop(&1), None); + assert_eq!(map.remove(&1), None); + assert_eq!(map.get(&1), None); + assert_eq!(map.insert(1u, 1u), None); + assert_eq!(map.get(&1), Some(&1)); + assert_eq!(map.insert(1, 2), Some(1)); + assert_eq!(map.get(&1), Some(&2)); + assert_eq!(map.insert(2, 4), None); + assert_eq!(map.get(&2), Some(&4)); + assert_eq!(map.remove(&1), Some(2)); + assert_eq!(map.remove(&2), Some(4)); + assert_eq!(map.remove(&1), None); } #[test] @@ -1283,7 +1285,7 @@ mod test { assert_eq!(view.set(100), 10); } } - assert_eq!(map.find(&1).unwrap(), &100); + assert_eq!(map.get(&1).unwrap(), &100); assert_eq!(map.len(), 6); @@ -1295,7 +1297,7 @@ mod test { *v *= 10; } } - assert_eq!(map.find(&2).unwrap(), &200); + assert_eq!(map.get(&2).unwrap(), &200); assert_eq!(map.len(), 6); // Existing key (take) @@ -1305,7 +1307,7 @@ mod test { assert_eq!(view.take(), 30); } } - assert_eq!(map.find(&3), None); + assert_eq!(map.get(&3), None); assert_eq!(map.len(), 5); @@ -1316,7 +1318,7 @@ mod test { assert_eq!(*view.set(1000), 1000); } } - assert_eq!(map.find(&10).unwrap(), &1000); + assert_eq!(map.get(&10).unwrap(), &1000); assert_eq!(map.len(), 6); } } @@ -1374,7 +1376,7 @@ mod bench { let mut m : BTreeMap = BTreeMap::new(); find_rand_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } #[bench] @@ -1382,7 +1384,7 @@ mod bench { let mut m : BTreeMap = BTreeMap::new(); find_rand_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } // Find seq @@ -1391,7 +1393,7 @@ mod bench { let mut m : BTreeMap = BTreeMap::new(); find_seq_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } #[bench] @@ -1399,7 +1401,7 @@ mod bench { let mut m : BTreeMap = BTreeMap::new(); find_seq_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } fn bench_iter(b: &mut Bencher, size: uint) { @@ -1407,7 +1409,7 @@ mod bench { let mut rng = weak_rng(); for _ in range(0, size) { - map.swap(rng.gen(), rng.gen()); + map.insert(rng.gen(), rng.gen()); } b.iter(|| { diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 27752207b979..f6a3de11d13d 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -20,6 +20,9 @@ use core::{iter, fmt}; use core::iter::Peekable; use core::fmt::Show; +// FIXME(conventions): implement bounded iterators +// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub + /// A set based on a B-Tree. /// /// See BTreeMap's documentation for a detailed discussion of this collection's performance @@ -61,6 +64,7 @@ pub struct UnionItems<'a, T:'a> { impl BTreeSet { /// Makes a new BTreeSet with a reasonable choice of B. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> BTreeSet { BTreeSet { map: BTreeMap::new() } } @@ -75,11 +79,13 @@ impl BTreeSet { impl BTreeSet { /// Gets an iterator over the BTreeSet's contents. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Items<'a, T> { self.map.keys() } /// Gets an iterator for moving out the BtreeSet's contents. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveItems { self.map.into_iter().map(|(k, _)| k) } @@ -87,23 +93,27 @@ impl BTreeSet { impl BTreeSet { /// Visits the values representing the difference, in ascending order. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a BTreeSet) -> DifferenceItems<'a, T> { DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visits the values representing the symmetric difference, in ascending order. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a BTreeSet) -> SymDifferenceItems<'a, T> { SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visits the values representing the intersection, in ascending order. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn intersection<'a>(&'a self, other: &'a BTreeSet) -> IntersectionItems<'a, T> { IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} } /// Visits the values representing the union, in ascending order. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn union<'a>(&'a self, other: &'a BTreeSet) -> UnionItems<'a, T> { UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} } @@ -120,6 +130,7 @@ impl BTreeSet { /// v.insert(1i); /// assert_eq!(v.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.map.len() } /// Returns true if the set contains no elements @@ -134,6 +145,7 @@ impl BTreeSet { /// v.insert(1i); /// assert!(!v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the set, removing all values. @@ -148,6 +160,7 @@ impl BTreeSet { /// v.clear(); /// assert!(v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.map.clear() } @@ -163,8 +176,9 @@ impl BTreeSet { /// assert_eq!(set.contains(&1), true); /// assert_eq!(set.contains(&4), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains(&self, value: &T) -> bool { - self.map.find(value).is_some() + self.map.contains_key(value) } /// Returns `true` if the set has no elements in common with `other`. @@ -184,6 +198,7 @@ impl BTreeSet { /// b.insert(1); /// assert_eq!(a.is_disjoint(&b), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_disjoint(&self, other: &BTreeSet) -> bool { self.intersection(other).next().is_none() } @@ -204,6 +219,7 @@ impl BTreeSet { /// set.insert(4); /// assert_eq!(set.is_subset(&sup), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &BTreeSet) -> bool { // Stolen from TreeMap let mut x = self.iter(); @@ -248,6 +264,7 @@ impl BTreeSet { /// set.insert(2); /// assert_eq!(set.is_superset(&sub), true); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_superset(&self, other: &BTreeSet) -> bool { other.is_subset(self) } @@ -266,8 +283,9 @@ impl BTreeSet { /// assert_eq!(set.insert(2i), false); /// assert_eq!(set.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn insert(&mut self, value: T) -> bool { - self.map.insert(value, ()) + self.map.insert(value, ()).is_none() } /// Removes a value from the set. Returns `true` if the value was @@ -284,8 +302,9 @@ impl BTreeSet { /// assert_eq!(set.remove(&2), true); /// assert_eq!(set.remove(&2), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn remove(&mut self, value: &T) -> bool { - self.map.remove(value) + self.map.remove(value).is_some() } } diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index a1e286d12457..9d9955141df1 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -195,6 +195,7 @@ impl Default for DList { impl DList { /// Creates an empty `DList`. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> DList { DList{list_head: None, list_tail: Rawlink::none(), length: 0} } @@ -209,9 +210,9 @@ impl DList { /// use std::collections::DList; /// /// let mut dl = DList::new(); - /// dl.push(1i); - /// dl.push(2); - /// dl.push(3); + /// dl.push_back(1i); + /// dl.push_back(2); + /// dl.push_back(3); /// /// dl.rotate_forward(); /// @@ -236,9 +237,9 @@ impl DList { /// use std::collections::DList; /// /// let mut dl = DList::new(); - /// dl.push(1i); - /// dl.push(2); - /// dl.push(3); + /// dl.push_back(1i); + /// dl.push_back(2); + /// dl.push_back(3); /// /// dl.rotate_backward(); /// @@ -264,10 +265,10 @@ impl DList { /// /// let mut a = DList::new(); /// let mut b = DList::new(); - /// a.push(1i); - /// a.push(2); - /// b.push(3i); - /// b.push(4); + /// a.push_back(1i); + /// a.push_back(2); + /// b.push_back(3i); + /// b.push_back(4); /// /// a.append(b); /// @@ -305,10 +306,10 @@ impl DList { /// /// let mut a = DList::new(); /// let mut b = DList::new(); - /// a.push(1i); - /// a.push(2); - /// b.push(3i); - /// b.push(4); + /// a.push_back(1i); + /// a.push_back(2); + /// b.push_back(3i); + /// b.push_back(4); /// /// a.prepend(b); /// @@ -333,10 +334,10 @@ impl DList { /// use std::collections::DList; /// /// let mut a: DList = DList::new(); - /// a.push(2i); - /// a.push(4); - /// a.push(7); - /// a.push(8); + /// a.push_back(2i); + /// a.push_back(4); + /// a.push_back(7); + /// a.push_back(8); /// /// // insert 11 before the first odd number in the list /// a.insert_when(11, |&e, _| e % 2 == 1); @@ -387,12 +388,14 @@ impl DList { /// Provides a forward iterator. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Items<'a, T> { Items{nelem: self.len(), head: &self.list_head, tail: self.list_tail} } /// Provides a forward iterator with mutable references. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> { let head_raw = match self.list_head { Some(ref mut h) => Rawlink::some(&mut **h), @@ -408,6 +411,7 @@ impl DList { /// Consumes the list into an iterator yielding elements by value. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveItems { MoveItems{list: self} } @@ -416,6 +420,7 @@ impl DList { /// /// This operation should compute in O(1) time. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.list_head.is_none() } @@ -424,6 +429,7 @@ impl DList { /// /// This operation should compute in O(1) time. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.length } @@ -432,6 +438,7 @@ impl DList { /// /// This operation should compute in O(n) time. #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { *self = DList::new() } @@ -439,34 +446,39 @@ impl DList { /// Provides a reference to the front element, or `None` if the list is /// empty. #[inline] - pub fn front<'a>(&'a self) -> Option<&'a T> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn front(&self) -> Option<&T> { self.list_head.as_ref().map(|head| &head.value) } /// Provides a mutable reference to the front element, or `None` if the list /// is empty. #[inline] - pub fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn front_mut(&mut self) -> Option<&mut T> { self.list_head.as_mut().map(|head| &mut head.value) } /// Provides a reference to the back element, or `None` if the list is /// empty. #[inline] - pub fn back<'a>(&'a self) -> Option<&'a T> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn back(&self) -> Option<&T> { self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value) } /// Provides a mutable reference to the back element, or `None` if the list /// is empty. #[inline] - pub fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn back_mut(&mut self) -> Option<&mut T> { self.list_tail.resolve().map(|tail| &mut tail.value) } /// Adds an element first in the list. /// /// This operation should compute in O(1) time. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn push_front(&mut self, elt: T) { self.push_front_node(box Node::new(elt)) } @@ -475,10 +487,17 @@ impl DList { /// empty. /// /// This operation should compute in O(1) time. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn pop_front(&mut self) -> Option { self.pop_front_node().map(|box Node{value, ..}| value) } + /// Deprecated: Renamed to `push_back`. + #[deprecated = "Renamed to `push_back`"] + pub fn push(&mut self, elt: T) { + self.push_back(elt) + } + /// Appends an element to the back of a list /// /// # Example @@ -487,14 +506,21 @@ impl DList { /// use std::collections::DList; /// /// let mut d = DList::new(); - /// d.push(1i); - /// d.push(3); + /// d.push_back(1i); + /// d.push_back(3); /// assert_eq!(3, *d.back().unwrap()); /// ``` - pub fn push(&mut self, elt: T) { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn push_back(&mut self, elt: T) { self.push_back_node(box Node::new(elt)) } + /// Deprecated: Renamed to `pop_back`. + #[deprecated = "Renamed to `pop_back`"] + pub fn pop(&mut self) -> Option { + self.pop_back() + } + /// Removes the last element from a list and returns it, or `None` if /// it is empty. /// @@ -504,12 +530,13 @@ impl DList { /// use std::collections::DList; /// /// let mut d = DList::new(); - /// assert_eq!(d.pop(), None); - /// d.push(1i); - /// d.push(3); - /// assert_eq!(d.pop(), Some(3)); + /// assert_eq!(d.pop_back(), None); + /// d.push_back(1i); + /// d.push_back(3); + /// assert_eq!(d.pop_back(), Some(3)); /// ``` - pub fn pop(&mut self) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn pop_back(&mut self) -> Option { self.pop_back_node().map(|box Node{value, ..}| value) } } @@ -682,7 +709,7 @@ impl Iterator for MoveItems { impl DoubleEndedIterator for MoveItems { #[inline] - fn next_back(&mut self) -> Option { self.list.pop() } + fn next_back(&mut self) -> Option { self.list.pop_back() } } impl FromIterator for DList { @@ -695,7 +722,7 @@ impl FromIterator for DList { impl Extendable for DList { fn extend>(&mut self, mut iterator: T) { - for elt in iterator { self.push(elt); } + for elt in iterator { self.push_back(elt); } } } @@ -801,21 +828,21 @@ mod tests { fn test_basic() { let mut m: DList> = DList::new(); assert_eq!(m.pop_front(), None); - assert_eq!(m.pop(), None); + assert_eq!(m.pop_back(), None); assert_eq!(m.pop_front(), None); m.push_front(box 1); assert_eq!(m.pop_front(), Some(box 1)); - m.push(box 2); - m.push(box 3); + m.push_back(box 2); + m.push_back(box 3); assert_eq!(m.len(), 2); assert_eq!(m.pop_front(), Some(box 2)); assert_eq!(m.pop_front(), Some(box 3)); assert_eq!(m.len(), 0); assert_eq!(m.pop_front(), None); - m.push(box 1); - m.push(box 3); - m.push(box 5); - m.push(box 7); + m.push_back(box 1); + m.push_back(box 3); + m.push_back(box 5); + m.push_back(box 7); assert_eq!(m.pop_front(), Some(box 1)); let mut n = DList::new(); @@ -853,19 +880,19 @@ mod tests { { let mut m = DList::new(); let mut n = DList::new(); - n.push(2i); + n.push_back(2i); m.append(n); assert_eq!(m.len(), 1); - assert_eq!(m.pop(), Some(2)); + assert_eq!(m.pop_back(), Some(2)); check_links(&m); } { let mut m = DList::new(); let n = DList::new(); - m.push(2i); + m.push_back(2i); m.append(n); assert_eq!(m.len(), 1); - assert_eq!(m.pop(), Some(2)); + assert_eq!(m.pop_back(), Some(2)); check_links(&m); } @@ -887,10 +914,10 @@ mod tests { { let mut m = DList::new(); let mut n = DList::new(); - n.push(2i); + n.push_back(2i); m.prepend(n); assert_eq!(m.len(), 1); - assert_eq!(m.pop(), Some(2)); + assert_eq!(m.pop_back(), Some(2)); check_links(&m); } @@ -948,9 +975,9 @@ mod tests { #[test] fn test_iterator_clone() { let mut n = DList::new(); - n.push(2i); - n.push(3); - n.push(4); + n.push_back(2i); + n.push_back(3); + n.push_back(4); let mut it = n.iter(); it.next(); let mut jt = it.clone(); @@ -1005,7 +1032,7 @@ mod tests { let mut n = DList::new(); assert!(n.iter_mut().next().is_none()); n.push_front(4i); - n.push(5); + n.push_back(5); let mut it = n.iter_mut(); assert_eq!(it.size_hint(), (2, Some(2))); assert!(it.next().is_some()); @@ -1079,8 +1106,8 @@ mod tests { assert_eq!(n.pop_front(), Some(1)); let mut m = DList::new(); - m.push(2i); - m.push(4); + m.push_back(2i); + m.push_back(4); m.insert_ordered(3); check_links(&m); assert_eq!(vec![2,3,4], m.into_iter().collect::>()); @@ -1117,7 +1144,7 @@ mod tests { assert!(n == m); n.push_front(1); assert!(n != m); - m.push(1); + m.push_back(1); assert!(n == m); let n = list_from([2i,3,4]); @@ -1132,9 +1159,9 @@ mod tests { assert!(hash::hash(&x) == hash::hash(&y)); - x.push(1i); - x.push(2); - x.push(3); + x.push_back(1i); + x.push_back(2); + x.push_back(3); y.push_front(3i); y.push_front(2); @@ -1214,7 +1241,7 @@ mod tests { let r: u8 = rand::random(); match r % 6 { 0 => { - m.pop(); + m.pop_back(); v.pop(); } 1 => { @@ -1226,7 +1253,7 @@ mod tests { v.insert(0, -i); } 3 | 5 | _ => { - m.push(i); + m.push_back(i); v.push(i); } } @@ -1262,7 +1289,7 @@ mod tests { fn bench_push_back(b: &mut test::Bencher) { let mut m: DList = DList::new(); b.iter(|| { - m.push(0); + m.push_back(0); }) } @@ -1270,8 +1297,8 @@ mod tests { fn bench_push_back_pop_back(b: &mut test::Bencher) { let mut m: DList = DList::new(); b.iter(|| { - m.push(0); - m.pop(); + m.push_back(0); + m.pop_back(); }) } diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index bcae4fe68c9b..454d4f1ca872 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -16,6 +16,10 @@ use core::prelude::*; use core::fmt; +// FIXME(conventions): implement BitXor +// FIXME(contentions): implement union family of methods? (general design may be wrong here) +// FIXME(conventions): implement len + #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] /// A specialized `Set` implementation to use enum types. pub struct EnumSet { @@ -47,34 +51,56 @@ pub trait CLike { fn from_uint(uint) -> Self; } -fn bit(e: E) -> uint { +fn bit(e: &E) -> uint { 1 << e.to_uint() } impl EnumSet { - /// Returns an empty `EnumSet`. + /// Deprecated: Renamed to `new`. + #[deprecated = "Renamed to `new`"] pub fn empty() -> EnumSet { + EnumSet::new() + } + + /// Returns an empty `EnumSet`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn new() -> EnumSet { EnumSet {bits: 0} } /// Returns true if the `EnumSet` is empty. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.bits == 0 } + pub fn clear(&mut self) { + self.bits = 0; + } + /// Returns `true` if the `EnumSet` contains any enum of the given `EnumSet`. + /// Deprecated: Use `is_disjoint`. + #[deprecated = "Use `is_disjoint`"] pub fn intersects(&self, e: EnumSet) -> bool { - (self.bits & e.bits) != 0 + !self.is_disjoint(&e) } - /// Returns the intersection of both `EnumSets`. - pub fn intersection(&self, e: EnumSet) -> EnumSet { - EnumSet {bits: self.bits & e.bits} + /// Returns `false` if the `EnumSet` contains any enum of the given `EnumSet`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn is_disjoint(&self, other: &EnumSet) -> bool { + (self.bits & other.bits) == 0 } - /// Returns `true` if a given `EnumSet` is included in an `EnumSet`. - pub fn contains(&self, e: EnumSet) -> bool { - (self.bits & e.bits) == e.bits + /// Returns `true` if a given `EnumSet` is included in this `EnumSet`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn is_superset(&self, other: &EnumSet) -> bool { + (self.bits & other.bits) == other.bits + } + + /// Returns `true` if this `EnumSet` is included in the given `EnumSet`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn is_subset(&self, other: &EnumSet) -> bool { + other.is_subset(self) } /// Returns the union of both `EnumSets`. @@ -82,17 +108,47 @@ impl EnumSet { EnumSet {bits: self.bits | e.bits} } - /// Adds an enum to an `EnumSet`. + /// Returns the intersection of both `EnumSets`. + pub fn intersection(&self, e: EnumSet) -> EnumSet { + EnumSet {bits: self.bits & e.bits} + } + + /// Deprecated: Use `insert`. + #[deprecated = "Use `insert`"] pub fn add(&mut self, e: E) { - self.bits |= bit(e); + self.insert(e); + } + + /// Adds an enum to the `EnumSet`, and returns `true` if it wasn't there before + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, e: E) -> bool { + let result = !self.contains(&e); + self.bits |= bit(&e); + result + } + + /// Removes an enum from the EnumSet + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, e: &E) -> bool { + let result = self.contains(e); + self.bits &= !bit(e); + result + } + + /// Deprecated: use `contains`. + #[deprecated = "use `contains"] + pub fn contains_elem(&self, e: E) -> bool { + self.contains(&e) } /// Returns `true` if an `EnumSet` contains a given enum. - pub fn contains_elem(&self, e: E) -> bool { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn contains(&self, e: &E) -> bool { (self.bits & bit(e)) != 0 } /// Returns an iterator over an `EnumSet`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter(&self) -> Items { Items::new(self.bits) } @@ -174,18 +230,18 @@ mod test { } #[test] - fn test_empty() { - let e: EnumSet = EnumSet::empty(); + fn test_new() { + let e: EnumSet = EnumSet::new(); assert!(e.is_empty()); } #[test] fn test_show() { - let mut e = EnumSet::empty(); + let mut e = EnumSet::new(); assert_eq!("{}", e.to_string().as_slice()); - e.add(A); + e.insert(A); assert_eq!("{A}", e.to_string().as_slice()); - e.add(C); + e.insert(C); assert_eq!("{A, C}", e.to_string().as_slice()); } @@ -194,75 +250,75 @@ mod test { #[test] fn test_two_empties_do_not_intersect() { - let e1: EnumSet = EnumSet::empty(); - let e2: EnumSet = EnumSet::empty(); - assert!(!e1.intersects(e2)); + let e1: EnumSet = EnumSet::new(); + let e2: EnumSet = EnumSet::new(); + assert!(e1.is_disjoint(&e2)); } #[test] fn test_empty_does_not_intersect_with_full() { - let e1: EnumSet = EnumSet::empty(); + let e1: EnumSet = EnumSet::new(); - let mut e2: EnumSet = EnumSet::empty(); - e2.add(A); - e2.add(B); - e2.add(C); + let mut e2: EnumSet = EnumSet::new(); + e2.insert(A); + e2.insert(B); + e2.insert(C); - assert!(!e1.intersects(e2)); + assert!(e1.is_disjoint(&e2)); } #[test] fn test_disjoint_intersects() { - let mut e1: EnumSet = EnumSet::empty(); - e1.add(A); + let mut e1: EnumSet = EnumSet::new(); + e1.insert(A); - let mut e2: EnumSet = EnumSet::empty(); - e2.add(B); + let mut e2: EnumSet = EnumSet::new(); + e2.insert(B); - assert!(!e1.intersects(e2)); + assert!(e1.is_disjoint(&e2)); } #[test] fn test_overlapping_intersects() { - let mut e1: EnumSet = EnumSet::empty(); - e1.add(A); + let mut e1: EnumSet = EnumSet::new(); + e1.insert(A); - let mut e2: EnumSet = EnumSet::empty(); - e2.add(A); - e2.add(B); + let mut e2: EnumSet = EnumSet::new(); + e2.insert(A); + e2.insert(B); - assert!(e1.intersects(e2)); + assert!(!e1.is_disjoint(&e2)); } /////////////////////////////////////////////////////////////////////////// // contains and contains_elem #[test] - fn test_contains() { - let mut e1: EnumSet = EnumSet::empty(); - e1.add(A); + fn test_superset() { + let mut e1: EnumSet = EnumSet::new(); + e1.insert(A); - let mut e2: EnumSet = EnumSet::empty(); - e2.add(A); - e2.add(B); + let mut e2: EnumSet = EnumSet::new(); + e2.insert(A); + e2.insert(B); - assert!(!e1.contains(e2)); - assert!(e2.contains(e1)); + assert!(!e1.is_superset(&e2)); + assert!(e2.is_superset(&e1)); } #[test] - fn test_contains_elem() { - let mut e1: EnumSet = EnumSet::empty(); - e1.add(A); - assert!(e1.contains_elem(A)); - assert!(!e1.contains_elem(B)); - assert!(!e1.contains_elem(C)); + fn test_contains() { + let mut e1: EnumSet = EnumSet::new(); + e1.insert(A); + assert!(e1.contains(&A)); + assert!(!e1.contains(&B)); + assert!(!e1.contains(&C)); - e1.add(A); - e1.add(B); - assert!(e1.contains_elem(A)); - assert!(e1.contains_elem(B)); - assert!(!e1.contains_elem(C)); + e1.insert(A); + e1.insert(B); + assert!(e1.contains(&A)); + assert!(e1.contains(&B)); + assert!(!e1.contains(&C)); } /////////////////////////////////////////////////////////////////////////// @@ -270,24 +326,24 @@ mod test { #[test] fn test_iterator() { - let mut e1: EnumSet = EnumSet::empty(); + let mut e1: EnumSet = EnumSet::new(); let elems: Vec = e1.iter().collect(); assert!(elems.is_empty()) - e1.add(A); + e1.insert(A); let elems = e1.iter().collect(); assert_eq!(vec![A], elems) - e1.add(C); + e1.insert(C); let elems = e1.iter().collect(); assert_eq!(vec![A,C], elems) - e1.add(C); + e1.insert(C); let elems = e1.iter().collect(); assert_eq!(vec![A,C], elems) - e1.add(B); + e1.insert(B); let elems = e1.iter().collect(); assert_eq!(vec![A,B,C], elems) } @@ -297,13 +353,13 @@ mod test { #[test] fn test_operators() { - let mut e1: EnumSet = EnumSet::empty(); - e1.add(A); - e1.add(C); + let mut e1: EnumSet = EnumSet::new(); + e1.insert(A); + e1.insert(C); - let mut e2: EnumSet = EnumSet::empty(); - e2.add(B); - e2.add(C); + let mut e2: EnumSet = EnumSet::new(); + e2.insert(B); + e2.insert(C); let e_union = e1 | e2; let elems = e_union.iter().collect(); diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 3c4c3fce61d7..549ebb14b3e1 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -27,6 +27,11 @@ use vec::Vec; static INITIAL_CAPACITY: uint = 8u; // 2^3 static MINIMUM_CAPACITY: uint = 2u; +// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should +// be scrapped anyway. Defer to rewrite? +// FIXME(conventions): implement into_iter + + /// `RingBuf` is a circular buffer that implements `Deque`. #[deriving(Clone)] pub struct RingBuf { @@ -42,11 +47,13 @@ impl Default for RingBuf { impl RingBuf { /// Creates an empty `RingBuf`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> RingBuf { RingBuf::with_capacity(INITIAL_CAPACITY) } /// Creates an empty `RingBuf` with space for at least `n` elements. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(n: uint) -> RingBuf { RingBuf{nelts: 0, lo: 0, elts: Vec::from_fn(cmp::max(MINIMUM_CAPACITY, n), |_| None)} @@ -54,24 +61,51 @@ impl RingBuf { /// Retrieves an element in the `RingBuf` by index. /// - /// Fails if there is no element with the given index. + /// # Example + /// + /// ```rust + /// use std::collections::RingBuf; + /// + /// let mut buf = RingBuf::new(); + /// buf.push_back(3i); + /// buf.push_back(4); + /// buf.push_back(5); + /// assert_eq!(buf.get(1).unwrap(), &4); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&self, i: uint) -> Option<&T> { + match self.elts.get(i) { + None => None, + Some(opt) => opt.as_ref(), + } + } + + /// Retrieves an element in the `RingBuf` mutably by index. /// /// # Example /// /// ```rust - /// # #![allow(deprecated)] /// use std::collections::RingBuf; /// /// let mut buf = RingBuf::new(); - /// buf.push(3i); - /// buf.push(4); - /// buf.push(5); - /// *buf.get_mut(1) = 7; + /// buf.push_back(3i); + /// buf.push_back(4); + /// buf.push_back(5); + /// match buf.get_mut(1) { + /// None => {} + /// Some(elem) => { + /// *elem = 7; + /// } + /// } + /// /// assert_eq!(buf[1], 7); /// ``` - #[deprecated = "use indexing instead: `buf[index] = value`"] - pub fn get_mut(&mut self, i: uint) -> &mut T { - &mut self[i] + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get_mut(&mut self, i: uint) -> Option<&mut T> { + match self.elts.get_mut(i) { + None => None, + Some(opt) => opt.as_mut(), + } } /// Swaps elements at indices `i` and `j`. @@ -86,9 +120,9 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut buf = RingBuf::new(); - /// buf.push(3i); - /// buf.push(4); - /// buf.push(5); + /// buf.push_back(3i); + /// buf.push_back(4); + /// buf.push_back(5); /// buf.swap(0, 2); /// assert_eq!(buf[0], 5); /// assert_eq!(buf[2], 3); @@ -107,21 +141,70 @@ impl RingBuf { raw_index(self.lo, self.elts.len(), idx) } - /// Reserves capacity for exactly `n` elements in the given `RingBuf`, - /// doing nothing if `self`'s capacity is already equal to or greater - /// than the requested capacity. - pub fn reserve_exact(&mut self, n: uint) { - self.elts.reserve_exact(n); + /// Returns the number of elements the `RingBuf` can hold without + /// reallocating. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let buf: RingBuf = RingBuf::with_capacity(10); + /// assert_eq!(buf.capacity(), 10); + /// ``` + #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn capacity(&self) -> uint { + // FXIME(Gankro): not the actual usable capacity if you use reserve/reserve_exact + self.elts.capacity() } - /// Reserves capacity for at least `n` elements in the given `RingBuf`, - /// over-allocating in case the caller needs to reserve additional - /// space. + /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the + /// given `RingBuf`. Does nothing if the capacity is already sufficient. /// - /// Do nothing if `self`'s capacity is already equal to or greater - /// than the requested capacity. - pub fn reserve(&mut self, n: uint) { - self.elts.reserve(n); + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut buf: RingBuf = vec![1].into_iter().collect(); + /// buf.reserve_exact(10); + /// assert!(buf.capacity() >= 11); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_exact(&mut self, additional: uint) { + // FIXME(Gankro): this is just wrong. The ringbuf won't actually use this space + self.elts.reserve_exact(additional); + } + + /// Reserves capacity for at least `additional` more elements to be inserted in the given + /// `Ringbuf`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. + /// + /// # Example + /// + /// ``` + /// use std::collections::RingBuf; + /// + /// let mut buf: RingBuf = vec![1].into_iter().collect(); + /// buf.reserve(10); + /// assert!(buf.capacity() >= 11); + /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve(&mut self, additional: uint) { + // FIXME(Gankro): this is just wrong. The ringbuf won't actually use this space + self.elts.reserve(additional); } /// Returns a front-to-back iterator. @@ -132,12 +215,13 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut buf = RingBuf::new(); - /// buf.push(5i); - /// buf.push(3); - /// buf.push(4); + /// buf.push_back(5i); + /// buf.push_back(3); + /// buf.push_back(4); /// let b: &[_] = &[&5, &3, &4]; /// assert_eq!(buf.iter().collect::>().as_slice(), b); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter(&self) -> Items { Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()} } @@ -150,15 +234,16 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut buf = RingBuf::new(); - /// buf.push(5i); - /// buf.push(3); - /// buf.push(4); + /// buf.push_back(5i); + /// buf.push_back(3); + /// buf.push_back(4); /// for num in buf.iter_mut() { /// *num = *num - 2; /// } /// let b: &[_] = &[&mut 3, &mut 1, &mut 2]; /// assert_eq!(buf.iter_mut().collect::>()[], b); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut(&mut self) -> MutItems { let start_index = raw_index(self.lo, self.elts.len(), 0); let end_index = raw_index(self.lo, self.elts.len(), self.nelts); @@ -197,9 +282,10 @@ impl RingBuf { /// /// let mut v = RingBuf::new(); /// assert_eq!(v.len(), 0); - /// v.push(1i); + /// v.push_back(1i); /// assert_eq!(v.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.nelts } /// Returns true if the buffer contains no elements @@ -214,6 +300,7 @@ impl RingBuf { /// v.push_front(1i); /// assert!(!v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the buffer, removing all values. @@ -224,10 +311,11 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut v = RingBuf::new(); - /// v.push(1i); + /// v.push_back(1i); /// v.clear(); /// assert!(v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { for x in self.elts.iter_mut() { *x = None } self.nelts = 0; @@ -245,10 +333,11 @@ impl RingBuf { /// let mut d = RingBuf::new(); /// assert_eq!(d.front(), None); /// - /// d.push(1i); - /// d.push(2i); + /// d.push_back(1i); + /// d.push_back(2i); /// assert_eq!(d.front(), Some(&1i)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn front(&self) -> Option<&T> { if self.nelts > 0 { Some(&self[0]) } else { None } } @@ -264,14 +353,15 @@ impl RingBuf { /// let mut d = RingBuf::new(); /// assert_eq!(d.front_mut(), None); /// - /// d.push(1i); - /// d.push(2i); + /// d.push_back(1i); + /// d.push_back(2i); /// match d.front_mut() { /// Some(x) => *x = 9i, /// None => (), /// } /// assert_eq!(d.front(), Some(&9i)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn front_mut(&mut self) -> Option<&mut T> { if self.nelts > 0 { Some(&mut self[0]) } else { None } } @@ -287,10 +377,11 @@ impl RingBuf { /// let mut d = RingBuf::new(); /// assert_eq!(d.back(), None); /// - /// d.push(1i); - /// d.push(2i); + /// d.push_back(1i); + /// d.push_back(2i); /// assert_eq!(d.back(), Some(&2i)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn back(&self) -> Option<&T> { if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None } } @@ -306,14 +397,15 @@ impl RingBuf { /// let mut d = RingBuf::new(); /// assert_eq!(d.back(), None); /// - /// d.push(1i); - /// d.push(2i); + /// d.push_back(1i); + /// d.push_back(2i); /// match d.back_mut() { /// Some(x) => *x = 9i, /// None => (), /// } /// assert_eq!(d.back(), Some(&9i)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn back_mut(&mut self) -> Option<&mut T> { let nelts = self.nelts; if nelts > 0 { Some(&mut self[nelts - 1]) } else { None } @@ -328,13 +420,14 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut d = RingBuf::new(); - /// d.push(1i); - /// d.push(2i); + /// d.push_back(1i); + /// d.push_back(2i); /// /// assert_eq!(d.pop_front(), Some(1i)); /// assert_eq!(d.pop_front(), Some(2i)); /// assert_eq!(d.pop_front(), None); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn pop_front(&mut self) -> Option { let result = self.elts[self.lo].take(); if result.is_some() { @@ -356,6 +449,7 @@ impl RingBuf { /// d.push_front(2i); /// assert_eq!(d.front(), Some(&2i)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn push_front(&mut self, t: T) { if self.nelts == self.elts.len() { grow(self.nelts, &mut self.lo, &mut self.elts); @@ -367,6 +461,12 @@ impl RingBuf { self.nelts += 1u; } + /// Deprecated: Renamed to `push_back`. + #[deprecated = "Renamed to `push_back`"] + pub fn push(&mut self, t: T) { + self.push_back(t) + } + /// Appends an element to the back of a buffer /// /// # Example @@ -375,11 +475,12 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut buf = RingBuf::new(); - /// buf.push(1i); - /// buf.push(3); + /// buf.push_back(1i); + /// buf.push_back(3); /// assert_eq!(3, *buf.back().unwrap()); /// ``` - pub fn push(&mut self, t: T) { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn push_back(&mut self, t: T) { if self.nelts == self.elts.len() { grow(self.nelts, &mut self.lo, &mut self.elts); } @@ -388,6 +489,12 @@ impl RingBuf { self.nelts += 1u; } + /// Deprecated: Renamed to `pop_back`. + #[deprecated = "Renamed to `pop_back`"] + pub fn pop(&mut self) -> Option { + self.pop_back() + } + /// Removes the last element from a buffer and returns it, or `None` if /// it is empty. /// @@ -397,12 +504,13 @@ impl RingBuf { /// use std::collections::RingBuf; /// /// let mut buf = RingBuf::new(); - /// assert_eq!(buf.pop(), None); - /// buf.push(1i); - /// buf.push(3); - /// assert_eq!(buf.pop(), Some(3)); + /// assert_eq!(buf.pop_back(), None); + /// buf.push_back(1i); + /// buf.push_back(3); + /// assert_eq!(buf.pop_back(), Some(3)); /// ``` - pub fn pop(&mut self) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn pop_back(&mut self) -> Option { if self.nelts > 0 { self.nelts -= 1; let hi = self.raw_index(self.nelts); @@ -523,7 +631,7 @@ impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {} fn grow(nelts: uint, loptr: &mut uint, elts: &mut Vec>) { assert_eq!(nelts, elts.len()); let lo = *loptr; - elts.reserve(nelts * 2); + elts.reserve_exact(nelts); let newlen = elts.capacity(); /* fill with None */ @@ -630,7 +738,7 @@ impl FromIterator for RingBuf { impl Extendable for RingBuf { fn extend>(&mut self, mut iterator: T) { for elt in iterator { - self.push(elt); + self.push_back(elt); } } } @@ -666,9 +774,9 @@ mod tests { assert_eq!(d.len(), 0u); d.push_front(17i); d.push_front(42i); - d.push(137); + d.push_back(137); assert_eq!(d.len(), 3u); - d.push(137); + d.push_back(137); assert_eq!(d.len(), 4u); debug!("{}", d.front()); assert_eq!(*d.front().unwrap(), 42); @@ -677,21 +785,21 @@ mod tests { let mut i = d.pop_front(); debug!("{}", i); assert_eq!(i, Some(42)); - i = d.pop(); + i = d.pop_back(); debug!("{}", i); assert_eq!(i, Some(137)); - i = d.pop(); + i = d.pop_back(); debug!("{}", i); assert_eq!(i, Some(137)); - i = d.pop(); + i = d.pop_back(); debug!("{}", i); assert_eq!(i, Some(17)); assert_eq!(d.len(), 0u); - d.push(3); + d.push_back(3); assert_eq!(d.len(), 1u); d.push_front(2); assert_eq!(d.len(), 2u); - d.push(4); + d.push_back(4); assert_eq!(d.len(), 3u); d.push_front(1); assert_eq!(d.len(), 4u); @@ -711,22 +819,22 @@ mod tests { assert_eq!(deq.len(), 0); deq.push_front(a.clone()); deq.push_front(b.clone()); - deq.push(c.clone()); + deq.push_back(c.clone()); assert_eq!(deq.len(), 3); - deq.push(d.clone()); + deq.push_back(d.clone()); assert_eq!(deq.len(), 4); assert_eq!((*deq.front().unwrap()).clone(), b.clone()); assert_eq!((*deq.back().unwrap()).clone(), d.clone()); assert_eq!(deq.pop_front().unwrap(), b.clone()); - assert_eq!(deq.pop().unwrap(), d.clone()); - assert_eq!(deq.pop().unwrap(), c.clone()); - assert_eq!(deq.pop().unwrap(), a.clone()); + assert_eq!(deq.pop_back().unwrap(), d.clone()); + assert_eq!(deq.pop_back().unwrap(), c.clone()); + assert_eq!(deq.pop_back().unwrap(), a.clone()); assert_eq!(deq.len(), 0); - deq.push(c.clone()); + deq.push_back(c.clone()); assert_eq!(deq.len(), 1); deq.push_front(b.clone()); assert_eq!(deq.len(), 2); - deq.push(d.clone()); + deq.push_back(d.clone()); assert_eq!(deq.len(), 3); deq.push_front(a.clone()); assert_eq!(deq.len(), 4); @@ -750,7 +858,7 @@ mod tests { let mut deq = RingBuf::new(); for i in range(0u, 66) { - deq.push(i); + deq.push_back(i); } for i in range(0u, 66) { @@ -788,7 +896,7 @@ mod tests { fn bench_push_back(b: &mut test::Bencher) { let mut deq = RingBuf::new(); b.iter(|| { - deq.push(0i); + deq.push_back(0i); }) } @@ -861,17 +969,17 @@ mod tests { #[test] fn test_with_capacity() { let mut d = RingBuf::with_capacity(0); - d.push(1i); + d.push_back(1i); assert_eq!(d.len(), 1); let mut d = RingBuf::with_capacity(50); - d.push(1i); + d.push_back(1i); assert_eq!(d.len(), 1); } #[test] fn test_with_capacity_non_power_two() { let mut d3 = RingBuf::with_capacity(3); - d3.push(1i); + d3.push_back(1i); // X = None, | = lo // [|1, X, X] @@ -880,20 +988,20 @@ mod tests { assert_eq!(d3.front(), None); // [X, |3, X] - d3.push(3); + d3.push_back(3); // [X, |3, 6] - d3.push(6); + d3.push_back(6); // [X, X, |6] assert_eq!(d3.pop_front(), Some(3)); // Pushing the lo past half way point to trigger // the 'B' scenario for growth // [9, X, |6] - d3.push(9); + d3.push_back(9); // [9, 12, |6] - d3.push(12); + d3.push_back(12); - d3.push(15); + d3.push_back(15); // There used to be a bug here about how the // RingBuf made growth assumptions about the // underlying Vec which didn't hold and lead @@ -912,25 +1020,25 @@ mod tests { #[test] fn test_reserve_exact() { let mut d = RingBuf::new(); - d.push(0u64); + d.push_back(0u64); d.reserve_exact(50); - assert_eq!(d.elts.capacity(), 50); + assert!(d.capacity() >= 51); let mut d = RingBuf::new(); - d.push(0u32); + d.push_back(0u32); d.reserve_exact(50); - assert_eq!(d.elts.capacity(), 50); + assert!(d.capacity() >= 51); } #[test] fn test_reserve() { let mut d = RingBuf::new(); - d.push(0u64); + d.push_back(0u64); d.reserve(50); - assert_eq!(d.elts.capacity(), 64); + assert!(d.capacity() >= 64); let mut d = RingBuf::new(); - d.push(0u32); + d.push_back(0u32); d.reserve(50); - assert_eq!(d.elts.capacity(), 64); + assert!(d.capacity() >= 64); } #[test] @@ -948,7 +1056,7 @@ mod tests { assert_eq!(d.iter().size_hint(), (0, Some(0))); for i in range(0i, 5) { - d.push(i); + d.push_back(i); } { let b: &[_] = &[&0,&1,&2,&3,&4]; @@ -979,7 +1087,7 @@ mod tests { assert_eq!(d.iter().rev().next(), None); for i in range(0i, 5) { - d.push(i); + d.push_back(i); } { let b: &[_] = &[&4,&3,&2,&1,&0]; @@ -998,11 +1106,11 @@ mod tests { let mut d = RingBuf::with_capacity(3); assert!(d.iter_mut().rev().next().is_none()); - d.push(1i); - d.push(2); - d.push(3); + d.push_back(1i); + d.push_back(2); + d.push_back(3); assert_eq!(d.pop_front(), Some(1)); - d.push(4); + d.push_back(4); assert_eq!(d.iter_mut().rev().map(|x| *x).collect::>(), vec!(4, 3, 2)); @@ -1075,13 +1183,13 @@ mod tests { let mut d = RingBuf::new(); d.push_front(17i); d.push_front(42); - d.push(137); - d.push(137); + d.push_back(137); + d.push_back(137); assert_eq!(d.len(), 4u); let mut e = d.clone(); assert_eq!(e.len(), 4u); while !d.is_empty() { - assert_eq!(d.pop(), e.pop()); + assert_eq!(d.pop_back(), e.pop_back()); } assert_eq!(d.len(), 0u); assert_eq!(e.len(), 0u); @@ -1094,15 +1202,15 @@ mod tests { d.push_front(137i); d.push_front(17); d.push_front(42); - d.push(137); + d.push_back(137); let mut e = RingBuf::with_capacity(0); - e.push(42); - e.push(17); - e.push(137); - e.push(137); + e.push_back(42); + e.push_back(17); + e.push_back(137); + e.push_back(137); assert!(&e == &d); - e.pop(); - e.push(0); + e.pop_back(); + e.push_back(0); assert!(e != d); e.clear(); assert!(e == RingBuf::new()); @@ -1113,15 +1221,15 @@ mod tests { let mut x = RingBuf::new(); let mut y = RingBuf::new(); - x.push(1i); - x.push(2); - x.push(3); + x.push_back(1i); + x.push_back(2); + x.push_back(3); - y.push(0i); - y.push(1i); + y.push_back(0i); + y.push_back(1i); y.pop_front(); - y.push(2); - y.push(3); + y.push_back(2); + y.push_back(3); assert!(hash::hash(&x) == hash::hash(&y)); } @@ -1130,9 +1238,9 @@ mod tests { fn test_ord() { let x = RingBuf::new(); let mut y = RingBuf::new(); - y.push(1i); - y.push(2); - y.push(3); + y.push_back(1i); + y.push_back(2); + y.push_back(3); assert!(x < y); assert!(y > x); assert!(x <= x); diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index e4af5795e1cc..13703d6fe95f 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1523,10 +1523,10 @@ mod tests { fn test_capacity() { let mut v = vec![0u64]; v.reserve_exact(10u); - assert_eq!(v.capacity(), 10u); + assert!(v.capacity() >= 11u); let mut v = vec![0u32]; v.reserve_exact(10u); - assert_eq!(v.capacity(), 10u); + assert!(v.capacity() >= 11u); } #[test] @@ -2318,7 +2318,7 @@ mod bench { v.set_len(1024); } for i in range(0u, 1024) { - *v.get_mut(i) = 0; + v[i] = 0; } }); } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index cdca0d10eedd..bed14e933bf3 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -76,6 +76,8 @@ pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange}; pub use core::str::{Str, StrSlice}; pub use unicode::str::{UnicodeStrSlice, Words, Graphemes, GraphemeIndices}; +// FIXME(conventions): ensure bit/char conventions are followed by str's API + /* Section: Creating a string */ @@ -308,7 +310,7 @@ impl<'a> Iterator for Recompositions<'a> { self.composee = Some(ch); return Some(k); } - self.buffer.push(ch); + self.buffer.push_back(ch); self.last_ccc = Some(ch_class); } } @@ -322,7 +324,7 @@ impl<'a> Iterator for Recompositions<'a> { self.state = Purging; return Some(k); } - self.buffer.push(ch); + self.buffer.push_back(ch); self.last_ccc = Some(ch_class); continue; } @@ -332,7 +334,7 @@ impl<'a> Iterator for Recompositions<'a> { continue; } None => { - self.buffer.push(ch); + self.buffer.push_back(ch); self.last_ccc = Some(ch_class); } } diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index b3c83ba55598..ff9bd039a7d9 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -330,8 +330,8 @@ impl String { let mut buf = String::new(); buf.push(ch); - let size = buf.len() * length; - buf.reserve(size); + let size = buf.len() * (length - 1); + buf.reserve_exact(size); for _ in range(1, length) { buf.push(ch) } @@ -379,27 +379,23 @@ impl String { /// assert!(s.capacity() >= 10); /// ``` #[inline] - #[unstable = "just implemented, needs to prove itself"] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn capacity(&self) -> uint { self.vec.capacity() } - /// Reserves capacity for at least `extra` additional bytes in this string buffer. - /// - /// # Example - /// - /// ``` - /// let mut s = String::with_capacity(10); - /// let before = s.capacity(); - /// s.reserve_additional(100); - /// assert!(s.capacity() - before >= 100); - /// ``` - #[inline] + /// Deprecated: Renamed to `reserve`. + #[deprecated = "Renamed to `reserve`"] pub fn reserve_additional(&mut self, extra: uint) { - self.vec.reserve_additional(extra) + self.vec.reserve(extra) } - /// Reserves capacity for at least `capacity` bytes in this string buffer. + /// Reserves capacity for at least `additional` more bytes to be inserted in the given + /// `String`. The collection may reserve more space to avoid frequent reallocations. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. /// /// # Example /// @@ -409,22 +405,33 @@ impl String { /// assert!(s.capacity() >= 10); /// ``` #[inline] - pub fn reserve(&mut self, capacity: uint) { - self.vec.reserve(capacity) + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve(&mut self, additional: uint) { + self.vec.reserve(additional) } - /// Reserves capacity for exactly `capacity` bytes in this string buffer. + /// Reserves the minimum capacity for exactly `additional` more bytes to be inserted in the + /// given `String`. Does nothing if the capacity is already sufficient. + /// + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. /// /// # Example /// /// ``` /// let mut s = String::new(); - /// s.reserve_exact(10); - /// assert_eq!(s.capacity(), 10); + /// s.reserve(10); + /// assert!(s.capacity() >= 10); /// ``` #[inline] - pub fn reserve_exact(&mut self, capacity: uint) { - self.vec.reserve_exact(capacity) + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_exact(&mut self, additional: uint) { + self.vec.reserve_exact(additional) } /// Shrinks the capacity of this string buffer to match its length. @@ -439,6 +446,7 @@ impl String { /// assert_eq!(s.capacity(), 3); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn shrink_to_fit(&mut self) { self.vec.shrink_to_fit() } @@ -459,7 +467,7 @@ impl String { pub fn push(&mut self, ch: char) { let cur_len = self.len(); // This may use up to 4 bytes. - self.vec.reserve_additional(4); + self.vec.reserve(4); unsafe { // Attempt to not use an intermediate buffer by just pushing bytes @@ -590,7 +598,7 @@ impl String { let len = self.len(); assert!(idx <= len); assert!(self.as_slice().is_char_boundary(idx)); - self.vec.reserve_additional(4); + self.vec.reserve(4); let mut bits = [0, ..4]; let amt = ch.encode_utf8(bits).unwrap(); diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs index 8e24eabfccfe..ea1c37d036ae 100644 --- a/src/libcollections/tree/map.rs +++ b/src/libcollections/tree/map.rs @@ -21,6 +21,9 @@ use std::hash::{Writer, Hash}; use vec::Vec; +// FIXME(conventions): implement bounded iterators +// FIXME(conventions): replace rev_iter(_mut) by making iter(_mut) DoubleEnded + /// This is implemented as an AA tree, which is a simplified variation of /// a red-black tree where red (horizontal) nodes can only be added /// as a right child. The time complexity is the same, and re-balancing @@ -60,7 +63,7 @@ use vec::Vec; /// } /// /// for key in range(0, 4) { -/// match map.find(&key) { +/// match map.get(&key) { /// Some(val) => println!("{} has a value: {}", key, val), /// None => println!("{} not in map", key), /// } @@ -188,14 +191,14 @@ impl Default for TreeMap { impl Index for TreeMap { #[inline] fn index<'a>(&'a self, i: &K) -> &'a V { - self.find(i).expect("no entry found for key") + self.get(i).expect("no entry found for key") } } impl IndexMut for TreeMap { #[inline] fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V { - self.find_mut(i).expect("no entry found for key") + self.get_mut(i).expect("no entry found for key") } } @@ -208,6 +211,7 @@ impl TreeMap { /// use std::collections::TreeMap; /// let mut map: TreeMap<&str, int> = TreeMap::new(); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } /// Gets a lazy iterator over the keys in the map, in ascending order. @@ -226,6 +230,7 @@ impl TreeMap { /// println!("{}", x); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { self.iter().map(|(k, _v)| k) } @@ -247,6 +252,7 @@ impl TreeMap { /// println!("{}", x); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'a>(&'a self) -> Values<'a, K, V> { self.iter().map(|(_k, v)| v) } @@ -267,6 +273,7 @@ impl TreeMap { /// println!("{}: {}", key, value); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Entries<'a, K, V> { Entries { stack: vec!(), @@ -314,10 +321,11 @@ impl TreeMap { /// if key == &"b" { break } /// } /// - /// assert_eq!(map.find(&"a"), Some(&11)); - /// assert_eq!(map.find(&"b"), Some(&12)); - /// assert_eq!(map.find(&"c"), Some(&3)); + /// assert_eq!(map.get(&"a"), Some(&11)); + /// assert_eq!(map.get(&"b"), Some(&12)); + /// assert_eq!(map.get(&"c"), Some(&3)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, K, V> { MutEntries { stack: vec!(), @@ -345,15 +353,15 @@ impl TreeMap { /// if key == &"b" { break } /// } /// - /// assert_eq!(map.find(&"a"), Some(&1)); - /// assert_eq!(map.find(&"b"), Some(&12)); - /// assert_eq!(map.find(&"c"), Some(&13)); + /// assert_eq!(map.get(&"a"), Some(&1)); + /// assert_eq!(map.get(&"b"), Some(&12)); + /// assert_eq!(map.get(&"c"), Some(&13)); /// ``` pub fn rev_iter_mut<'a>(&'a mut self) -> RevMutEntries<'a, K, V> { RevMutEntries{iter: self.iter_mut()} } - /// Gets a lazy iterator that consumes the TreeMap. + /// Gets a lazy iterator that consumes the treemap. /// /// # Example /// @@ -368,6 +376,7 @@ impl TreeMap { /// let vec: Vec<(&str, int)> = map.into_iter().collect(); /// assert_eq!(vec, vec![("a", 1), ("b", 2), ("c", 3)]); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveEntries { let TreeMap { root, length } = self; let stk = match root { @@ -392,6 +401,7 @@ impl TreeMap { /// a.insert(1u, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.length } /// Return true if the map contains no elements. @@ -406,6 +416,7 @@ impl TreeMap { /// a.insert(1u, "a"); /// assert!(!a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } @@ -421,11 +432,18 @@ impl TreeMap { /// a.clear(); /// assert!(a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.root = None; self.length = 0 } + /// Deprecated: Renamed to `get`. + #[deprecated = "Renamed to `get`"] + pub fn find(&self, key: &K) -> Option<&V> { + self.get(key) + } + /// Returns a reference to the value corresponding to the key. /// /// # Example @@ -435,11 +453,12 @@ impl TreeMap { /// /// let mut map = TreeMap::new(); /// map.insert(1u, "a"); - /// assert_eq!(map.find(&1), Some(&"a")); - /// assert_eq!(map.find(&2), None); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); /// ``` #[inline] - pub fn find<'a>(&'a self, key: &K) -> Option<&'a V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&self, key: &K) -> Option<&V> { tree_find_with(&self.root, |k2| key.cmp(k2)) } @@ -456,8 +475,15 @@ impl TreeMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains_key(&self, key: &K) -> bool { - self.find(key).is_some() + self.get(key).is_some() + } + + /// Deprecated: Renamed to `get_mut`. + #[deprecated = "Renamed to `get_mut`"] + pub fn find_mut(&mut self, key: &K) -> Option<&mut V> { + self.get_mut(key) } /// Returns a mutable reference to the value corresponding to the key. @@ -469,52 +495,22 @@ impl TreeMap { /// /// let mut map = TreeMap::new(); /// map.insert(1u, "a"); - /// match map.find_mut(&1) { + /// match map.get_mut(&1) { /// Some(x) => *x = "b", /// None => (), /// } /// assert_eq!(map[1], "b"); /// ``` #[inline] - pub fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { tree_find_with_mut(&mut self.root, |x| key.cmp(x)) } - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// assert_eq!(map.insert(2u, "value"), true); - /// assert_eq!(map.insert(2, "value2"), false); - /// assert_eq!(map[2], "value2"); - /// ``` - #[inline] - pub fn insert(&mut self, key: K, value: V) -> bool { - self.swap(key, value).is_none() - } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::TreeMap; - /// - /// let mut map = TreeMap::new(); - /// assert_eq!(map.remove(&1u), false); - /// map.insert(1, "a"); - /// assert_eq!(map.remove(&1), true); - /// ``` - #[inline] - pub fn remove(&mut self, key: &K) -> bool { - self.pop(key).is_some() + /// Deprecated: Renamed to `insert`. + #[deprecated = "Renamed to `insert`"] + pub fn swap(&mut self, key: K, value: V) -> Option { + self.insert(key, value) } /// Inserts a key-value pair from the map. If the key already had a value @@ -526,19 +522,26 @@ impl TreeMap { /// use std::collections::TreeMap; /// /// let mut map = TreeMap::new(); - /// assert_eq!(map.swap(37u, "a"), None); + /// assert_eq!(map.insert(37u, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); - /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[37], "c"); /// ``` - pub fn swap(&mut self, key: K, value: V) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, key: K, value: V) -> Option { let ret = insert(&mut self.root, key, value); if ret.is_none() { self.length += 1 } ret } + /// Deprecated: Renamed to `remove`. + #[deprecated = "Renamed to `remove`"] + pub fn pop(&mut self, key: &K) -> Option { + self.remove(key) + } + /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// @@ -549,10 +552,11 @@ impl TreeMap { /// /// let mut map = TreeMap::new(); /// map.insert(1u, "a"); - /// assert_eq!(map.pop(&1), Some("a")); - /// assert_eq!(map.pop(&1), None); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); /// ``` - pub fn pop(&mut self, key: &K) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, key: &K) -> Option { let ret = remove(&mut self.root, key); if ret.is_some() { self.length -= 1 } ret @@ -567,7 +571,7 @@ impl TreeMap { /// # Example /// /// ``` - /// use std::collections::TreeMap; + /// use collections::tree_map::TreeMap; /// /// fn get_headers() -> TreeMap { /// let mut result = TreeMap::new(); @@ -585,7 +589,7 @@ impl TreeMap { /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); /// ``` #[inline] - pub fn find_with<'a>(&'a self, f:|&K| -> Ordering) -> Option<&'a V> { + pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> { tree_find_with(&self.root, f) } @@ -596,9 +600,7 @@ impl TreeMap { /// # Example /// /// ``` - /// use std::collections::TreeMap; - /// - /// let mut t = TreeMap::new(); + /// let mut t = collections::tree_map::TreeMap::new(); /// t.insert("Content-Type", "application/xml"); /// t.insert("User-Agent", "Curl-Rust/0.1"); /// @@ -608,7 +610,7 @@ impl TreeMap { /// None => panic!(), /// } /// - /// assert_eq!(t.find(&"User-Agent"), Some(&new_ua)); + /// assert_eq!(t.get(&"User-Agent"), Some(&new_ua)); /// ``` #[inline] pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> { @@ -742,10 +744,10 @@ impl TreeMap { /// *value = "changed"; /// } /// - /// assert_eq!(map.find(&2), Some(&"a")); - /// assert_eq!(map.find(&4), Some(&"changed")); - /// assert_eq!(map.find(&6), Some(&"changed")); - /// assert_eq!(map.find(&8), Some(&"changed")); + /// assert_eq!(map.get(&2), Some(&"a")); + /// assert_eq!(map.get(&4), Some(&"changed")); + /// assert_eq!(map.get(&6), Some(&"changed")); + /// assert_eq!(map.get(&8), Some(&"changed")); /// ``` pub fn lower_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> { bound_setup!(self.iter_mut_for_traversal(), k, true) @@ -776,10 +778,10 @@ impl TreeMap { /// *value = "changed"; /// } /// - /// assert_eq!(map.find(&2), Some(&"a")); - /// assert_eq!(map.find(&4), Some(&"b")); - /// assert_eq!(map.find(&6), Some(&"changed")); - /// assert_eq!(map.find(&8), Some(&"changed")); + /// assert_eq!(map.get(&2), Some(&"a")); + /// assert_eq!(map.get(&4), Some(&"b")); + /// assert_eq!(map.get(&6), Some(&"changed")); + /// assert_eq!(map.get(&8), Some(&"changed")); /// ``` pub fn upper_bound_mut<'a>(&'a mut self, k: &K) -> MutEntries<'a, K, V> { bound_setup!(self.iter_mut_for_traversal(), k, false) @@ -1287,16 +1289,16 @@ mod test_treemap { #[test] fn find_empty() { let m: TreeMap = TreeMap::new(); - assert!(m.find(&5) == None); + assert!(m.get(&5) == None); } #[test] fn find_not_found() { let mut m = TreeMap::new(); - assert!(m.insert(1i, 2i)); - assert!(m.insert(5i, 3i)); - assert!(m.insert(9i, 3i)); - assert_eq!(m.find(&2), None); + assert!(m.insert(1i, 2i).is_none()); + assert!(m.insert(5i, 3i).is_none()); + assert!(m.insert(9i, 3i).is_none()); + assert_eq!(m.get(&2), None); } #[test] @@ -1308,41 +1310,42 @@ mod test_treemap { #[test] fn find_with_not_found() { let mut m = TreeMap::new(); - assert!(m.insert("test1", 2i)); - assert!(m.insert("test2", 3i)); - assert!(m.insert("test3", 3i)); + assert!(m.insert("test1", 2i).is_none()); + assert!(m.insert("test2", 3i).is_none()); + assert!(m.insert("test3", 3i).is_none()); assert_eq!(m.find_with(|&k| "test4".cmp(k)), None); } #[test] fn find_with_found() { let mut m = TreeMap::new(); - assert!(m.insert("test1", 2i)); - assert!(m.insert("test2", 3i)); - assert!(m.insert("test3", 4i)); + assert!(m.insert("test1", 2i).is_none()); + assert!(m.insert("test2", 3i).is_none()); + assert!(m.insert("test3", 4i).is_none()); assert_eq!(m.find_with(|&k| "test2".cmp(k)), Some(&3i)); } #[test] fn test_find_mut() { let mut m = TreeMap::new(); - assert!(m.insert(1i, 12i)); - assert!(m.insert(2, 8)); - assert!(m.insert(5, 14)); + assert!(m.insert(1i, 12i).is_none()); + assert!(m.insert(2, 8).is_none()); + assert!(m.insert(5, 14).is_none()); let new = 100; - match m.find_mut(&5) { + match m.get_mut(&5) { None => panic!(), Some(x) => *x = new } - assert_eq!(m.find(&5), Some(&new)); + assert_eq!(m.get(&5), Some(&new)); } #[test] fn test_find_with_mut() { let mut m = TreeMap::new(); - assert!(m.insert("t1", 12i)); - assert!(m.insert("t2", 8)); - assert!(m.insert("t5", 14)); + assert!(m.insert("t1", 12i).is_none()); + assert!(m.insert("t2", 8).is_none()); + assert!(m.insert("t5", 14).is_none()); let new = 100; + match m.find_with_mut(|&k| "t5".cmp(k)) { None => panic!(), Some(x) => *x = new } @@ -1352,23 +1355,23 @@ mod test_treemap { #[test] fn insert_replace() { let mut m = TreeMap::new(); - assert!(m.insert(5i, 2i)); - assert!(m.insert(2, 9)); - assert!(!m.insert(2, 11)); - assert_eq!(m.find(&2).unwrap(), &11); + assert!(m.insert(5i, 2i).is_none()); + assert!(m.insert(2, 9).is_none()); + assert!(!m.insert(2, 11).is_none()); + assert_eq!(m.get(&2).unwrap(), &11); } #[test] fn test_clear() { let mut m = TreeMap::new(); m.clear(); - assert!(m.insert(5i, 11i)); - assert!(m.insert(12, -3)); - assert!(m.insert(19, 2)); + assert!(m.insert(5i, 11i).is_none()); + assert!(m.insert(12, -3).is_none()); + assert!(m.insert(19, 2).is_none()); m.clear(); - assert!(m.find(&5).is_none()); - assert!(m.find(&12).is_none()); - assert!(m.find(&19).is_none()); + assert!(m.get(&5).is_none()); + assert!(m.get(&12).is_none()); + assert!(m.get(&19).is_none()); assert!(m.is_empty()); } @@ -1384,8 +1387,8 @@ mod test_treemap { m.insert(k1.clone(), v1.clone()); m.insert(k2.clone(), v2.clone()); - assert_eq!(m.find(&k2), Some(&v2)); - assert_eq!(m.find(&k1), Some(&v1)); + assert_eq!(m.get(&k2), Some(&v2)); + assert_eq!(m.get(&k1), Some(&v1)); } fn check_equal(ctrl: &[(K, V)], @@ -1393,7 +1396,7 @@ mod test_treemap { assert_eq!(ctrl.is_empty(), map.is_empty()); for x in ctrl.iter() { let &(ref k, ref v) = x; - assert!(map.find(k).unwrap() == v) + assert!(map.get(k).unwrap() == v) } for (map_k, map_v) in map.iter() { let mut found = false; @@ -1455,7 +1458,7 @@ mod test_treemap { let mut ctrl = vec![]; check_equal(ctrl.as_slice(), &map); - assert!(map.find(&5).is_none()); + assert!(map.get(&5).is_none()); let seed: &[_] = &[42]; let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed); @@ -1465,7 +1468,7 @@ mod test_treemap { let k = rng.gen(); let v = rng.gen(); if !ctrl.iter().any(|x| x == &(k, v)) { - assert!(map.insert(k, v)); + assert!(map.insert(k, v).is_none()); ctrl.push((k, v)); check_structure(&map); check_equal(ctrl.as_slice(), &map); @@ -1475,7 +1478,7 @@ mod test_treemap { for _ in range(0u, 30) { let r = rng.gen_range(0, ctrl.len()); let (key, _) = ctrl.remove(r).unwrap(); - assert!(map.remove(&key)); + assert!(map.remove(&key).is_some()); check_structure(&map); check_equal(ctrl.as_slice(), &map); } @@ -1485,19 +1488,19 @@ mod test_treemap { #[test] fn test_len() { let mut m = TreeMap::new(); - assert!(m.insert(3i, 6i)); + assert!(m.insert(3i, 6i).is_none()); assert_eq!(m.len(), 1); - assert!(m.insert(0, 0)); + assert!(m.insert(0, 0).is_none()); assert_eq!(m.len(), 2); - assert!(m.insert(4, 8)); + assert!(m.insert(4, 8).is_none()); assert_eq!(m.len(), 3); - assert!(m.remove(&3)); + assert!(m.remove(&3).is_some()); assert_eq!(m.len(), 2); - assert!(!m.remove(&5)); + assert!(!m.remove(&5).is_some()); assert_eq!(m.len(), 2); - assert!(m.insert(2, 4)); + assert!(m.insert(2, 4).is_none()); assert_eq!(m.len(), 3); - assert!(m.insert(1, 2)); + assert!(m.insert(1, 2).is_none()); assert_eq!(m.len(), 4); } @@ -1505,11 +1508,11 @@ mod test_treemap { fn test_iterator() { let mut m = TreeMap::new(); - assert!(m.insert(3i, 6i)); - assert!(m.insert(0, 0)); - assert!(m.insert(4, 8)); - assert!(m.insert(2, 4)); - assert!(m.insert(1, 2)); + assert!(m.insert(3i, 6i).is_none()); + assert!(m.insert(0, 0).is_none()); + assert!(m.insert(4, 8).is_none()); + assert!(m.insert(2, 4).is_none()); + assert!(m.insert(1, 2).is_none()); let mut n = 0; for (k, v) in m.iter() { @@ -1524,7 +1527,7 @@ mod test_treemap { fn test_interval_iteration() { let mut m = TreeMap::new(); for i in range(1i, 100i) { - assert!(m.insert(i * 2, i * 4)); + assert!(m.insert(i * 2, i * 4).is_none()); } for i in range(1i, 198i) { @@ -1548,11 +1551,11 @@ mod test_treemap { fn test_rev_iter() { let mut m = TreeMap::new(); - assert!(m.insert(3i, 6i)); - assert!(m.insert(0, 0)); - assert!(m.insert(4, 8)); - assert!(m.insert(2, 4)); - assert!(m.insert(1, 2)); + assert!(m.insert(3i, 6i).is_none()); + assert!(m.insert(0, 0).is_none()); + assert!(m.insert(4, 8).is_none()); + assert!(m.insert(2, 4).is_none()); + assert!(m.insert(1, 2).is_none()); let mut n = 4; for (k, v) in m.rev_iter() { @@ -1566,7 +1569,7 @@ mod test_treemap { fn test_mut_iter() { let mut m = TreeMap::new(); for i in range(0u, 10) { - assert!(m.insert(i, 100 * i)); + assert!(m.insert(i, 100 * i).is_none()); } for (i, (&k, v)) in m.iter_mut().enumerate() { @@ -1581,7 +1584,7 @@ mod test_treemap { fn test_mut_rev_iter() { let mut m = TreeMap::new(); for i in range(0u, 10) { - assert!(m.insert(i, 100 * i)); + assert!(m.insert(i, 100 * i).is_none()); } for (i, (&k, v)) in m.rev_iter_mut().enumerate() { @@ -1598,8 +1601,8 @@ mod test_treemap { let mut m_lower = TreeMap::new(); let mut m_upper = TreeMap::new(); for i in range(1i, 100i) { - assert!(m_lower.insert(i * 2, i * 4)); - assert!(m_upper.insert(i * 2, i * 4)); + assert!(m_lower.insert(i * 2, i * 4).is_none()); + assert!(m_upper.insert(i * 2, i * 4).is_none()); } for i in range(1i, 199) { @@ -1653,15 +1656,15 @@ mod test_treemap { let mut b = TreeMap::new(); assert!(a == b); - assert!(a.insert(0i, 5i)); + assert!(a.insert(0i, 5i).is_none()); assert!(a != b); - assert!(b.insert(0, 4)); + assert!(b.insert(0, 4).is_none()); assert!(a != b); - assert!(a.insert(5, 19)); + assert!(a.insert(5, 19).is_none()); assert!(a != b); - assert!(!b.insert(0, 5)); + assert!(!b.insert(0, 5).is_none()); assert!(a != b); - assert!(b.insert(5, 19)); + assert!(b.insert(5, 19).is_none()); assert!(a == b); } @@ -1671,15 +1674,15 @@ mod test_treemap { let mut b = TreeMap::new(); assert!(!(a < b) && !(b < a)); - assert!(b.insert(0i, 5i)); + assert!(b.insert(0i, 5i).is_none()); assert!(a < b); - assert!(a.insert(0, 7)); + assert!(a.insert(0, 7).is_none()); assert!(!(a < b) && b < a); - assert!(b.insert(-2, 0)); + assert!(b.insert(-2, 0).is_none()); assert!(b < a); - assert!(a.insert(-5, 2)); + assert!(a.insert(-5, 2).is_none()); assert!(a < b); - assert!(a.insert(6, 2)); + assert!(a.insert(6, 2).is_none()); assert!(a < b && !(b < a)); } @@ -1689,10 +1692,10 @@ mod test_treemap { let mut b = TreeMap::new(); assert!(a <= b && a >= b); - assert!(a.insert(1i, 1i)); + assert!(a.insert(1i, 1i).is_none()); assert!(a > b && a >= b); assert!(b < a && b <= a); - assert!(b.insert(2, 2)); + assert!(b.insert(2, 2).is_none()); assert!(b > a && b >= a); assert!(a < b && a <= b); } @@ -1720,11 +1723,11 @@ mod test_treemap { let (x4, y4) = (29, 5); let (x5, y5) = (103, 3); - assert!(m.insert(x1, y1)); - assert!(m.insert(x2, y2)); - assert!(m.insert(x3, y3)); - assert!(m.insert(x4, y4)); - assert!(m.insert(x5, y5)); + assert!(m.insert(x1, y1).is_none()); + assert!(m.insert(x2, y2).is_none()); + assert!(m.insert(x3, y3).is_none()); + assert!(m.insert(x4, y4).is_none()); + assert!(m.insert(x5, y5).is_none()); let m = m; let mut a = m.iter(); @@ -1765,7 +1768,7 @@ mod test_treemap { let map: TreeMap = xs.iter().map(|&x| x).collect(); for &(k, v) in xs.iter() { - assert_eq!(map.find(&k), Some(&v)); + assert_eq!(map.get(&k), Some(&v)); } } @@ -1795,17 +1798,17 @@ mod test_treemap { #[test] fn test_swap() { let mut m = TreeMap::new(); - assert_eq!(m.swap(1u, 2i), None); - assert_eq!(m.swap(1u, 3i), Some(2)); - assert_eq!(m.swap(1u, 4i), Some(3)); + assert_eq!(m.insert(1u, 2i), None); + assert_eq!(m.insert(1u, 3i), Some(2)); + assert_eq!(m.insert(1u, 4i), Some(3)); } #[test] fn test_pop() { let mut m = TreeMap::new(); m.insert(1u, 2i); - assert_eq!(m.pop(&1), Some(2)); - assert_eq!(m.pop(&1), None); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); } } @@ -1857,7 +1860,7 @@ mod bench { let mut m : TreeMap = TreeMap::new(); find_rand_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } #[bench] @@ -1865,7 +1868,7 @@ mod bench { let mut m : TreeMap = TreeMap::new(); find_rand_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } // Find seq @@ -1874,7 +1877,7 @@ mod bench { let mut m : TreeMap = TreeMap::new(); find_seq_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } #[bench] @@ -1882,7 +1885,7 @@ mod bench { let mut m : TreeMap = TreeMap::new(); find_seq_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } fn bench_iter(b: &mut Bencher, size: uint) { @@ -1890,7 +1893,7 @@ mod bench { let mut rng = weak_rng(); for _ in range(0, size) { - map.swap(rng.gen(), rng.gen()); + map.insert(rng.gen(), rng.gen()); } b.iter(|| { diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs index d24a8234b20b..22307a5d376b 100644 --- a/src/libcollections/tree/set.rs +++ b/src/libcollections/tree/set.rs @@ -19,6 +19,10 @@ use std::hash::{Writer, Hash}; use tree_map::{TreeMap, Entries, RevEntries, MoveEntries}; +// FIXME(conventions): implement bounded iterators +// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub +// FIXME(conventions): replace rev_iter(_mut) by making iter(_mut) DoubleEnded + /// An implementation of the `Set` trait on top of the `TreeMap` container. The /// only requirement is that the type of the elements contained ascribes to the /// `Ord` trait. @@ -145,6 +149,7 @@ impl TreeSet { /// let mut set: TreeSet = TreeSet::new(); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> TreeSet { TreeSet{map: TreeMap::new()} } /// Gets a lazy iterator over the values in the set, in ascending order. @@ -161,6 +166,7 @@ impl TreeSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> SetItems<'a, T> { SetItems{iter: self.map.iter()} } @@ -197,6 +203,7 @@ impl TreeSet { /// assert_eq!(v, vec![1, 2, 3, 4, 5]); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveSetItems { self.map.into_iter().map(|(value, _)| value) } @@ -261,6 +268,7 @@ impl TreeSet { /// let diff: TreeSet = b.difference(&a).map(|&x| x).collect(); /// assert_eq!(diff, [4, 5].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a TreeSet) -> DifferenceItems<'a, T> { DifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} } @@ -286,6 +294,7 @@ impl TreeSet { /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1, 2, 4, 5].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a TreeSet) -> SymDifferenceItems<'a, T> { SymDifferenceItems{a: self.iter().peekable(), b: other.iter().peekable()} @@ -309,6 +318,7 @@ impl TreeSet { /// let diff: TreeSet = a.intersection(&b).map(|&x| x).collect(); /// assert_eq!(diff, [2, 3].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn intersection<'a>(&'a self, other: &'a TreeSet) -> IntersectionItems<'a, T> { IntersectionItems{a: self.iter().peekable(), b: other.iter().peekable()} @@ -332,6 +342,7 @@ impl TreeSet { /// let diff: TreeSet = a.union(&b).map(|&x| x).collect(); /// assert_eq!(diff, [1, 2, 3, 4, 5].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn union<'a>(&'a self, other: &'a TreeSet) -> UnionItems<'a, T> { UnionItems{a: self.iter().peekable(), b: other.iter().peekable()} } @@ -349,6 +360,7 @@ impl TreeSet { /// assert_eq!(v.len(), 1); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.map.len() } /// Returns true if the set contains no elements @@ -363,6 +375,7 @@ impl TreeSet { /// v.insert(1i); /// assert!(!v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the set, removing all values. @@ -378,6 +391,7 @@ impl TreeSet { /// assert!(v.is_empty()); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.map.clear() } /// Returns `true` if the set contains a value. @@ -392,6 +406,7 @@ impl TreeSet { /// assert_eq!(set.contains(&4), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } @@ -413,6 +428,7 @@ impl TreeSet { /// b.insert(1); /// assert_eq!(a.is_disjoint(&b), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_disjoint(&self, other: &TreeSet) -> bool { self.intersection(other).next().is_none() } @@ -433,6 +449,7 @@ impl TreeSet { /// set.insert(4); /// assert_eq!(set.is_subset(&sup), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &TreeSet) -> bool { let mut x = self.iter(); let mut y = other.iter(); @@ -476,6 +493,7 @@ impl TreeSet { /// set.insert(2); /// assert_eq!(set.is_superset(&sub), true); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_superset(&self, other: &TreeSet) -> bool { other.is_subset(self) } @@ -495,7 +513,8 @@ impl TreeSet { /// assert_eq!(set.len(), 1); /// ``` #[inline] - pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } /// Removes a value from the set. Returns `true` if the value was /// present in the set. @@ -512,7 +531,8 @@ impl TreeSet { /// assert_eq!(set.remove(&2), false); /// ``` #[inline] - pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() } } /// A lazy forward iterator over a set. diff --git a/src/libcollections/trie/map.rs b/src/libcollections/trie/map.rs index 27486de6f199..d604e176a672 100644 --- a/src/libcollections/trie/map.rs +++ b/src/libcollections/trie/map.rs @@ -32,6 +32,10 @@ use std::hash::{Writer, Hash}; use slice::{Items, MutItems}; use slice; +// FIXME(conventions): implement bounded iterators +// FIXME(conventions): implement into_iter +// FIXME(conventions): replace each_reverse by making iter DoubleEnded + // FIXME: #5244: need to manually update the TrieNode constructor const SHIFT: uint = 4; const SIZE: uint = 1 << SHIFT; @@ -59,14 +63,14 @@ enum Child { /// map.insert(1, "Martin"); /// /// assert_eq!(map.len(), 3); -/// assert_eq!(map.find(&1), Some(&"Martin")); +/// assert_eq!(map.get(&1), Some(&"Martin")); /// /// if !map.contains_key(&90) { /// println!("Nobody is keyed 90"); /// } /// /// // Update a key -/// match map.find_mut(&1) { +/// match map.get_mut(&1) { /// Some(value) => *value = "Olga", /// None => (), /// } @@ -140,6 +144,7 @@ impl TrieMap { /// let mut map: TrieMap<&str> = TrieMap::new(); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> TrieMap { TrieMap{root: TrieNode::new(), length: 0} } @@ -169,12 +174,14 @@ impl TrieMap { /// Gets an iterator visiting all keys in ascending order by the keys. /// The iterator's element type is `uint`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'r>(&'r self) -> Keys<'r, T> { self.iter().map(|(k, _v)| k) } /// Gets an iterator visiting all values in ascending order by the keys. /// The iterator's element type is `&'r T`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'r>(&'r self) -> Values<'r, T> { self.iter().map(|(_k, v)| v) } @@ -191,6 +198,7 @@ impl TrieMap { /// println!("{}: {}", key, value); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> Entries<'a, T> { let mut iter = unsafe {Entries::new()}; iter.stack[0] = self.root.children.iter(); @@ -214,10 +222,11 @@ impl TrieMap { /// *value = -(key as int); /// } /// - /// assert_eq!(map.find(&1), Some(&-1)); - /// assert_eq!(map.find(&2), Some(&-2)); - /// assert_eq!(map.find(&3), Some(&-3)); + /// assert_eq!(map.get(&1), Some(&-1)); + /// assert_eq!(map.get(&2), Some(&-2)); + /// assert_eq!(map.get(&3), Some(&-3)); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut<'a>(&'a mut self) -> MutEntries<'a, T> { let mut iter = unsafe {MutEntries::new()}; iter.stack[0] = self.root.children.iter_mut(); @@ -241,6 +250,7 @@ impl TrieMap { /// assert_eq!(a.len(), 1); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.length } /// Return true if the map contains no elements. @@ -256,6 +266,7 @@ impl TrieMap { /// assert!(!a.is_empty()); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the map, removing all values. @@ -271,11 +282,18 @@ impl TrieMap { /// assert!(a.is_empty()); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.root = TrieNode::new(); self.length = 0; } + /// Deprecated: renamed to `get`. + #[deprecated = "renamed to `get`"] + pub fn find(&self, key: &uint) -> Option<&T> { + self.get(key) + } + /// Returns a reference to the value corresponding to the key. /// /// # Example @@ -285,12 +303,13 @@ impl TrieMap { /// /// let mut map = TrieMap::new(); /// map.insert(1, "a"); - /// assert_eq!(map.find(&1), Some(&"a")); - /// assert_eq!(map.find(&2), None); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); /// ``` #[inline] - pub fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { - let mut node: &'a TrieNode = &self.root; + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&self, key: &uint) -> Option<&T> { + let mut node = &self.root; let mut idx = 0; loop { match node.children[chunk(*key, idx)] { @@ -321,8 +340,15 @@ impl TrieMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains_key(&self, key: &uint) -> bool { - self.find(key).is_some() + self.get(key).is_some() + } + + /// Deprecated: renamed to `get_mut`. + #[deprecated = "renamed to `get_mut`"] + pub fn find_mut(&mut self, key: &uint) -> Option<&mut T> { + self.get_mut(key) } /// Returns a mutable reference to the value corresponding to the key. @@ -334,52 +360,22 @@ impl TrieMap { /// /// let mut map = TrieMap::new(); /// map.insert(1, "a"); - /// match map.find_mut(&1) { + /// match map.get_mut(&1) { /// Some(x) => *x = "b", /// None => (), /// } /// assert_eq!(map[1], "b"); /// ``` #[inline] - pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> { find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1) } - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// assert_eq!(map.insert(2, "value"), true); - /// assert_eq!(map.insert(2, "value2"), false); - /// assert_eq!(map[2], "value2"); - /// ``` - #[inline] - pub fn insert(&mut self, key: uint, value: T) -> bool { - self.swap(key, value).is_none() - } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::TrieMap; - /// - /// let mut map = TrieMap::new(); - /// assert_eq!(map.remove(&1), false); - /// map.insert(1, "a"); - /// assert_eq!(map.remove(&1), true); - /// ``` - #[inline] - pub fn remove(&mut self, key: &uint) -> bool { - self.pop(key).is_some() + /// Deprecated: Renamed to `insert`. + #[deprecated = "Renamed to `insert`"] + pub fn swap(&mut self, key: uint, value: T) -> Option { + self.insert(key, value) } /// Inserts a key-value pair from the map. If the key already had a value @@ -391,14 +387,15 @@ impl TrieMap { /// use std::collections::TrieMap; /// /// let mut map = TrieMap::new(); - /// assert_eq!(map.swap(37, "a"), None); + /// assert_eq!(map.insert(37, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); - /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[37], "c"); /// ``` - pub fn swap(&mut self, key: uint, value: T) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, key: uint, value: T) -> Option { let ret = insert(&mut self.root.count, &mut self.root.children[chunk(key, 0)], key, value, 1); @@ -406,6 +403,12 @@ impl TrieMap { ret } + /// Deprecated: Renamed to `remove`. + #[deprecated = "Renamed to `remove`"] + pub fn pop(&mut self, key: &uint) -> Option { + self.remove(key) + } + /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// @@ -416,10 +419,11 @@ impl TrieMap { /// /// let mut map = TrieMap::new(); /// map.insert(1, "a"); - /// assert_eq!(map.pop(&1), Some("a")); - /// assert_eq!(map.pop(&1), None); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); /// ``` - pub fn pop(&mut self, key: &uint) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, key: &uint) -> Option { let ret = remove(&mut self.root.count, &mut self.root.children[chunk(*key, 0)], *key, 1); @@ -582,9 +586,9 @@ impl TrieMap { /// *value = "changed"; /// } /// - /// assert_eq!(map.find(&2), Some(&"a")); - /// assert_eq!(map.find(&4), Some(&"changed")); - /// assert_eq!(map.find(&6), Some(&"changed")); + /// assert_eq!(map.get(&2), Some(&"a")); + /// assert_eq!(map.get(&4), Some(&"changed")); + /// assert_eq!(map.get(&6), Some(&"changed")); /// ``` pub fn lower_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> { self.bound_mut(key, false) @@ -607,9 +611,9 @@ impl TrieMap { /// *value = "changed"; /// } /// - /// assert_eq!(map.find(&2), Some(&"a")); - /// assert_eq!(map.find(&4), Some(&"b")); - /// assert_eq!(map.find(&6), Some(&"changed")); + /// assert_eq!(map.get(&2), Some(&"a")); + /// assert_eq!(map.get(&4), Some(&"b")); + /// assert_eq!(map.get(&6), Some(&"changed")); /// ``` pub fn upper_bound_mut<'a>(&'a mut self, key: uint) -> MutEntries<'a, T> { self.bound_mut(key, true) @@ -643,14 +647,14 @@ impl> Hash for TrieMap { impl Index for TrieMap { #[inline] fn index<'a>(&'a self, i: &uint) -> &'a T { - self.find(i).expect("key not present") + self.get(i).expect("key not present") } } impl IndexMut for TrieMap { #[inline] fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut T { - self.find_mut(i).expect("key not present") + self.get_mut(i).expect("key not present") } } @@ -957,24 +961,24 @@ mod test { #[test] fn test_find_mut() { let mut m = TrieMap::new(); - assert!(m.insert(1u, 12i)); - assert!(m.insert(2u, 8i)); - assert!(m.insert(5u, 14i)); + assert!(m.insert(1u, 12i).is_none()); + assert!(m.insert(2u, 8i).is_none()); + assert!(m.insert(5u, 14i).is_none()); let new = 100; - match m.find_mut(&5) { + match m.get_mut(&5) { None => panic!(), Some(x) => *x = new } - assert_eq!(m.find(&5), Some(&new)); + assert_eq!(m.get(&5), Some(&new)); } #[test] fn test_find_mut_missing() { let mut m = TrieMap::new(); - assert!(m.find_mut(&0).is_none()); - assert!(m.insert(1u, 12i)); - assert!(m.find_mut(&0).is_none()); - assert!(m.insert(2, 8)); - assert!(m.find_mut(&0).is_none()); + assert!(m.get_mut(&0).is_none()); + assert!(m.insert(1u, 12i).is_none()); + assert!(m.get_mut(&0).is_none()); + assert!(m.insert(2, 8).is_none()); + assert!(m.get_mut(&0).is_none()); } #[test] @@ -983,32 +987,32 @@ mod test { let n = 300u; for x in range_step(1u, n, 2) { - assert!(trie.insert(x, x + 1)); + assert!(trie.insert(x, x + 1).is_none()); assert!(trie.contains_key(&x)); check_integrity(&trie.root); } for x in range_step(0u, n, 2) { assert!(!trie.contains_key(&x)); - assert!(trie.insert(x, x + 1)); + assert!(trie.insert(x, x + 1).is_none()); check_integrity(&trie.root); } for x in range(0u, n) { assert!(trie.contains_key(&x)); - assert!(!trie.insert(x, x + 1)); + assert!(!trie.insert(x, x + 1).is_none()); check_integrity(&trie.root); } for x in range_step(1u, n, 2) { - assert!(trie.remove(&x)); + assert!(trie.remove(&x).is_some()); assert!(!trie.contains_key(&x)); check_integrity(&trie.root); } for x in range_step(0u, n, 2) { assert!(trie.contains_key(&x)); - assert!(!trie.insert(x, x + 1)); + assert!(!trie.insert(x, x + 1).is_none()); check_integrity(&trie.root); } } @@ -1017,11 +1021,11 @@ mod test { fn test_each_reverse() { let mut m = TrieMap::new(); - assert!(m.insert(3, 6)); - assert!(m.insert(0, 0)); - assert!(m.insert(4, 8)); - assert!(m.insert(2, 4)); - assert!(m.insert(1, 2)); + assert!(m.insert(3, 6).is_none()); + assert!(m.insert(0, 0).is_none()); + assert!(m.insert(4, 8).is_none()); + assert!(m.insert(2, 4).is_none()); + assert!(m.insert(1, 2).is_none()); let mut n = 4; m.each_reverse(|k, v| { @@ -1054,19 +1058,19 @@ mod test { } #[test] - fn test_swap() { + fn test_insert() { let mut m = TrieMap::new(); - assert_eq!(m.swap(1u, 2i), None); - assert_eq!(m.swap(1u, 3i), Some(2)); - assert_eq!(m.swap(1u, 4i), Some(3)); + assert_eq!(m.insert(1u, 2i), None); + assert_eq!(m.insert(1u, 3i), Some(2)); + assert_eq!(m.insert(1u, 4i), Some(3)); } #[test] - fn test_pop() { + fn test_remove() { let mut m = TrieMap::new(); m.insert(1u, 2i); - assert_eq!(m.pop(&1), Some(2)); - assert_eq!(m.pop(&1), None); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); } #[test] @@ -1076,7 +1080,7 @@ mod test { let map: TrieMap = xs.iter().map(|&x| x).collect(); for &(k, v) in xs.iter() { - assert_eq!(map.find(&k), Some(&v)); + assert_eq!(map.get(&k), Some(&v)); } } @@ -1243,15 +1247,15 @@ mod test { let mut b = TrieMap::new(); assert!(a == b); - assert!(a.insert(0, 5i)); + assert!(a.insert(0, 5i).is_none()); assert!(a != b); - assert!(b.insert(0, 4i)); + assert!(b.insert(0, 4i).is_none()); assert!(a != b); - assert!(a.insert(5, 19)); + assert!(a.insert(5, 19).is_none()); assert!(a != b); - assert!(!b.insert(0, 5)); + assert!(!b.insert(0, 5).is_none()); assert!(a != b); - assert!(b.insert(5, 19)); + assert!(b.insert(5, 19).is_none()); assert!(a == b); } @@ -1261,15 +1265,15 @@ mod test { let mut b = TrieMap::new(); assert!(!(a < b) && !(b < a)); - assert!(b.insert(2u, 5i)); + assert!(b.insert(2u, 5i).is_none()); assert!(a < b); - assert!(a.insert(2, 7)); + assert!(a.insert(2, 7).is_none()); assert!(!(a < b) && b < a); - assert!(b.insert(1, 0)); + assert!(b.insert(1, 0).is_none()); assert!(b < a); - assert!(a.insert(0, 6)); + assert!(a.insert(0, 6).is_none()); assert!(a < b); - assert!(a.insert(6, 2)); + assert!(a.insert(6, 2).is_none()); assert!(a < b && !(b < a)); } @@ -1279,10 +1283,10 @@ mod test { let mut b = TrieMap::new(); assert!(a <= b && a >= b); - assert!(a.insert(1u, 1i)); + assert!(a.insert(1u, 1i).is_none()); assert!(a > b && a >= b); assert!(b < a && b <= a); - assert!(b.insert(2, 2)); + assert!(b.insert(2, 2).is_none()); assert!(b > a && b >= a); assert!(a < b && a <= b); } @@ -1355,7 +1359,7 @@ mod bench { let mut rng = weak_rng(); for _ in range(0, size) { - map.swap(rng.gen(), rng.gen()); + map.insert(rng.gen(), rng.gen()); } b.iter(|| { diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs index ddddd279b046..dd5a81fe96ee 100644 --- a/src/libcollections/trie/set.rs +++ b/src/libcollections/trie/set.rs @@ -8,6 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// FIXME(conventions): implement bounded iterators +// FIXME(conventions): implement union family of fns +// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub +// FIXME(conventions): replace each_reverse by making iter DoubleEnded +// FIXME(conventions): implement iter_mut and into_iter + use core::prelude::*; use core::default::Default; @@ -79,6 +85,7 @@ impl TrieSet { /// let mut set = TrieSet::new(); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> TrieSet { TrieSet{map: TrieMap::new()} } @@ -126,6 +133,7 @@ impl TrieSet { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> SetItems<'a> { SetItems{iter: self.map.iter()} } @@ -177,6 +185,7 @@ impl TrieSet { /// assert_eq!(v.len(), 1); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.map.len() } /// Returns true if the set contains no elements @@ -191,6 +200,7 @@ impl TrieSet { /// v.insert(1); /// assert!(!v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the set, removing all values. @@ -206,6 +216,7 @@ impl TrieSet { /// assert!(v.is_empty()); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.map.clear() } /// Returns `true` if the set contains a value. @@ -220,6 +231,7 @@ impl TrieSet { /// assert_eq!(set.contains(&4), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) } @@ -242,6 +254,7 @@ impl TrieSet { /// assert_eq!(a.is_disjoint(&b), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_disjoint(&self, other: &TrieSet) -> bool { self.iter().all(|v| !other.contains(&v)) } @@ -263,6 +276,7 @@ impl TrieSet { /// assert_eq!(set.is_subset(&sup), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &TrieSet) -> bool { self.iter().all(|v| other.contains(&v)) } @@ -287,6 +301,7 @@ impl TrieSet { /// assert_eq!(set.is_superset(&sub), true); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_superset(&self, other: &TrieSet) -> bool { other.is_subset(self) } @@ -306,8 +321,9 @@ impl TrieSet { /// assert_eq!(set.len(), 1); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn insert(&mut self, value: uint) -> bool { - self.map.insert(value, ()) + self.map.insert(value, ()).is_none() } /// Removes a value from the set. Returns `true` if the value was @@ -325,8 +341,9 @@ impl TrieSet { /// assert_eq!(set.remove(&2), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn remove(&mut self, value: &uint) -> bool { - self.map.remove(value) + self.map.remove(value).is_some() } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 4b6921ed0c0d..707084d9c70b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -312,7 +312,7 @@ impl Vec { #[inline] #[experimental] pub fn push_all(&mut self, other: &[T]) { - self.reserve_additional(other.len()); + self.reserve(other.len()); for i in range(0, other.len()) { let len = self.len(); @@ -342,7 +342,7 @@ impl Vec { /// ``` #[stable] pub fn grow(&mut self, n: uint, value: T) { - self.reserve_additional(n); + self.reserve(n); let mut i: uint = 0u; while i < n { @@ -489,7 +489,7 @@ impl Extendable for Vec { #[inline] fn extend>(&mut self, mut iterator: I) { let (lower, _) = iterator.size_hint(); - self.reserve_additional(lower); + self.reserve(lower); for element in iterator { self.push(element) } @@ -578,74 +578,70 @@ impl Vec { self.cap } - /// Reserves capacity for at least `n` additional elements in the given - /// vector. - /// - /// # Failure - /// - /// Fails if the new capacity overflows `uint`. - /// - /// # Example - /// - /// ``` - /// let mut vec: Vec = vec![1i]; - /// vec.reserve_additional(10); - /// assert!(vec.capacity() >= 11); - /// ``` + /// Deprecated: Renamed to `reserve`. + #[deprecated = "Renamed to `reserve`"] pub fn reserve_additional(&mut self, extra: uint) { - if self.cap - self.len < extra { - match self.len.checked_add(&extra) { - None => panic!("Vec::reserve_additional: `uint` overflow"), - Some(new_cap) => self.reserve(new_cap) - } - } + self.reserve(extra) } - /// Reserves capacity for at least `n` elements in the given vector. + /// Reserves capacity for at least `additional` more elements to be inserted in the given + /// `Vec`. The collection may reserve more space to avoid frequent reallocations. /// - /// This function will over-allocate in order to amortize the allocation - /// costs in scenarios where the caller may need to repeatedly reserve - /// additional space. + /// # Panics /// - /// If the capacity for `self` is already equal to or greater than the - /// requested capacity, then no action is taken. + /// Panics if the new capacity overflows `uint`. /// /// # Example /// /// ``` - /// let mut vec = vec![1i, 2, 3]; + /// let mut vec: Vec = vec![1]; /// vec.reserve(10); - /// assert!(vec.capacity() >= 10); + /// assert!(vec.capacity() >= 11); /// ``` - pub fn reserve(&mut self, capacity: uint) { - if capacity > self.cap { - self.reserve_exact(num::next_power_of_two(capacity)) + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve(&mut self, additional: uint) { + if self.cap - self.len < additional { + match self.len.checked_add(&additional) { + None => panic!("Vec::reserve: `uint` overflow"), + // if the checked_add + Some(new_cap) => { + let amort_cap = num::next_power_of_two(new_cap); + // next_power_of_two will overflow to exactly 0 for really big capacities + if amort_cap == 0 { + self.grow_capacity(new_cap); + } else { + self.grow_capacity(amort_cap); + } + } + } } } - /// Reserves capacity for exactly `capacity` elements in the given vector. + /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the + /// given `Vec`. Does nothing if the capacity is already sufficient. /// - /// If the capacity for `self` is already equal to or greater than the - /// requested capacity, then no action is taken. + /// Note that the allocator may give the collection more space than it requests. Therefore + /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future + /// insertions are expected. + /// + /// # Panics + /// + /// Panics if the new capacity overflows `uint`. /// /// # Example /// /// ``` - /// let mut vec: Vec = Vec::with_capacity(10); - /// vec.reserve_exact(11); - /// assert_eq!(vec.capacity(), 11); + /// let mut vec: Vec = vec![1]; + /// vec.reserve_exact(10); + /// assert!(vec.capacity() >= 11); /// ``` - pub fn reserve_exact(&mut self, capacity: uint) { - if mem::size_of::() == 0 { return } - - if capacity > self.cap { - let size = capacity.checked_mul(&mem::size_of::()) - .expect("capacity overflow"); - unsafe { - self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::(), size); - if self.ptr.is_null() { ::alloc::oom() } + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn reserve_exact(&mut self, additional: uint) { + if self.cap - self.len < additional { + match self.len.checked_add(&additional) { + None => panic!("Vec::reserve: `uint` overflow"), + Some(new_cap) => self.grow_capacity(new_cap) } - self.cap = capacity; } } @@ -663,6 +659,7 @@ impl Vec { /// assert!(vec.capacity() >= 3); /// ``` #[stable] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn shrink_to_fit(&mut self) { if mem::size_of::() == 0 { return } @@ -713,7 +710,7 @@ impl Vec { /// vec.truncate(2); /// assert_eq!(vec, vec![1, 2]); /// ``` - #[unstable = "waiting on panic semantics"] + #[unstable = "matches collection reform specification; waiting on panic semantics"] pub fn truncate(&mut self, len: uint) { unsafe { // drop any extra elements @@ -761,6 +758,7 @@ impl Vec { /// } /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveItems { unsafe { let ptr = self.ptr; @@ -796,26 +794,6 @@ impl Vec { self.len = len; } - /// Returns a mutable reference to the value at index `index`. - /// - /// # Failure - /// - /// Fails if `index` is out of bounds - /// - /// # Example - /// - /// ``` - /// # #![allow(deprecated)] - /// let mut vec = vec![1i, 2, 3]; - /// *vec.get_mut(1) = 4; - /// assert_eq!(vec, vec![1i, 4, 3]); - /// ``` - #[inline] - #[deprecated = "use `foo[index] = bar` instead"] - pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T { - &mut self.as_mut_slice()[index] - } - /// Removes an element from anywhere in the vector and return it, replacing /// it with the last element. This does not preserve ordering, but is O(1). /// @@ -868,7 +846,7 @@ impl Vec { let len = self.len(); assert!(index <= len); // space for the new element - self.reserve(len + 1); + self.reserve(1); unsafe { // infallible // The spot to put the new value @@ -970,7 +948,7 @@ impl Vec { /// ``` #[unstable = "this function may be renamed or change to unboxed closures"] pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) { - self.reserve_additional(n); + self.reserve(n); for i in range(0u, n) { self.push(f(i)); } @@ -1076,7 +1054,26 @@ impl Vec { /// v.push(1i); /// assert!(!v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } + + /// Reserves capacity for exactly `capacity` elements in the given vector. + /// + /// If the capacity for `self` is already equal to or greater than the + /// requested capacity, then no action is taken. + fn grow_capacity(&mut self, capacity: uint) { + if mem::size_of::() == 0 { return } + + if capacity > self.cap { + let size = capacity.checked_mul(&mem::size_of::()) + .expect("capacity overflow"); + unsafe { + self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::(), size); + if self.ptr.is_null() { ::alloc::oom() } + } + self.cap = capacity; + } + } } impl Vec { @@ -1742,11 +1739,11 @@ mod tests { } #[test] - fn test_reserve_additional() { + fn test_reserve() { let mut v = Vec::new(); assert_eq!(v.capacity(), 0); - v.reserve_additional(2); + v.reserve(2); assert!(v.capacity() >= 2); for i in range(0i, 16) { @@ -1754,12 +1751,12 @@ mod tests { } assert!(v.capacity() >= 16); - v.reserve_additional(16); + v.reserve(16); assert!(v.capacity() >= 32); v.push(16); - v.reserve_additional(16); + v.reserve(16); assert!(v.capacity() >= 33) } diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index c0bc785126c7..38a345272b04 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -26,6 +26,8 @@ use vec::Vec; use hash; use hash::Hash; +// FIXME(conventions): capacity management??? + /// A map optimized for small integer keys. /// /// # Example @@ -42,14 +44,14 @@ use hash::Hash; /// println!("The end is near!"); /// } /// -/// assert_eq!(months.find(&1), Some(&"Jan")); +/// assert_eq!(months.get(&1), Some(&"Jan")); /// -/// match months.find_mut(&3) { +/// match months.get_mut(&3) { /// Some(value) => *value = "Venus", /// None => (), /// } /// -/// assert_eq!(months.find(&3), Some(&"Venus")); +/// assert_eq!(months.get(&3), Some(&"Venus")); /// /// // Print out all months /// for (key, value) in months.iter() { @@ -77,10 +79,7 @@ impl Clone for VecMap { #[inline] fn clone_from(&mut self, source: &VecMap) { - self.v.reserve(source.v.len()); - for (i, w) in self.v.iter_mut().enumerate() { - *w = source.v[i].clone(); - } + self.v.clone_from(&source.v); } } @@ -99,6 +98,7 @@ impl VecMap { /// use std::collections::VecMap; /// let mut map: VecMap<&str> = VecMap::new(); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> VecMap { VecMap{v: vec!()} } /// Creates an empty `VecMap` with space for at least `capacity` @@ -110,18 +110,21 @@ impl VecMap { /// use std::collections::VecMap; /// let mut map: VecMap<&str> = VecMap::with_capacity(10); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(capacity: uint) -> VecMap { VecMap { v: Vec::with_capacity(capacity) } } /// Returns an iterator visiting all keys in ascending order by the keys. /// The iterator's element type is `uint`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys<'r>(&'r self) -> Keys<'r, V> { self.iter().map(|(k, _v)| k) } /// Returns an iterator visiting all values in ascending order by the keys. /// The iterator's element type is `&'r V`. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values<'r>(&'r self) -> Values<'r, V> { self.iter().map(|(_k, v)| v) } @@ -144,6 +147,7 @@ impl VecMap { /// println!("{}: {}", key, value); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'r>(&'r self) -> Entries<'r, V> { Entries { front: 0, @@ -174,6 +178,7 @@ impl VecMap { /// assert_eq!(value, &"x"); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut<'r>(&'r mut self) -> MutEntries<'r, V> { MutEntries { front: 0, @@ -201,6 +206,7 @@ impl VecMap { /// /// assert_eq!(vec, vec![(1, "a"), (2, "b"), (3, "c")]); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(&mut self) -> FilterMap<(uint, Option), (uint, V), Enumerate>>> @@ -223,6 +229,7 @@ impl VecMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.v.iter().filter(|elt| elt.is_some()).count() } @@ -239,6 +246,7 @@ impl VecMap { /// a.insert(1, "a"); /// assert!(!a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.v.iter().all(|elt| elt.is_none()) } @@ -255,8 +263,15 @@ impl VecMap { /// a.clear(); /// assert!(a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.v.clear() } + /// Deprecated: Renamed to `get`. + #[deprecated = "Renamed to `get`"] + pub fn find(&self, key: &uint) -> Option<&V> { + self.get(key) + } + /// Returns a reference to the value corresponding to the key. /// /// # Example @@ -266,10 +281,11 @@ impl VecMap { /// /// let mut map = VecMap::new(); /// map.insert(1, "a"); - /// assert_eq!(map.find(&1), Some(&"a")); - /// assert_eq!(map.find(&2), None); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); /// ``` - pub fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&self, key: &uint) -> Option<&V> { if *key < self.v.len() { match self.v[*key] { Some(ref value) => Some(value), @@ -293,8 +309,15 @@ impl VecMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains_key(&self, key: &uint) -> bool { - self.find(key).is_some() + self.get(key).is_some() + } + + /// Deprecated: Renamed to `get_mut`. + #[deprecated = "Renamed to `get_mut`"] + pub fn find_mut(&mut self, key: &uint) -> Option<&mut V> { + self.get_mut(key) } /// Returns a mutable reference to the value corresponding to the key. @@ -306,13 +329,14 @@ impl VecMap { /// /// let mut map = VecMap::new(); /// map.insert(1, "a"); - /// match map.find_mut(&1) { + /// match map.get_mut(&1) { /// Some(x) => *x = "b", /// None => (), /// } /// assert_eq!(map[1], "b"); /// ``` - pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get_mut(&mut self, key: &uint) -> Option<&mut V> { if *key < self.v.len() { match *(&mut self.v[*key]) { Some(ref mut value) => Some(value), @@ -323,45 +347,10 @@ impl VecMap { } } - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::VecMap; - /// - /// let mut map = VecMap::new(); - /// assert_eq!(map.insert(2, "value"), true); - /// assert_eq!(map.insert(2, "value2"), false); - /// assert_eq!(map[2], "value2"); - /// ``` - pub fn insert(&mut self, key: uint, value: V) -> bool { - let exists = self.contains_key(&key); - let len = self.v.len(); - if len <= key { - self.v.grow_fn(key - len + 1, |_| None); - } - self.v[key] = Some(value); - !exists - } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::VecMap; - /// - /// let mut map = VecMap::new(); - /// assert_eq!(map.remove(&1), false); - /// map.insert(1, "a"); - /// assert_eq!(map.remove(&1), true); - /// ``` - pub fn remove(&mut self, key: &uint) -> bool { - self.pop(key).is_some() + /// Deprecated: Renamed to `insert`. + #[deprecated = "Renamed to `insert`"] + pub fn swap(&mut self, key: uint, value: V) -> Option { + self.insert(key, value) } /// Inserts a key-value pair from the map. If the key already had a value @@ -373,20 +362,26 @@ impl VecMap { /// use std::collections::VecMap; /// /// let mut map = VecMap::new(); - /// assert_eq!(map.swap(37, "a"), None); + /// assert_eq!(map.insert(37, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); - /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[37], "c"); /// ``` - pub fn swap(&mut self, key: uint, value: V) -> Option { - match self.find_mut(&key) { - Some(loc) => { return Some(replace(loc, value)); } - None => () + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, key: uint, value: V) -> Option { + let len = self.v.len(); + if len <= key { + self.v.grow_fn(key - len + 1, |_| None); } - self.insert(key, value); - return None; + replace(&mut self.v[key], Some(value)) + } + + /// Deprecated: Renamed to `remove`. + #[deprecated = "Renamed to `remove`"] + pub fn pop(&mut self, key: &uint) -> Option { + self.remove(key) } /// Removes a key from the map, returning the value at the key if the key @@ -399,10 +394,11 @@ impl VecMap { /// /// let mut map = VecMap::new(); /// map.insert(1, "a"); - /// assert_eq!(map.pop(&1), Some("a")); - /// assert_eq!(map.pop(&1), None); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); /// ``` - pub fn pop(&mut self, key: &uint) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, key: &uint) -> Option { if *key >= self.v.len() { return None; } @@ -460,11 +456,11 @@ impl VecMap { val: V, ff: |uint, V, V| -> V) -> bool { - let new_val = match self.find(&key) { + let new_val = match self.get(&key) { None => val, Some(orig) => ff(key, (*orig).clone(), val) }; - self.insert(key, new_val) + self.insert(key, new_val).is_none() } } @@ -514,14 +510,14 @@ impl Extendable<(uint, V)> for VecMap { impl Index for VecMap { #[inline] fn index<'a>(&'a self, i: &uint) -> &'a V { - self.find(i).expect("key not present") + self.get(i).expect("key not present") } } impl IndexMut for VecMap { #[inline] fn index_mut<'a>(&'a mut self, i: &uint) -> &'a mut V { - self.find_mut(i).expect("key not present") + self.get_mut(i).expect("key not present") } } @@ -615,16 +611,16 @@ mod test_map { use super::VecMap; #[test] - fn test_find_mut() { + fn test_get_mut() { let mut m = VecMap::new(); - assert!(m.insert(1, 12i)); - assert!(m.insert(2, 8)); - assert!(m.insert(5, 14)); + assert!(m.insert(1, 12i).is_none()); + assert!(m.insert(2, 8).is_none()); + assert!(m.insert(5, 14).is_none()); let new = 100; - match m.find_mut(&5) { + match m.get_mut(&5) { None => panic!(), Some(x) => *x = new } - assert_eq!(m.find(&5), Some(&new)); + assert_eq!(m.get(&5), Some(&new)); } #[test] @@ -632,13 +628,13 @@ mod test_map { let mut map = VecMap::new(); assert_eq!(map.len(), 0); assert!(map.is_empty()); - assert!(map.insert(5, 20i)); + assert!(map.insert(5, 20i).is_none()); assert_eq!(map.len(), 1); assert!(!map.is_empty()); - assert!(map.insert(11, 12)); + assert!(map.insert(11, 12).is_none()); assert_eq!(map.len(), 2); assert!(!map.is_empty()); - assert!(map.insert(14, 22)); + assert!(map.insert(14, 22).is_none()); assert_eq!(map.len(), 3); assert!(!map.is_empty()); } @@ -646,14 +642,14 @@ mod test_map { #[test] fn test_clear() { let mut map = VecMap::new(); - assert!(map.insert(5, 20i)); - assert!(map.insert(11, 12)); - assert!(map.insert(14, 22)); + assert!(map.insert(5, 20i).is_none()); + assert!(map.insert(11, 12).is_none()); + assert!(map.insert(14, 22).is_none()); map.clear(); assert!(map.is_empty()); - assert!(map.find(&5).is_none()); - assert!(map.find(&11).is_none()); - assert!(map.find(&14).is_none()); + assert!(map.get(&5).is_none()); + assert!(map.get(&11).is_none()); + assert!(map.get(&14).is_none()); } #[test] @@ -678,28 +674,28 @@ mod test_map { map.update_with_key(3, 2, add_more_to_count); // check the total counts - assert_eq!(map.find(&3).unwrap(), &10); - assert_eq!(map.find(&5).unwrap(), &3); - assert_eq!(map.find(&9).unwrap(), &1); + assert_eq!(map.get(&3).unwrap(), &10); + assert_eq!(map.get(&5).unwrap(), &3); + assert_eq!(map.get(&9).unwrap(), &1); // sadly, no sevens were counted - assert!(map.find(&7).is_none()); + assert!(map.get(&7).is_none()); } #[test] - fn test_swap() { + fn test_insert() { let mut m = VecMap::new(); - assert_eq!(m.swap(1, 2i), None); - assert_eq!(m.swap(1, 3i), Some(2)); - assert_eq!(m.swap(1, 4i), Some(3)); + assert_eq!(m.insert(1, 2i), None); + assert_eq!(m.insert(1, 3i), Some(2)); + assert_eq!(m.insert(1, 4i), Some(3)); } #[test] - fn test_pop() { + fn test_remove() { let mut m = VecMap::new(); m.insert(1, 2i); - assert_eq!(m.pop(&1), Some(2)); - assert_eq!(m.pop(&1), None); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); } #[test] @@ -732,11 +728,11 @@ mod test_map { fn test_iterator() { let mut m = VecMap::new(); - assert!(m.insert(0, 1i)); - assert!(m.insert(1, 2)); - assert!(m.insert(3, 5)); - assert!(m.insert(6, 10)); - assert!(m.insert(10, 11)); + assert!(m.insert(0, 1i).is_none()); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(3, 5).is_none()); + assert!(m.insert(6, 10).is_none()); + assert!(m.insert(10, 11).is_none()); let mut it = m.iter(); assert_eq!(it.size_hint(), (0, Some(11))); @@ -757,11 +753,11 @@ mod test_map { fn test_iterator_size_hints() { let mut m = VecMap::new(); - assert!(m.insert(0, 1i)); - assert!(m.insert(1, 2)); - assert!(m.insert(3, 5)); - assert!(m.insert(6, 10)); - assert!(m.insert(10, 11)); + assert!(m.insert(0, 1i).is_none()); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(3, 5).is_none()); + assert!(m.insert(6, 10).is_none()); + assert!(m.insert(10, 11).is_none()); assert_eq!(m.iter().size_hint(), (0, Some(11))); assert_eq!(m.iter().rev().size_hint(), (0, Some(11))); @@ -773,11 +769,11 @@ mod test_map { fn test_mut_iterator() { let mut m = VecMap::new(); - assert!(m.insert(0, 1i)); - assert!(m.insert(1, 2)); - assert!(m.insert(3, 5)); - assert!(m.insert(6, 10)); - assert!(m.insert(10, 11)); + assert!(m.insert(0, 1i).is_none()); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(3, 5).is_none()); + assert!(m.insert(6, 10).is_none()); + assert!(m.insert(10, 11).is_none()); for (k, v) in m.iter_mut() { *v += k as int; @@ -796,11 +792,11 @@ mod test_map { fn test_rev_iterator() { let mut m = VecMap::new(); - assert!(m.insert(0, 1i)); - assert!(m.insert(1, 2)); - assert!(m.insert(3, 5)); - assert!(m.insert(6, 10)); - assert!(m.insert(10, 11)); + assert!(m.insert(0, 1i).is_none()); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(3, 5).is_none()); + assert!(m.insert(6, 10).is_none()); + assert!(m.insert(10, 11).is_none()); let mut it = m.iter().rev(); assert_eq!(it.next().unwrap(), (10, &11)); @@ -815,11 +811,11 @@ mod test_map { fn test_mut_rev_iterator() { let mut m = VecMap::new(); - assert!(m.insert(0, 1i)); - assert!(m.insert(1, 2)); - assert!(m.insert(3, 5)); - assert!(m.insert(6, 10)); - assert!(m.insert(10, 11)); + assert!(m.insert(0, 1i).is_none()); + assert!(m.insert(1, 2).is_none()); + assert!(m.insert(3, 5).is_none()); + assert!(m.insert(6, 10).is_none()); + assert!(m.insert(10, 11).is_none()); for (k, v) in m.iter_mut().rev() { *v += k as int; @@ -880,15 +876,15 @@ mod test_map { let mut b = VecMap::new(); assert!(a == b); - assert!(a.insert(0, 5i)); + assert!(a.insert(0, 5i).is_none()); assert!(a != b); - assert!(b.insert(0, 4i)); + assert!(b.insert(0, 4i).is_none()); assert!(a != b); - assert!(a.insert(5, 19)); + assert!(a.insert(5, 19).is_none()); assert!(a != b); - assert!(!b.insert(0, 5)); + assert!(!b.insert(0, 5).is_none()); assert!(a != b); - assert!(b.insert(5, 19)); + assert!(b.insert(5, 19).is_none()); assert!(a == b); } @@ -898,15 +894,15 @@ mod test_map { let mut b = VecMap::new(); assert!(!(a < b) && !(b < a)); - assert!(b.insert(2u, 5i)); + assert!(b.insert(2u, 5i).is_none()); assert!(a < b); - assert!(a.insert(2, 7)); + assert!(a.insert(2, 7).is_none()); assert!(!(a < b) && b < a); - assert!(b.insert(1, 0)); + assert!(b.insert(1, 0).is_none()); assert!(b < a); - assert!(a.insert(0, 6)); + assert!(a.insert(0, 6).is_none()); assert!(a < b); - assert!(a.insert(6, 2)); + assert!(a.insert(6, 2).is_none()); assert!(a < b && !(b < a)); } @@ -916,10 +912,10 @@ mod test_map { let mut b = VecMap::new(); assert!(a <= b && a >= b); - assert!(a.insert(1u, 1i)); + assert!(a.insert(1u, 1i).is_none()); assert!(a > b && a >= b); assert!(b < a && b <= a); - assert!(b.insert(2, 2)); + assert!(b.insert(2, 2).is_none()); assert!(b > a && b >= a); assert!(a < b && a <= b); } @@ -948,7 +944,7 @@ mod test_map { let map: VecMap = xs.iter().map(|&x| x).collect(); for &(k, v) in xs.iter() { - assert_eq!(map.find(&k), Some(&v)); + assert_eq!(map.get(&k), Some(&v)); } } @@ -1022,7 +1018,7 @@ mod bench { let mut m : VecMap = VecMap::new(); find_rand_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } #[bench] @@ -1030,7 +1026,7 @@ mod bench { let mut m : VecMap = VecMap::new(); find_rand_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } // Find seq @@ -1039,7 +1035,7 @@ mod bench { let mut m : VecMap = VecMap::new(); find_seq_n(100, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } #[bench] @@ -1047,6 +1043,6 @@ mod bench { let mut m : VecMap = VecMap::new(); find_seq_n(10_000, &mut m, b, |m, i| { m.insert(i, 1); }, - |m, i| { m.find(&i); }); + |m, i| { m.get(&i); }); } } diff --git a/src/libstd/collections/hash/bench.rs b/src/libstd/collections/hash/bench.rs index 62b93336a34b..87aebb24f987 100644 --- a/src/libstd/collections/hash/bench.rs +++ b/src/libstd/collections/hash/bench.rs @@ -102,14 +102,14 @@ fn hashmap_as_queue(b: &mut Bencher) { let mut k = 1i; b.iter(|| { - m.pop(&k); + m.remove(&k); m.insert(k + 1000, k + 1000); k += 1; }); } #[bench] -fn find_pop_insert(b: &mut Bencher) { +fn get_remove_insert(b: &mut Bencher) { use super::map::HashMap; let mut m = HashMap::new(); @@ -121,9 +121,9 @@ fn find_pop_insert(b: &mut Bencher) { let mut k = 1i; b.iter(|| { - m.find(&(k + 400)); - m.find(&(k + 2000)); - m.pop(&k); + m.get(&(k + 400)); + m.get(&(k + 2000)); + m.remove(&k); m.insert(k + 1000, k + 1000); k += 1; }) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 596e483c2f6d..7ff332c295cf 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -36,6 +36,9 @@ use super::table::{ SafeHash }; +// FIXME(conventions): update capacity management to match other collections (no auto-shrink) +// FIXME(conventions): axe find_copy/get_copy in favour of Option.cloned (also implement that) + const INITIAL_LOG2_CAP: uint = 5; pub const INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5 @@ -233,7 +236,7 @@ impl DefaultResizePolicy { /// // look up the values associated with some keys. /// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; /// for book in to_find.iter() { -/// match book_reviews.find(book) { +/// match book_reviews.get(book) { /// Some(review) => println!("{}: {}", *book, *review), /// None => println!("{} is unreviewed.", *book) /// } @@ -480,6 +483,7 @@ impl HashMap { /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> HashMap { let hasher = RandomSipHasher::new(); HashMap::with_hasher(hasher) @@ -494,6 +498,7 @@ impl HashMap { /// let mut map: HashMap<&str, int> = HashMap::with_capacity(10); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(capacity: uint) -> HashMap { let hasher = RandomSipHasher::new(); HashMap::with_capacity_and_hasher(capacity, hasher) @@ -741,38 +746,6 @@ impl, V, S, H: Hasher> HashMap { } } - /// Retrieves a mutable value for the given key. - /// See [`find_mut`](../trait.MutableMap.html#tymethod.find_mut) for a non-panicking - /// alternative. - /// - /// # Failure - /// - /// Fails if the key is not present. - /// - /// # Example - /// - /// ``` - /// # #![allow(deprecated)] - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1i); - /// { - /// // val will freeze map to prevent usage during its lifetime - /// let val = map.get_mut(&"a"); - /// *val = 40; - /// } - /// assert_eq!(map["a"], 40); - /// - /// // A more direct way could be: - /// *map.get_mut(&"a") = -2; - /// assert_eq!(map["a"], -2); - /// ``` - #[deprecated = "use indexing instead: `&mut map[key]`"] - pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V { - &mut self[*k] - } - /// Return true if the map contains a value for the specified key, /// using equivalence. /// @@ -875,6 +848,7 @@ impl, V, S, H: Hasher> HashMap { /// println!("{}", key); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn keys(&self) -> Keys { self.iter().map(|(k, _v)| k) } @@ -896,6 +870,7 @@ impl, V, S, H: Hasher> HashMap { /// println!("{}", key); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn values(&self) -> Values { self.iter().map(|(_k, v)| v) } @@ -917,6 +892,7 @@ impl, V, S, H: Hasher> HashMap { /// println!("key: {} val: {}", key, val); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter(&self) -> Entries { Entries { inner: self.table.iter() } } @@ -944,6 +920,7 @@ impl, V, S, H: Hasher> HashMap { /// println!("key: {} val: {}", key, val); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter_mut(&mut self) -> MutEntries { MutEntries { inner: self.table.iter_mut() } } @@ -965,6 +942,7 @@ impl, V, S, H: Hasher> HashMap { /// // Not possible with .iter() /// let vec: Vec<(&str, int)> = map.into_iter().collect(); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> MoveEntries { MoveEntries { inner: self.table.into_iter().map(|(_, k, v)| (k, v)) @@ -996,6 +974,7 @@ impl, V, S, H: Hasher> HashMap { /// a.insert(1u, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.table.size() } /// Return true if the map contains no elements. @@ -1011,6 +990,7 @@ impl, V, S, H: Hasher> HashMap { /// assert!(!a.is_empty()); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clears the map, removing all key-value pairs. Keeps the allocated memory @@ -1026,6 +1006,7 @@ impl, V, S, H: Hasher> HashMap { /// a.clear(); /// assert!(a.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { // Prevent reallocations from happening from now on. Makes it possible // for the map to be reused but has a downside: reserves permanently. @@ -1045,6 +1026,12 @@ impl, V, S, H: Hasher> HashMap { } } + /// Deprecated: Renamed to `get`. + #[deprecated = "Renamed to `get`"] + pub fn find(&self, k: &K) -> Option<&V> { + self.get(k) + } + /// Returns a reference to the value corresponding to the key. /// /// # Example @@ -1054,10 +1041,11 @@ impl, V, S, H: Hasher> HashMap { /// /// let mut map = HashMap::new(); /// map.insert(1u, "a"); - /// assert_eq!(map.find(&1), Some(&"a")); - /// assert_eq!(map.find(&2), None); + /// assert_eq!(map.get(&1), Some(&"a")); + /// assert_eq!(map.get(&2), None); /// ``` - pub fn find<'a>(&'a self, k: &K) -> Option<&'a V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&self, k: &K) -> Option<&V> { self.search(k).map(|bucket| { let (_, v) = bucket.into_refs(); v @@ -1076,10 +1064,17 @@ impl, V, S, H: Hasher> HashMap { /// assert_eq!(map.contains_key(&1), true); /// assert_eq!(map.contains_key(&2), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains_key(&self, k: &K) -> bool { self.search(k).is_some() } + /// Deprecated: Renamed to `get_mut`. + #[deprecated = "Renamed to `get_mut`"] + pub fn find_mut(&mut self, k: &K) -> Option<&mut V> { + self.get_mut(k) + } + /// Returns a mutable reference to the value corresponding to the key. /// /// # Example @@ -1089,13 +1084,14 @@ impl, V, S, H: Hasher> HashMap { /// /// let mut map = HashMap::new(); /// map.insert(1u, "a"); - /// match map.find_mut(&1) { + /// match map.get_mut(&1) { /// Some(x) => *x = "b", /// None => (), /// } /// assert_eq!(map[1], "b"); /// ``` - pub fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get_mut(&mut self, k: &K) -> Option<&mut V> { match self.search_mut(k) { Some(bucket) => { let (_, v) = bucket.into_mut_refs(); @@ -1105,41 +1101,10 @@ impl, V, S, H: Hasher> HashMap { } } - /// Inserts a key-value pair into the map. An existing value for a - /// key is replaced by the new value. Returns `true` if the key did - /// not already exist in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// assert_eq!(map.insert(2u, "value"), true); - /// assert_eq!(map.insert(2, "value2"), false); - /// assert_eq!(map[2], "value2"); - /// ``` - #[inline] - pub fn insert(&mut self, key: K, value: V) -> bool { - self.swap(key, value).is_none() - } - - /// Removes a key-value pair from the map. Returns `true` if the key - /// was present in the map. - /// - /// # Example - /// - /// ``` - /// use std::collections::HashMap; - /// - /// let mut map = HashMap::new(); - /// assert_eq!(map.remove(&1u), false); - /// map.insert(1, "a"); - /// assert_eq!(map.remove(&1), true); - /// ``` - #[inline] - pub fn remove(&mut self, key: &K) -> bool { - self.pop(key).is_some() + /// Deprecated: Renamed to `insert`. + #[deprecated = "Renamed to `insert`"] + pub fn swap(&mut self, k: K, v: V) -> Option { + self.insert(k, v) } /// Inserts a key-value pair from the map. If the key already had a value @@ -1151,14 +1116,15 @@ impl, V, S, H: Hasher> HashMap { /// use std::collections::HashMap; /// /// let mut map = HashMap::new(); - /// assert_eq!(map.swap(37u, "a"), None); + /// assert_eq!(map.insert(37u, "a"), None); /// assert_eq!(map.is_empty(), false); /// /// map.insert(37, "b"); - /// assert_eq!(map.swap(37, "c"), Some("b")); + /// assert_eq!(map.insert(37, "c"), Some("b")); /// assert_eq!(map[37], "c"); /// ``` - pub fn swap(&mut self, k: K, v: V) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, k: K, v: V) -> Option { let hash = self.make_hash(&k); let potential_new_size = self.table.size() + 1; self.make_some_room(potential_new_size); @@ -1170,6 +1136,12 @@ impl, V, S, H: Hasher> HashMap { retval } + /// Deprecated: Renamed to `remove`. + #[deprecated = "Renamed to `remove`"] + pub fn pop(&mut self, k: &K) -> Option { + self.remove(k) + } + /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// @@ -1180,10 +1152,11 @@ impl, V, S, H: Hasher> HashMap { /// /// let mut map = HashMap::new(); /// map.insert(1u, "a"); - /// assert_eq!(map.pop(&1), Some("a")); - /// assert_eq!(map.pop(&1), None); + /// assert_eq!(map.remove(&1), Some("a")); + /// assert_eq!(map.remove(&1), None); /// ``` - pub fn pop(&mut self, k: &K) -> Option { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, k: &K) -> Option { if self.table.size() == 0 { return None } @@ -1260,7 +1233,7 @@ impl, V: Clone, S, H: Hasher> HashMap { /// let s: String = map.find_copy(&1).unwrap(); /// ``` pub fn find_copy(&self, k: &K) -> Option { - self.find(k).map(|v| (*v).clone()) + self.get(k).map(|v| (*v).clone()) } /// Return a copy of the value corresponding to the key. @@ -1288,7 +1261,7 @@ impl, V: PartialEq, S, H: Hasher> PartialEq for HashMap, V, S, H: Hasher + Default> Default for HashMap impl, V, S, H: Hasher> Index for HashMap { #[inline] fn index<'a>(&'a self, index: &K) -> &'a V { - self.find(index).expect("no entry found for key") + self.get(index).expect("no entry found for key") } } impl, V, S, H: Hasher> IndexMut for HashMap { #[inline] fn index_mut<'a>(&'a mut self, index: &K) -> &'a mut V { - match self.find_mut(index) { + match self.get_mut(index) { Some(v) => v, None => panic!("no entry found for key") } @@ -1514,7 +1487,7 @@ mod test_map { fn test_create_capacity_zero() { let mut m = HashMap::with_capacity(0); - assert!(m.insert(1i, 1i)); + assert!(m.insert(1i, 1i).is_none()); assert!(m.contains_key(&1)); assert!(!m.contains_key(&0)); @@ -1524,12 +1497,12 @@ mod test_map { fn test_insert() { let mut m = HashMap::new(); assert_eq!(m.len(), 0); - assert!(m.insert(1i, 2i)); + assert!(m.insert(1i, 2i).is_none()); assert_eq!(m.len(), 1); - assert!(m.insert(2i, 4i)); + assert!(m.insert(2i, 4i).is_none()); assert_eq!(m.len(), 2); - assert_eq!(*m.find(&1).unwrap(), 2); - assert_eq!(*m.find(&2).unwrap(), 4); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&2).unwrap(), 4); } local_data_key!(drop_vector: RefCell>) @@ -1588,7 +1561,7 @@ mod test_map { for i in range(0u, 50) { let k = Dropable::new(i); - let v = m.pop(&k); + let v = m.remove(&k); assert!(v.is_some()); @@ -1679,7 +1652,7 @@ mod test_map { #[test] fn test_empty_pop() { let mut m: HashMap = HashMap::new(); - assert_eq!(m.pop(&0), None); + assert_eq!(m.remove(&0), None); } #[test] @@ -1692,15 +1665,15 @@ mod test_map { assert!(m.is_empty()); for i in range_inclusive(1i, 1000) { - assert!(m.insert(i, i)); + assert!(m.insert(i, i).is_none()); for j in range_inclusive(1, i) { - let r = m.find(&j); + let r = m.get(&j); assert_eq!(r, Some(&j)); } for j in range_inclusive(i+1, 1000) { - let r = m.find(&j); + let r = m.get(&j); assert_eq!(r, None); } } @@ -1711,7 +1684,7 @@ mod test_map { // remove forwards for i in range_inclusive(1i, 1000) { - assert!(m.remove(&i)); + assert!(m.remove(&i).is_some()); for j in range_inclusive(1, i) { assert!(!m.contains_key(&j)); @@ -1727,12 +1700,12 @@ mod test_map { } for i in range_inclusive(1i, 1000) { - assert!(m.insert(i, i)); + assert!(m.insert(i, i).is_none()); } // remove backwards for i in range_step_inclusive(1000i, 1, -1) { - assert!(m.remove(&i)); + assert!(m.remove(&i).is_some()); for j in range_inclusive(i, 1000) { assert!(!m.contains_key(&j)); @@ -1748,59 +1721,59 @@ mod test_map { #[test] fn test_find_mut() { let mut m = HashMap::new(); - assert!(m.insert(1i, 12i)); - assert!(m.insert(2i, 8i)); - assert!(m.insert(5i, 14i)); + assert!(m.insert(1i, 12i).is_none()); + assert!(m.insert(2i, 8i).is_none()); + assert!(m.insert(5i, 14i).is_none()); let new = 100; - match m.find_mut(&5) { + match m.get_mut(&5) { None => panic!(), Some(x) => *x = new } - assert_eq!(m.find(&5), Some(&new)); + assert_eq!(m.get(&5), Some(&new)); } #[test] fn test_insert_overwrite() { let mut m = HashMap::new(); - assert!(m.insert(1i, 2i)); - assert_eq!(*m.find(&1).unwrap(), 2); - assert!(!m.insert(1i, 3i)); - assert_eq!(*m.find(&1).unwrap(), 3); + assert!(m.insert(1i, 2i).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(!m.insert(1i, 3i).is_none()); + assert_eq!(*m.get(&1).unwrap(), 3); } #[test] fn test_insert_conflicts() { let mut m = HashMap::with_capacity(4); - assert!(m.insert(1i, 2i)); - assert!(m.insert(5i, 3i)); - assert!(m.insert(9i, 4i)); - assert_eq!(*m.find(&9).unwrap(), 4); - assert_eq!(*m.find(&5).unwrap(), 3); - assert_eq!(*m.find(&1).unwrap(), 2); + assert!(m.insert(1i, 2i).is_none()); + assert!(m.insert(5i, 3i).is_none()); + assert!(m.insert(9i, 4i).is_none()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&1).unwrap(), 2); } #[test] fn test_conflict_remove() { let mut m = HashMap::with_capacity(4); - assert!(m.insert(1i, 2i)); - assert_eq!(*m.find(&1).unwrap(), 2); - assert!(m.insert(5, 3)); - assert_eq!(*m.find(&1).unwrap(), 2); - assert_eq!(*m.find(&5).unwrap(), 3); - assert!(m.insert(9, 4)); - assert_eq!(*m.find(&1).unwrap(), 2); - assert_eq!(*m.find(&5).unwrap(), 3); - assert_eq!(*m.find(&9).unwrap(), 4); - assert!(m.remove(&1)); - assert_eq!(*m.find(&9).unwrap(), 4); - assert_eq!(*m.find(&5).unwrap(), 3); + assert!(m.insert(1i, 2i).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert!(m.insert(5, 3).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert!(m.insert(9, 4).is_none()); + assert_eq!(*m.get(&1).unwrap(), 2); + assert_eq!(*m.get(&5).unwrap(), 3); + assert_eq!(*m.get(&9).unwrap(), 4); + assert!(m.remove(&1).is_some()); + assert_eq!(*m.get(&9).unwrap(), 4); + assert_eq!(*m.get(&5).unwrap(), 3); } #[test] fn test_is_empty() { let mut m = HashMap::with_capacity(4); - assert!(m.insert(1i, 2i)); + assert!(m.insert(1i, 2i).is_none()); assert!(!m.is_empty()); - assert!(m.remove(&1)); + assert!(m.remove(&1).is_some()); assert!(m.is_empty()); } @@ -1808,8 +1781,8 @@ mod test_map { fn test_pop() { let mut m = HashMap::new(); m.insert(1i, 2i); - assert_eq!(m.pop(&1), Some(2)); - assert_eq!(m.pop(&1), None); + assert_eq!(m.remove(&1), Some(2)); + assert_eq!(m.remove(&1), None); } #[test] @@ -1821,19 +1794,11 @@ mod test_map { assert_eq!(m.pop_equiv(&KindaIntLike(1)), None); } - #[test] - fn test_swap() { - let mut m = HashMap::new(); - assert_eq!(m.swap(1i, 2i), None); - assert_eq!(m.swap(1i, 3i), Some(2)); - assert_eq!(m.swap(1i, 4i), Some(3)); - } - #[test] fn test_iterate() { let mut m = HashMap::with_capacity(4); for i in range(0u, 32) { - assert!(m.insert(i, i*2)); + assert!(m.insert(i, i*2).is_none()); } assert_eq!(m.len(), 32); @@ -1871,9 +1836,9 @@ mod test_map { #[test] fn test_find() { let mut m = HashMap::new(); - assert!(m.find(&1i).is_none()); + assert!(m.get(&1i).is_none()); m.insert(1i, 2i); - match m.find(&1) { + match m.get(&1) { None => panic!(), Some(v) => assert_eq!(*v, 2) } @@ -1882,7 +1847,7 @@ mod test_map { #[test] fn test_find_copy() { let mut m = HashMap::new(); - assert!(m.find(&1i).is_none()); + assert!(m.get(&1i).is_none()); for i in range(1i, 10000) { m.insert(i, i + 7); @@ -2026,7 +1991,7 @@ mod test_map { let map: HashMap = xs.iter().map(|&x| x).collect(); for &(k, v) in xs.iter() { - assert_eq!(map.find(&k), Some(&v)); + assert_eq!(map.get(&k), Some(&v)); } } @@ -2093,7 +2058,7 @@ mod test_map { assert_eq!(view.set(100), 10); } } - assert_eq!(map.find(&1).unwrap(), &100); + assert_eq!(map.get(&1).unwrap(), &100); assert_eq!(map.len(), 6); @@ -2106,7 +2071,7 @@ mod test_map { *v = new_v; } } - assert_eq!(map.find(&2).unwrap(), &200); + assert_eq!(map.get(&2).unwrap(), &200); assert_eq!(map.len(), 6); // Existing key (take) @@ -2116,7 +2081,7 @@ mod test_map { assert_eq!(view.take(), 30); } } - assert_eq!(map.find(&3), None); + assert_eq!(map.get(&3), None); assert_eq!(map.len(), 5); @@ -2127,7 +2092,7 @@ mod test_map { assert_eq!(*view.set(1000), 1000); } } - assert_eq!(map.find(&10).unwrap(), &1000); + assert_eq!(map.get(&10).unwrap(), &1000); assert_eq!(map.len(), 6); } } diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 688036d22dd6..45574deec410 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -23,6 +23,9 @@ use result::{Ok, Err}; use super::map::{HashMap, Entries, MoveEntries, INITIAL_CAPACITY}; +// FIXME(conventions): implement BitOr, BitAnd, BitXor, and Sub +// FIXME(conventions): update capacity management to match other collections (no auto-shrink) + // Future Optimization (FIXME!) // ============================= @@ -103,6 +106,7 @@ impl HashSet { /// let mut set: HashSet = HashSet::new(); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new() -> HashSet { HashSet::with_capacity(INITIAL_CAPACITY) } @@ -117,6 +121,7 @@ impl HashSet { /// let mut set: HashSet = HashSet::with_capacity(10); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn with_capacity(capacity: uint) -> HashSet { HashSet { map: HashMap::with_capacity(capacity) } } @@ -240,16 +245,11 @@ impl, S, H: Hasher> HashSet { /// println!("{}", x); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn iter<'a>(&'a self) -> SetItems<'a, T> { self.map.keys() } - /// Deprecated: use `into_iter`. - #[deprecated = "use into_iter"] - pub fn move_iter(self) -> SetMoveItems { - self.into_iter() - } - /// Creates a consuming iterator, that is, one that moves each value out /// of the set in arbitrary order. The set cannot be used after calling /// this. @@ -270,6 +270,7 @@ impl, S, H: Hasher> HashSet { /// println!("{}", x); /// } /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn into_iter(self) -> SetMoveItems { self.map.into_iter().map(|(k, _)| k) } @@ -296,6 +297,7 @@ impl, S, H: Hasher> HashSet { /// let diff: HashSet = b.difference(&a).map(|&x| x).collect(); /// assert_eq!(diff, [4i].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn difference<'a>(&'a self, other: &'a HashSet) -> SetAlgebraItems<'a, T, H> { Repeat::new(other).zip(self.iter()) .filter_map(|(other, elt)| { @@ -323,6 +325,7 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(diff1, diff2); /// assert_eq!(diff1, [1i, 4].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet) -> Chain, SetAlgebraItems<'a, T, H>> { self.difference(other).chain(other.difference(self)) @@ -345,6 +348,7 @@ impl, S, H: Hasher> HashSet { /// let diff: HashSet = a.intersection(&b).map(|&x| x).collect(); /// assert_eq!(diff, [2i, 3].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn intersection<'a>(&'a self, other: &'a HashSet) -> SetAlgebraItems<'a, T, H> { Repeat::new(other).zip(self.iter()) @@ -370,6 +374,7 @@ impl, S, H: Hasher> HashSet { /// let diff: HashSet = a.union(&b).map(|&x| x).collect(); /// assert_eq!(diff, [1i, 2, 3, 4].iter().map(|&x| x).collect()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn union<'a>(&'a self, other: &'a HashSet) -> Chain, SetAlgebraItems<'a, T, H>> { self.iter().chain(other.difference(self)) @@ -387,6 +392,7 @@ impl, S, H: Hasher> HashSet { /// v.insert(1u); /// assert_eq!(v.len(), 1); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.map.len() } /// Returns true if the set contains no elements @@ -401,6 +407,7 @@ impl, S, H: Hasher> HashSet { /// v.insert(1u); /// assert!(!v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.map.len() == 0 } /// Clears the set, removing all values. @@ -415,6 +422,7 @@ impl, S, H: Hasher> HashSet { /// v.clear(); /// assert!(v.is_empty()); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.map.clear() } /// Returns `true` if the set contains a value. @@ -428,6 +436,7 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(set.contains(&1), true); /// assert_eq!(set.contains(&4), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } /// Returns `true` if the set has no elements in common with `other`. @@ -447,6 +456,7 @@ impl, S, H: Hasher> HashSet { /// b.insert(1); /// assert_eq!(a.is_disjoint(&b), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_disjoint(&self, other: &HashSet) -> bool { self.iter().all(|v| !other.contains(v)) } @@ -467,6 +477,7 @@ impl, S, H: Hasher> HashSet { /// set.insert(4); /// assert_eq!(set.is_subset(&sup), false); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &HashSet) -> bool { self.iter().all(|v| other.contains(v)) } @@ -491,6 +502,7 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(set.is_superset(&sub), true); /// ``` #[inline] + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_superset(&self, other: &HashSet) -> bool { other.is_subset(self) } @@ -509,7 +521,8 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(set.insert(2), false); /// assert_eq!(set.len(), 1); /// ``` - pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) } + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } /// Removes a value from the set. Returns `true` if the value was /// present in the set. @@ -525,7 +538,8 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(set.remove(&2), true); /// assert_eq!(set.remove(&2), false); /// ``` - pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) } + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() } } impl, S, H: Hasher> PartialEq for HashSet { diff --git a/src/libstd/collections/lru_cache.rs b/src/libstd/collections/lru_cache.rs index 93e649f9355d..aab0924e7e43 100644 --- a/src/libstd/collections/lru_cache.rs +++ b/src/libstd/collections/lru_cache.rs @@ -20,20 +20,20 @@ //! use std::collections::LruCache; //! //! let mut cache: LruCache = LruCache::new(2); -//! cache.put(1, 10); -//! cache.put(2, 20); -//! cache.put(3, 30); +//! cache.insert(1, 10); +//! cache.insert(2, 20); +//! cache.insert(3, 30); //! assert!(cache.get(&1).is_none()); //! assert_eq!(*cache.get(&2).unwrap(), 20); //! assert_eq!(*cache.get(&3).unwrap(), 30); //! -//! cache.put(2, 22); +//! cache.insert(2, 22); //! assert_eq!(*cache.get(&2).unwrap(), 22); //! -//! cache.put(6, 60); +//! cache.insert(6, 60); //! assert!(cache.get(&3).is_none()); //! -//! cache.change_capacity(1); +//! cache.set_capacity(1); //! assert!(cache.get(&2).is_none()); //! ``` @@ -49,6 +49,9 @@ use boxed::Box; use ptr; use result::{Ok, Err}; +// FIXME(conventions): implement iterators? +// FIXME(conventions): implement indexing? + struct KeyRef { k: *const K } struct LruEntry { @@ -99,6 +102,7 @@ impl LruCache { /// use std::collections::LruCache; /// let mut cache: LruCache = LruCache::new(10); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn new(capacity: uint) -> LruCache { let cache = LruCache { map: HashMap::new(), @@ -112,7 +116,14 @@ impl LruCache { return cache; } - /// Put a key-value pair into cache. + /// Deprecated: Replaced with `insert`. + #[deprecated = "Replaced with `insert`"] + pub fn put(&mut self, k: K, v: V) { + self.insert(k, v); + } + + /// Inserts a key-value pair into the cache. If the key already existed, the old value is + /// returned. /// /// # Example /// @@ -120,22 +131,23 @@ impl LruCache { /// use std::collections::LruCache; /// let mut cache = LruCache::new(2); /// - /// cache.put(1i, "a"); - /// cache.put(2, "b"); + /// cache.insert(1i, "a"); + /// cache.insert(2, "b"); /// assert_eq!(cache.get(&1), Some(&"a")); /// assert_eq!(cache.get(&2), Some(&"b")); /// ``` - pub fn put(&mut self, k: K, v: V) { - let (node_ptr, node_opt) = match self.map.find_mut(&KeyRef{k: &k}) { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn insert(&mut self, k: K, v: V) -> Option { + let (node_ptr, node_opt, old_val) = match self.map.get_mut(&KeyRef{k: &k}) { Some(node) => { - node.value = v; + let old_val = mem::replace(&mut node.value, v); let node_ptr: *mut LruEntry = &mut **node; - (node_ptr, None) + (node_ptr, None, Some(old_val)) } None => { let mut node = box LruEntry::new(k, v); let node_ptr: *mut LruEntry = &mut *node; - (node_ptr, Some(node)) + (node_ptr, Some(node), None) } }; match node_opt { @@ -146,13 +158,14 @@ impl LruCache { } Some(node) => { let keyref = unsafe { &(*node_ptr).key }; - self.map.swap(KeyRef{k: keyref}, node); + self.map.insert(KeyRef{k: keyref}, node); self.attach(node_ptr); if self.len() > self.capacity() { self.remove_lru(); } } } + old_val } /// Return a value corresponding to the key in the cache. @@ -163,16 +176,17 @@ impl LruCache { /// use std::collections::LruCache; /// let mut cache = LruCache::new(2); /// - /// cache.put(1i, "a"); - /// cache.put(2, "b"); - /// cache.put(2, "c"); - /// cache.put(3, "d"); + /// cache.insert(1i, "a"); + /// cache.insert(2, "b"); + /// cache.insert(2, "c"); + /// cache.insert(3, "d"); /// /// assert_eq!(cache.get(&1), None); /// assert_eq!(cache.get(&2), Some(&"c")); /// ``` - pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> { - let (value, node_ptr_opt) = match self.map.find_mut(&KeyRef{k: k}) { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn get(&mut self, k: &K) -> Option<&V> { + let (value, node_ptr_opt) = match self.map.get_mut(&KeyRef{k: k}) { None => (None, None), Some(node) => { let node_ptr: *mut LruEntry = &mut **node; @@ -189,6 +203,12 @@ impl LruCache { return value; } + /// Deprecated: Renamed to `remove`. + #[deprecated = "Renamed to `remove`"] + pub fn pop(&mut self, k: &K) -> Option { + self.remove(k) + } + /// Remove and return a value corresponding to the key from the cache. /// /// # Example @@ -197,15 +217,16 @@ impl LruCache { /// use std::collections::LruCache; /// let mut cache = LruCache::new(2); /// - /// cache.put(2i, "a"); + /// cache.insert(2i, "a"); /// - /// assert_eq!(cache.pop(&1), None); - /// assert_eq!(cache.pop(&2), Some("a")); - /// assert_eq!(cache.pop(&2), None); + /// assert_eq!(cache.remove(&1), None); + /// assert_eq!(cache.remove(&2), Some("a")); + /// assert_eq!(cache.remove(&2), None); /// assert_eq!(cache.len(), 0); /// ``` - pub fn pop(&mut self, k: &K) -> Option { - match self.map.pop(&KeyRef{k: k}) { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn remove(&mut self, k: &K) -> Option { + match self.map.remove(&KeyRef{k: k}) { None => None, Some(lru_entry) => Some(lru_entry.value) } @@ -220,10 +241,17 @@ impl LruCache { /// let mut cache: LruCache = LruCache::new(2); /// assert_eq!(cache.capacity(), 2); /// ``` + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn capacity(&self) -> uint { self.max_size } + /// Deprecated: Renamed to `set_capacity`. + #[deprecated = "Renamed to `set_capacity`"] + pub fn change_capacity(&mut self, capacity: uint) { + self.set_capacity(capacity) + } + /// Change the number of key-value pairs the cache can hold. Remove /// least-recently-used key-value pairs if necessary. /// @@ -233,29 +261,30 @@ impl LruCache { /// use std::collections::LruCache; /// let mut cache = LruCache::new(2); /// - /// cache.put(1i, "a"); - /// cache.put(2, "b"); - /// cache.put(3, "c"); + /// cache.insert(1i, "a"); + /// cache.insert(2, "b"); + /// cache.insert(3, "c"); /// /// assert_eq!(cache.get(&1), None); /// assert_eq!(cache.get(&2), Some(&"b")); /// assert_eq!(cache.get(&3), Some(&"c")); /// - /// cache.change_capacity(3); - /// cache.put(1i, "a"); - /// cache.put(2, "b"); + /// cache.set_capacity(3); + /// cache.insert(1i, "a"); + /// cache.insert(2, "b"); /// /// assert_eq!(cache.get(&1), Some(&"a")); /// assert_eq!(cache.get(&2), Some(&"b")); /// assert_eq!(cache.get(&3), Some(&"c")); /// - /// cache.change_capacity(1); + /// cache.set_capacity(1); /// /// assert_eq!(cache.get(&1), None); /// assert_eq!(cache.get(&2), None); /// assert_eq!(cache.get(&3), Some(&"c")); /// ``` - pub fn change_capacity(&mut self, capacity: uint) { + #[unstable = "matches collection reform specification, waiting for dust to settle"] + pub fn set_capacity(&mut self, capacity: uint) { for _ in range(capacity, self.len()) { self.remove_lru(); } @@ -267,7 +296,7 @@ impl LruCache { if self.len() > 0 { let lru = unsafe { (*self.head).prev }; self.detach(lru); - self.map.pop(&KeyRef{k: unsafe { &(*lru).key }}); + self.map.remove(&KeyRef{k: unsafe { &(*lru).key }}); } } @@ -290,12 +319,15 @@ impl LruCache { } /// Return the number of key-value pairs in the cache. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn len(&self) -> uint { self.map.len() } /// Returns whether the cache is currently empty. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_empty(&self) -> bool { self.len() == 0 } /// Clear the cache of all key-value pairs. + #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn clear(&mut self) { self.map.clear(); } } @@ -347,8 +379,8 @@ mod tests { #[test] fn test_put_and_get() { let mut cache: LruCache = LruCache::new(2); - cache.put(1, 10); - cache.put(2, 20); + cache.insert(1, 10); + cache.insert(2, 20); assert_opt_eq(cache.get(&1), 10); assert_opt_eq(cache.get(&2), 20); assert_eq!(cache.len(), 2); @@ -357,8 +389,8 @@ mod tests { #[test] fn test_put_update() { let mut cache: LruCache> = LruCache::new(1); - cache.put("1".to_string(), vec![10, 10]); - cache.put("1".to_string(), vec![10, 19]); + cache.insert("1".to_string(), vec![10, 10]); + cache.insert("1".to_string(), vec![10, 19]); assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]); assert_eq!(cache.len(), 1); } @@ -366,22 +398,22 @@ mod tests { #[test] fn test_expire_lru() { let mut cache: LruCache = LruCache::new(2); - cache.put("foo1".to_string(), "bar1".to_string()); - cache.put("foo2".to_string(), "bar2".to_string()); - cache.put("foo3".to_string(), "bar3".to_string()); + cache.insert("foo1".to_string(), "bar1".to_string()); + cache.insert("foo2".to_string(), "bar2".to_string()); + cache.insert("foo3".to_string(), "bar3".to_string()); assert!(cache.get(&"foo1".to_string()).is_none()); - cache.put("foo2".to_string(), "bar2update".to_string()); - cache.put("foo4".to_string(), "bar4".to_string()); + cache.insert("foo2".to_string(), "bar2update".to_string()); + cache.insert("foo4".to_string(), "bar4".to_string()); assert!(cache.get(&"foo3".to_string()).is_none()); } #[test] fn test_pop() { let mut cache: LruCache = LruCache::new(2); - cache.put(1, 10); - cache.put(2, 20); + cache.insert(1, 10); + cache.insert(2, 20); assert_eq!(cache.len(), 2); - let opt1 = cache.pop(&1); + let opt1 = cache.remove(&1); assert!(opt1.is_some()); assert_eq!(opt1.unwrap(), 10); assert!(cache.get(&1).is_none()); @@ -392,9 +424,9 @@ mod tests { fn test_change_capacity() { let mut cache: LruCache = LruCache::new(2); assert_eq!(cache.capacity(), 2); - cache.put(1, 10); - cache.put(2, 20); - cache.change_capacity(1); + cache.insert(1, 10); + cache.insert(2, 20); + cache.set_capacity(1); assert!(cache.get(&1).is_none()); assert_eq!(cache.capacity(), 1); } @@ -402,25 +434,25 @@ mod tests { #[test] fn test_to_string() { let mut cache: LruCache = LruCache::new(3); - cache.put(1, 10); - cache.put(2, 20); - cache.put(3, 30); + cache.insert(1, 10); + cache.insert(2, 20); + cache.insert(3, 30); assert_eq!(cache.to_string(), "{3: 30, 2: 20, 1: 10}".to_string()); - cache.put(2, 22); + cache.insert(2, 22); assert_eq!(cache.to_string(), "{2: 22, 3: 30, 1: 10}".to_string()); - cache.put(6, 60); + cache.insert(6, 60); assert_eq!(cache.to_string(), "{6: 60, 2: 22, 3: 30}".to_string()); cache.get(&3); assert_eq!(cache.to_string(), "{3: 30, 6: 60, 2: 22}".to_string()); - cache.change_capacity(2); + cache.set_capacity(2); assert_eq!(cache.to_string(), "{3: 30, 6: 60}".to_string()); } #[test] fn test_clear() { let mut cache: LruCache = LruCache::new(2); - cache.put(1, 10); - cache.put(2, 20); + cache.insert(1, 10); + cache.insert(2, 20); cache.clear(); assert!(cache.get(&1).is_none()); assert!(cache.get(&2).is_none()); diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index 13486d4b8f84..3419a3d98a15 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -278,7 +278,7 @@ //! } //! } //! -//! assert_eq!(count.find(&'s'), Some(&8)); +//! assert_eq!(count.get(&'s'), Some(&8)); //! //! println!("Number of occurences of each character"); //! for (char, count) in count.iter() { From eec145be3f5e5f763e61749a6737f90df8504e05 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Thu, 6 Nov 2014 12:25:16 -0500 Subject: [PATCH 27/37] Fallout from collection conventions --- src/libgreen/lib.rs | 2 +- src/libgreen/sched.rs | 2 +- src/librustc/back/link.rs | 2 +- src/librustc/driver/session.rs | 2 +- src/librustc/lint/builtin.rs | 14 ++--- src/librustc/lint/context.rs | 12 ++-- src/librustc/metadata/cstore.rs | 2 +- src/librustc/metadata/decoder.rs | 4 +- src/librustc/metadata/encoder.rs | 14 ++--- src/librustc/metadata/tydecode.rs | 8 +-- src/librustc/metadata/tyencode.rs | 2 +- src/librustc/middle/astencode.rs | 26 ++++---- src/librustc/middle/borrowck/move_data.rs | 4 +- src/librustc/middle/cfg/construct.rs | 4 +- src/librustc/middle/check_const.rs | 4 +- src/librustc/middle/check_match.rs | 6 +- src/librustc/middle/check_static_recursion.rs | 2 +- src/librustc/middle/const_eval.rs | 6 +- src/librustc/middle/dataflow.rs | 4 +- src/librustc/middle/dead.rs | 6 +- src/librustc/middle/dependency_format.rs | 4 +- src/librustc/middle/expr_use_visitor.rs | 6 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/liveness.rs | 16 ++--- src/librustc/middle/mem_categorization.rs | 8 +-- src/librustc/middle/pat_util.rs | 6 +- src/librustc/middle/privacy.rs | 10 +-- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/region.rs | 14 ++--- src/librustc/middle/resolve.rs | 52 ++++++++-------- src/librustc/middle/traits/select.rs | 16 ++--- src/librustc/middle/trans/_match.rs | 4 +- src/librustc/middle/trans/adt.rs | 2 +- src/librustc/middle/trans/base.rs | 10 +-- src/librustc/middle/trans/builder.rs | 2 +- src/librustc/middle/trans/closure.rs | 4 +- src/librustc/middle/trans/common.rs | 8 +-- src/librustc/middle/trans/consts.rs | 4 +- src/librustc/middle/trans/controlflow.rs | 2 +- src/librustc/middle/trans/debuginfo.rs | 8 +-- src/librustc/middle/trans/expr.rs | 14 ++--- src/librustc/middle/trans/glue.rs | 4 +- src/librustc/middle/trans/inline.rs | 2 +- src/librustc/middle/trans/meth.rs | 8 +-- src/librustc/middle/trans/monomorphize.rs | 4 +- src/librustc/middle/trans/type_.rs | 2 +- src/librustc/middle/trans/type_of.rs | 2 +- src/librustc/middle/ty.rs | 56 ++++++++--------- src/librustc/middle/typeck/astconv.rs | 16 ++--- src/librustc/middle/typeck/check/_match.rs | 2 +- src/librustc/middle/typeck/check/method.rs | 10 +-- src/librustc/middle/typeck/check/mod.rs | 22 +++---- src/librustc/middle/typeck/check/regionck.rs | 22 +++---- src/librustc/middle/typeck/check/writeback.rs | 6 +- src/librustc/middle/typeck/coherence/mod.rs | 2 +- .../middle/typeck/coherence/overlap.rs | 2 +- src/librustc/middle/typeck/collect.rs | 16 ++--- .../middle/typeck/infer/error_reporting.rs | 2 +- .../typeck/infer/region_inference/mod.rs | 8 +-- src/librustc/middle/typeck/infer/sub.rs | 2 +- src/librustc/middle/typeck/mod.rs | 2 +- src/librustc/middle/typeck/variance.rs | 12 ++-- src/librustc/util/common.rs | 4 +- src/librustc/util/ppaux.rs | 6 +- src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/clean/mod.rs | 6 +- src/librustdoc/html/format.rs | 4 +- src/librustdoc/html/markdown.rs | 2 +- src/librustdoc/html/render.rs | 18 +++--- src/librustdoc/lib.rs | 4 +- src/librustrt/local_data.rs | 4 +- src/libserialize/collection_impls.rs | 8 +-- src/libserialize/json.rs | 10 +-- src/libstd/io/mod.rs | 4 +- src/libstd/io/process.rs | 2 +- src/libsyntax/diagnostics/plugin.rs | 4 +- src/libsyntax/ext/base.rs | 2 +- src/libsyntax/ext/format.rs | 8 +-- src/libsyntax/ext/mtwt.rs | 2 +- src/libsyntax/util/interner.rs | 2 +- src/libtest/lib.rs | 46 +++++++------- src/test/bench/core-map.rs | 12 ++-- src/test/bench/shootout-chameneos-redux.rs | 4 +- src/test/bench/shootout-fasta-redux.rs | 2 +- src/test/bench/shootout-k-nucleotide.rs | 4 +- src/test/bench/shootout-meteor.rs | 4 +- src/test/bench/shootout-regex-dna.rs | 2 +- src/test/bench/shootout-reverse-complement.rs | 5 +- src/test/bench/sudoku.rs | 6 +- .../compile-fail/borrowck-assign-comp-idx.rs | 6 +- .../borrowck-for-loop-head-linkage.rs | 2 +- .../compile-fail/borrowck-loan-vec-content.rs | 2 +- src/test/run-pass/foreach-nested.rs | 2 +- src/test/run-pass/hashmap-memory.rs | 2 +- src/test/run-pass/issue-3563-3.rs | 4 +- src/test/run-pass/issue-3991.rs | 2 +- src/test/run-pass/overloaded-deref.rs | 4 +- src/test/run-pass/send_str_hashmap.rs | 44 ++++++------- src/test/run-pass/send_str_treemap.rs | 62 +++++++++---------- src/test/run-pass/swap-2.rs | 2 +- src/test/run-pass/unique-in-vec-copy.rs | 2 +- 101 files changed, 418 insertions(+), 417 deletions(-) diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index fcebfeac2929..ed394fc0de5f 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -417,7 +417,7 @@ impl SchedPool { } // Jettison the task away! - self.handles.get_mut(idx).send(TaskFromFriend(task)); + self.handles[idx].send(TaskFromFriend(task)); } /// Spawns a new scheduler into this M:N pool. A handle is returned to the diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index b1c2695ac7d2..50b10873faf4 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -502,7 +502,7 @@ impl Scheduler { let len = work_queues.len(); let start_index = self.rng.gen_range(0, len); for index in range(0, len).map(|i| (i + start_index) % len) { - match work_queues.get_mut(index).steal() { + match work_queues[index].steal() { deque::Data(task) => { rtdebug!("found task by stealing"); return Some(task) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 81f856c29d5d..7488cb59830a 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -220,7 +220,7 @@ fn symbol_hash(tcx: &ty::ctxt, } fn get_symbol_hash(ccx: &CrateContext, t: ty::t) -> String { - match ccx.type_hashcodes().borrow().find(&t) { + match ccx.type_hashcodes().borrow().get(&t) { Some(h) => return h.to_string(), None => {} } diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 57c65ccebc5b..35ccbb4c7b41 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -127,7 +127,7 @@ impl Session { msg: String) { let lint_id = lint::LintId::of(lint); let mut lints = self.lints.borrow_mut(); - match lints.find_mut(&id) { + match lints.get_mut(&id) { Some(arr) => { arr.push((lint_id, sp, msg)); return; } None => {} } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index b60b2ba984e1..d42a9c69dc12 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -403,7 +403,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { libc::c_uint or libc::c_ulong should be used"); } def::DefTy(..) => { - let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().find(&ty_id) { + let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&ty_id) { Some(&ty::atttce_resolved(t)) => t, _ => panic!("ast_ty_to_ty_cache was incomplete after typeck!") }; @@ -994,7 +994,7 @@ impl LintPass for NonSnakeCase { fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { match &p.node { &ast::PatIdent(_, ref path1, _) => { - match cx.tcx.def_map.borrow().find(&p.id) { + match cx.tcx.def_map.borrow().get(&p.id) { Some(&def::DefLocal(_)) => { self.check_snake_case(cx, "variable", path1.node, p.span); } @@ -1051,7 +1051,7 @@ impl LintPass for NonUpperCaseGlobals { fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { // Lint for constants that look like binding identifiers (#7526) - match (&p.node, cx.tcx.def_map.borrow().find(&p.id)) { + match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) { (&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => { let s = token::get_ident(path1.node); if s.get().chars().any(|c| c.is_lowercase()) { @@ -1211,7 +1211,7 @@ impl LintPass for NonShorthandFieldPatterns { ast::PatStruct(_, ref v, _) => { for fieldpat in v.iter() .filter(|fieldpat| !fieldpat.node.is_shorthand) - .filter(|fieldpat| def_map.find(&fieldpat.node.pat.id) + .filter(|fieldpat| def_map.get(&fieldpat.node.pat.id) == Some(&def::DefLocal(fieldpat.node.pat.id))) { match fieldpat.node.pat.node { ast::PatIdent(_, ident, None) if ident.node.as_str() @@ -1368,7 +1368,7 @@ impl LintPass for UnusedAllocation { _ => return } - match cx.tcx.adjustments.borrow().find(&e.id) { + match cx.tcx.adjustments.borrow().get(&e.id) { Some(adjustment) => { match *adjustment { ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) => { @@ -1637,7 +1637,7 @@ impl LintPass for Stability { let id = match e.node { ast::ExprPath(..) | ast::ExprStruct(..) => { - match cx.tcx.def_map.borrow().find(&e.id) { + match cx.tcx.def_map.borrow().get(&e.id) { Some(&def) => def.def_id(), None => return } @@ -1645,7 +1645,7 @@ impl LintPass for Stability { ast::ExprMethodCall(i, _, _) => { span = i.span; let method_call = typeck::MethodCall::expr(e.id); - match cx.tcx.method_map.borrow().find(&method_call) { + match cx.tcx.method_map.borrow().get(&method_call) { Some(method) => { match method.origin { typeck::MethodStatic(def_id) => { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6da74eee8a31..76187f192c2b 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -84,7 +84,7 @@ enum TargetLint { impl LintStore { fn get_level_source(&self, lint: LintId) -> LevelSource { - match self.levels.find(&lint) { + match self.levels.get(&lint) { Some(&s) => s, None => (Allow, Default), } @@ -124,7 +124,7 @@ impl LintStore { self.lints.push((*lint, from_plugin)); let id = LintId::of(*lint); - if !self.by_name.insert(lint.name_lower(), Id(id)) { + if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { let msg = format!("duplicate specification of lint {}", lint.name_lower()); match (sess, from_plugin) { // We load builtin lints first, so a duplicate is a compiler bug. @@ -147,7 +147,7 @@ impl LintStore { pub fn register_group(&mut self, sess: Option<&Session>, from_plugin: bool, name: &'static str, to: Vec) { - let new = self.lint_groups.insert(name, (to, from_plugin)); + let new = self.lint_groups.insert(name, (to, from_plugin)).is_none(); if !new { let msg = format!("duplicate specification of lint group {}", name); @@ -437,11 +437,11 @@ impl<'a, 'tcx> Context<'a, 'tcx> { /// Get the level of `lint` at the current position of the lint /// traversal. pub fn current_level(&self, lint: &'static Lint) -> Level { - self.lints.levels.find(&LintId::of(lint)).map_or(Allow, |&(lvl, _)| lvl) + self.lints.levels.get(&LintId::of(lint)).map_or(Allow, |&(lvl, _)| lvl) } fn lookup_and_emit(&self, lint: &'static Lint, span: Option, msg: &str) { - let (level, src) = match self.lints.levels.find(&LintId::of(lint)) { + let (level, src) = match self.lints.levels.get(&LintId::of(lint)) { None => return, Some(&(Warn, src)) => { let lint_id = LintId::of(builtin::WARNINGS); @@ -750,7 +750,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { // Output any lints that were previously added to the session. impl<'a, 'tcx> IdVisitingOperation for Context<'a, 'tcx> { fn visit_id(&mut self, id: ast::NodeId) { - match self.tcx.sess.lints.borrow_mut().pop(&id) { + match self.tcx.sess.lints.borrow_mut().remove(&id) { None => {} Some(lints) => { for (lint_id, span, msg) in lints.into_iter() { diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index e8c5f6f4910e..36456b3c4a9a 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -213,7 +213,7 @@ impl CStore { pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { - self.extern_mod_crate_map.borrow().find(&emod_id).map(|x| *x) + self.extern_mod_crate_map.borrow().get(&emod_id).map(|x| *x) } } diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 92f3b888dcd5..2fd6e2b47870 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1209,7 +1209,7 @@ pub fn translate_def_id(cdata: Cmd, did: ast::DefId) -> ast::DefId { return ast::DefId { krate: cdata.cnum, node: did.node }; } - match cdata.cnum_map.find(&did.krate) { + match cdata.cnum_map.get(&did.krate) { Some(&n) => { ast::DefId { krate: n, @@ -1321,7 +1321,7 @@ pub fn get_dylib_dependency_formats(cdata: Cmd) let cnum = spec.split(':').nth(0).unwrap(); let link = spec.split(':').nth(1).unwrap(); let cnum = from_str(cnum).unwrap(); - let cnum = match cdata.cnum_map.find(&cnum) { + let cnum = match cdata.cnum_map.get(&cnum) { Some(&n) => n, None => panic!("didn't find a crate in the cnum_map") }; diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index da7e78d272fd..66b647fabdc8 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -253,7 +253,7 @@ fn encode_symbol(ecx: &EncodeContext, rbml_w: &mut Encoder, id: NodeId) { rbml_w.start_tag(tag_items_data_item_symbol); - match ecx.item_symbols.borrow().find(&id) { + match ecx.item_symbols.borrow().get(&id) { Some(x) => { debug!("encode_symbol(id={}, str={})", id, *x); rbml_w.writer.write(x.as_bytes()); @@ -397,7 +397,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext, exp: &middle::resolve::Export2) -> bool { let impl_items = ecx.tcx.impl_items.borrow(); - match ecx.tcx.inherent_impls.borrow().find(&exp.def_id) { + match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) { Some(implementations) => { for base_impl_did in implementations.iter() { for &method_did in (*impl_items)[*base_impl_did].iter() { @@ -426,7 +426,7 @@ fn encode_reexported_static_trait_methods(ecx: &EncodeContext, rbml_w: &mut Encoder, exp: &middle::resolve::Export2) -> bool { - match ecx.tcx.trait_items_cache.borrow().find(&exp.def_id) { + match ecx.tcx.trait_items_cache.borrow().get(&exp.def_id) { Some(trait_items) => { for trait_item in trait_items.iter() { match *trait_item { @@ -531,7 +531,7 @@ fn encode_reexports(ecx: &EncodeContext, id: NodeId, path: PathElems) { debug!("(encoding info for module) encoding reexports for {}", id); - match ecx.reexports2.find(&id) { + match ecx.reexports2.get(&id) { Some(ref exports) => { debug!("(encoding info for module) found reexports for {}", id); for exp in exports.iter() { @@ -978,7 +978,7 @@ fn should_inline(attrs: &[Attribute]) -> bool { fn encode_inherent_implementations(ecx: &EncodeContext, rbml_w: &mut Encoder, def_id: DefId) { - match ecx.tcx.inherent_impls.borrow().find(&def_id) { + match ecx.tcx.inherent_impls.borrow().get(&def_id) { None => {} Some(implementations) => { for &impl_def_id in implementations.iter() { @@ -994,7 +994,7 @@ fn encode_inherent_implementations(ecx: &EncodeContext, fn encode_extension_implementations(ecx: &EncodeContext, rbml_w: &mut Encoder, trait_def_id: DefId) { - match ecx.tcx.trait_impls.borrow().find(&trait_def_id) { + match ecx.tcx.trait_impls.borrow().get(&trait_def_id) { None => {} Some(implementations) => { for &impl_def_id in implementations.borrow().iter() { @@ -1987,7 +1987,7 @@ fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) { fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) { rbml_w.start_tag(tag_dylib_dependency_formats); - match ecx.tcx.dependency_formats.borrow().find(&config::CrateTypeDylib) { + match ecx.tcx.dependency_formats.borrow().get(&config::CrateTypeDylib) { Some(arr) => { let s = arr.iter().enumerate().filter_map(|(i, slot)| { slot.map(|kind| (format!("{}:{}", i + 1, match kind { diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index b9660dbd4662..227a6f71bfda 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -675,16 +675,16 @@ fn parse_builtin_bounds(st: &mut PState, _conv: conv_did) -> ty::BuiltinBounds { loop { match next(st) { 'S' => { - builtin_bounds.add(ty::BoundSend); + builtin_bounds.insert(ty::BoundSend); } 'Z' => { - builtin_bounds.add(ty::BoundSized); + builtin_bounds.insert(ty::BoundSized); } 'P' => { - builtin_bounds.add(ty::BoundCopy); + builtin_bounds.insert(ty::BoundCopy); } 'T' => { - builtin_bounds.add(ty::BoundSync); + builtin_bounds.insert(ty::BoundSync); } '.' => { return builtin_bounds; diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs index 5fb1fec53400..027b9980a32b 100644 --- a/src/librustc/metadata/tyencode.rs +++ b/src/librustc/metadata/tyencode.rs @@ -50,7 +50,7 @@ pub struct ty_abbrev { pub type abbrev_map = RefCell>; pub fn enc_ty(w: &mut SeekableMemWriter, cx: &ctxt, t: ty::t) { - match cx.abbrevs.borrow_mut().find(&t) { + match cx.abbrevs.borrow_mut().get(&t) { Some(a) => { w.write(a.s.as_bytes()); return; } None => {} } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 5410417ec3f5..9268418ef94e 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1151,14 +1151,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, debug!("Encoding side tables for id {}", id); - for def in tcx.def_map.borrow().find(&id).iter() { + for def in tcx.def_map.borrow().get(&id).iter() { rbml_w.tag(c::tag_table_def, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| (*def).encode(rbml_w).unwrap()); }) } - for &ty in tcx.node_types.borrow().find(&(id as uint)).iter() { + for &ty in tcx.node_types.borrow().get(&(id as uint)).iter() { rbml_w.tag(c::tag_table_node_type, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1167,7 +1167,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &item_substs in tcx.item_substs.borrow().find(&id).iter() { + for &item_substs in tcx.item_substs.borrow().get(&id).iter() { rbml_w.tag(c::tag_table_item_subst, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1176,7 +1176,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &fv in tcx.freevars.borrow().find(&id).iter() { + for &fv in tcx.freevars.borrow().get(&id).iter() { rbml_w.tag(c::tag_table_freevars, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1209,7 +1209,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } } - for &cm in tcx.capture_modes.borrow().find(&id).iter() { + for &cm in tcx.capture_modes.borrow().get(&id).iter() { rbml_w.tag(c::tag_table_capture_modes, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1219,7 +1219,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id }; - for &pty in tcx.tcache.borrow().find(&lid).iter() { + for &pty in tcx.tcache.borrow().get(&lid).iter() { rbml_w.tag(c::tag_table_tcache, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1228,7 +1228,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &type_param_def in tcx.ty_param_defs.borrow().find(&id).iter() { + for &type_param_def in tcx.ty_param_defs.borrow().get(&id).iter() { rbml_w.tag(c::tag_table_param_defs, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1238,7 +1238,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, } let method_call = MethodCall::expr(id); - for &method in tcx.method_map.borrow().find(&method_call).iter() { + for &method in tcx.method_map.borrow().get(&method_call).iter() { rbml_w.tag(c::tag_table_method_map, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1247,7 +1247,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &trait_ref in tcx.object_cast_map.borrow().find(&id).iter() { + for &trait_ref in tcx.object_cast_map.borrow().get(&id).iter() { rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1256,11 +1256,11 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, }) } - for &adjustment in tcx.adjustments.borrow().find(&id).iter() { + for &adjustment in tcx.adjustments.borrow().get(&id).iter() { match *adjustment { _ if ty::adjust_is_object(adjustment) => { let method_call = MethodCall::autoobject(id); - for &method in tcx.method_map.borrow().find(&method_call).iter() { + for &method in tcx.method_map.borrow().get(&method_call).iter() { rbml_w.tag(c::tag_table_method_map, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1273,7 +1273,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, assert!(!ty::adjust_is_object(adjustment)); for autoderef in range(0, adj.autoderefs) { let method_call = MethodCall::autoderef(id, autoderef); - for &method in tcx.method_map.borrow().find(&method_call).iter() { + for &method in tcx.method_map.borrow().get(&method_call).iter() { rbml_w.tag(c::tag_table_method_map, |rbml_w| { rbml_w.id(id); rbml_w.tag(c::tag_table_val, |rbml_w| { @@ -1299,7 +1299,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext, for unboxed_closure in tcx.unboxed_closures .borrow() - .find(&ast_util::local_def(id)) + .get(&ast_util::local_def(id)) .iter() { rbml_w.tag(c::tag_table_unboxed_closures, |rbml_w| { rbml_w.id(id); diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 98376726913c..2a92db3e7d4e 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -242,7 +242,7 @@ impl MoveData { * base paths that do not yet have an index. */ - match self.path_map.borrow().find(&lp) { + match self.path_map.borrow().get(&lp) { Some(&index) => { return index; } @@ -577,7 +577,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { //! Returns the kind of a move of `loan_path` by `id`, if one exists. let mut ret = None; - for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() { + for loan_path_index in self.move_data.path_map.borrow().get(&*loan_path).iter() { self.dfcx_moves.each_gen_bit(id, |move_index| { let the_move = self.move_data.moves.borrow(); let the_move = (*the_move)[move_index]; diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 146891825d68..1e38250ceb38 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -512,7 +512,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { func_or_rcvr: &ast::Expr, args: I) -> CFGIndex { let method_call = typeck::MethodCall::expr(call_expr.id); - let return_ty = ty::ty_fn_ret(match self.tcx.method_map.borrow().find(&method_call) { + let return_ty = ty::ty_fn_ret(match self.tcx.method_map.borrow().get(&method_call) { Some(method) => method.ty, None => ty::expr_ty(self.tcx, func_or_rcvr) }); @@ -610,7 +610,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { } Some(_) => { - match self.tcx.def_map.borrow().find(&expr.id) { + match self.tcx.def_map.borrow().get(&expr.id) { Some(&def::DefLabel(loop_id)) => { for l in self.loop_scopes.iter() { if l.loop_id == loop_id { diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 6cf1a93b40b7..b03fe0f3f6fb 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -143,7 +143,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool { "paths in constants may only refer to items without \ type parameters"); } - match v.tcx.def_map.borrow().find(&e.id) { + match v.tcx.def_map.borrow().get(&e.id) { Some(&DefStatic(..)) | Some(&DefConst(..)) | Some(&DefFn(..)) | @@ -162,7 +162,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) -> bool { } } ExprCall(ref callee, _) => { - match v.tcx.def_map.borrow().find(&callee.id) { + match v.tcx.def_map.borrow().get(&callee.id) { Some(&DefStruct(..)) | Some(&DefVariant(..)) => {} // OK. diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index fe38669ea6c2..4dcd5d8873ea 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -639,7 +639,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, let pat = raw_pat(p); match pat.node { PatIdent(..) => - match cx.tcx.def_map.borrow().find(&pat.id) { + match cx.tcx.def_map.borrow().get(&pat.id) { Some(&DefConst(..)) => cx.tcx.sess.span_bug(pat.span, "const pattern should've \ been rewritten"), @@ -648,7 +648,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, _ => vec!() }, PatEnum(..) => - match cx.tcx.def_map.borrow().find(&pat.id) { + match cx.tcx.def_map.borrow().get(&pat.id) { Some(&DefConst(..)) => cx.tcx.sess.span_bug(pat.span, "const pattern should've \ been rewritten"), @@ -656,7 +656,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, _ => vec!(Single) }, PatStruct(..) => - match cx.tcx.def_map.borrow().find(&pat.id) { + match cx.tcx.def_map.borrow().get(&pat.id) { Some(&DefConst(..)) => cx.tcx.sess.span_bug(pat.span, "const pattern should've \ been rewritten"), diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index 1c83bf199192..a3738f031a96 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -95,7 +95,7 @@ impl<'a, 'ast, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a, 'ast> { fn visit_expr(&mut self, e: &ast::Expr) { match e.node { ast::ExprPath(..) => { - match self.def_map.borrow().find(&e.id) { + match self.def_map.borrow().get(&e.id) { Some(&DefStatic(def_id, _)) | Some(&DefConst(def_id)) if ast_util::is_local(def_id) => { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index ce91bd1b1538..fdda5f1a860e 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -123,7 +123,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt, Some(_) => None } } else { - match tcx.extern_const_variants.borrow().find(&variant_def) { + match tcx.extern_const_variants.borrow().get(&variant_def) { Some(&ast::DUMMY_NODE_ID) => return None, Some(&expr_id) => { return Some(tcx.map.expect_expr(expr_id)); @@ -163,7 +163,7 @@ pub fn lookup_const_by_id<'a>(tcx: &'a ty::ctxt, def_id: ast::DefId) Some(_) => None } } else { - match tcx.extern_const_statics.borrow().find(&def_id) { + match tcx.extern_const_statics.borrow().get(&def_id) { Some(&ast::DUMMY_NODE_ID) => return None, Some(&expr_id) => { return Some(tcx.map.expect_expr(expr_id)); @@ -192,7 +192,7 @@ struct ConstEvalVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> { fn classify(&mut self, e: &Expr) -> constness { let did = ast_util::local_def(e.id); - match self.ccache.find(&did) { + match self.ccache.get(&did) { Some(&x) => return x, None => {} } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 612c9a00bbef..97dfa4ecd361 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -86,7 +86,7 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> { } fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap) -> CFGIndex { - let opt_cfgindex = index.find(&id).map(|&i|i); + let opt_cfgindex = index.get(&id).map(|&i|i); opt_cfgindex.unwrap_or_else(|| { panic!("nodeid_to_index does not have entry for NodeId {}", id); }) @@ -397,7 +397,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let mut changed = false; for &node_id in edge.data.exiting_scopes.iter() { - let opt_cfg_idx = self.nodeid_to_index.find(&node_id).map(|&i|i); + let opt_cfg_idx = self.nodeid_to_index.get(&node_id).map(|&i|i); match opt_cfg_idx { Some(cfg_idx) => { let (start, end) = self.compute_id_range(cfg_idx); diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index ec09706f97e8..2ae2f9bfe7a0 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -74,7 +74,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) { - self.tcx.def_map.borrow().find(id).map(|def| { + self.tcx.def_map.borrow().get(id).map(|def| { match def { &def::DefConst(_) => { self.check_def_id(def.def_id()) @@ -95,7 +95,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn lookup_and_handle_method(&mut self, id: ast::NodeId, span: codemap::Span) { let method_call = typeck::MethodCall::expr(id); - match self.tcx.method_map.borrow().find(&method_call) { + match self.tcx.method_map.borrow().get(&method_call) { Some(method) => { match method.origin { typeck::MethodStatic(def_id) => { @@ -493,7 +493,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { // method of a private type is used, but the type itself is never // called directly. let impl_items = self.tcx.impl_items.borrow(); - match self.tcx.inherent_impls.borrow().find(&local_def(id)) { + match self.tcx.inherent_impls.borrow().get(&local_def(id)) { None => (), Some(impl_list) => { for impl_did in impl_list.iter() { diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 20be74062049..bfabcc958d7c 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -158,7 +158,7 @@ fn calculate_type(sess: &session::Session, // Collect what we've got so far in the return vector. let mut ret = range(1, sess.cstore.next_crate_num()).map(|i| { - match formats.find(&i).map(|v| *v) { + match formats.get(&i).map(|v| *v) { v @ Some(cstore::RequireDynamic) => v, _ => None, } @@ -209,7 +209,7 @@ fn add_library(sess: &session::Session, cnum: ast::CrateNum, link: cstore::LinkagePreference, m: &mut HashMap) { - match m.find(&cnum) { + match m.get(&cnum) { Some(&link2) => { // If the linkages differ, then we'd have two copies of the library // if we continued linking. If the linkages are both static, then we diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index e8a85b89b584..d12b612b0336 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -162,7 +162,7 @@ impl OverloadedCallType { let trait_did = tcx.unboxed_closures .borrow() - .find(&closure_did) + .get(&closure_did) .expect("OverloadedCallType::from_unboxed_closure: didn't \ find closure id") .kind @@ -535,7 +535,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { match self.tcx() .method_map .borrow() - .find(&MethodCall::expr(call.id)) { + .get(&MethodCall::expr(call.id)) { Some(ref method_callee) => { OverloadedCallType::from_method_origin( self.tcx(), @@ -686,7 +686,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,TYPER> { // process. fn walk_adjustment(&mut self, expr: &ast::Expr) { let typer = self.typer; - match typer.adjustments().borrow().find(&expr.id) { + match typer.adjustments().borrow().get(&expr.id) { None => { } Some(adjustment) => { match *adjustment { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 08202897558f..1f3473c159f2 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -173,7 +173,7 @@ impl<'a> LanguageItemCollector<'a> { } // Matched. - *self.items.items.get_mut(item_index) = Some(item_def_id); + self.items.items[item_index] = Some(item_def_id); } pub fn collect_local_language_items(&mut self, krate: &ast::Crate) { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index b5847a94b8d9..dff9c45611aa 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -322,7 +322,7 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> { } fn variable(&self, node_id: NodeId, span: Span) -> Variable { - match self.variable_map.find(&node_id) { + match self.variable_map.get(&node_id) { Some(&var) => var, None => { self.tcx @@ -591,7 +591,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn live_node(&self, node_id: NodeId, span: Span) -> LiveNode { - match self.ir.live_node_map.find(&node_id) { + match self.ir.live_node_map.get(&node_id) { Some(&ln) => ln, None => { // This must be a mismatch between the ir_map construction @@ -719,7 +719,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { Some(_) => { // Refers to a labeled loop. Use the results of resolve // to find with one - match self.ir.tcx.def_map.borrow().find(&id) { + match self.ir.tcx.def_map.borrow().get(&id) { Some(&DefLabel(loop_id)) => loop_id, _ => self.ir.tcx.sess.span_bug(sp, "label on break/loop \ doesn't refer to a loop") @@ -988,7 +988,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // the construction of a closure itself is not important, // but we have to consider the closed over variables. - let caps = match this.ir.capture_info_map.find(&expr.id) { + let caps = match this.ir.capture_info_map.get(&expr.id) { Some(caps) => caps.clone(), None => { this.ir.tcx.sess.span_bug(expr.span, "no registered caps"); @@ -1096,7 +1096,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // Now that we know the label we're going to, // look it up in the break loop nodes table - match self.break_ln.find(&sc) { + match self.break_ln.get(&sc) { Some(&b) => b, None => self.ir.tcx.sess.span_bug(expr.span, "break to unknown label") @@ -1110,7 +1110,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // Now that we know the label we're going to, // look it up in the continue loop nodes table - match self.cont_ln.find(&sc) { + match self.cont_ln.get(&sc) { Some(&b) => b, None => self.ir.tcx.sess.span_bug(expr.span, "loop to unknown label") @@ -1167,7 +1167,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ExprMethodCall(_, _, ref args) => { let method_call = typeck::MethodCall::expr(expr.id); - let method_ty = self.ir.tcx.method_map.borrow().find(&method_call).unwrap().ty; + let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty; let diverges = ty::ty_fn_ret(method_ty) == ty::FnDiverging; let succ = if diverges { self.s.exit_ln @@ -1520,7 +1520,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ty::ty_unboxed_closure(closure_def_id, _, _) => self.ir.tcx.unboxed_closures() .borrow() - .find(&closure_def_id) + .get(&closure_def_id) .unwrap() .closure_type .sig diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c0188cac259c..4c396a5a2051 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -389,7 +389,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult { let unadjusted_ty = if_ok!(self.expr_ty(expr)); Ok(ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty, - self.typer.adjustments().borrow().find(&expr.id), + self.typer.adjustments().borrow().get(&expr.id), |method_call| self.typer.node_method_ty(method_call))) } @@ -402,7 +402,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } pub fn cat_expr(&self, expr: &ast::Expr) -> McResult { - match self.typer.adjustments().borrow().find(&expr.id) { + match self.typer.adjustments().borrow().get(&expr.id) { None => { // No adjustments. self.cat_expr_unadjusted(expr) @@ -861,7 +861,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { deref_cnt: uint, implicit: bool) -> cmt { - let adjustment = match self.typer.adjustments().borrow().find(&node.id()) { + let adjustment = match self.typer.adjustments().borrow().get(&node.id()) { Some(adj) if ty::adjust_is_object(adj) => typeck::AutoObject, _ if deref_cnt != 0 => typeck::AutoDeref(deref_cnt), _ => typeck::NoAdjustment @@ -1170,7 +1170,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { // variant(..) } ast::PatEnum(_, Some(ref subpats)) => { - match self.tcx().def_map.borrow().find(&pat.id) { + match self.tcx().def_map.borrow().get(&pat.id) { Some(&def::DefVariant(enum_did, _, _)) => { // variant(x, y, z) diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 357f4cdf0ebc..958f65d7efb2 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -34,7 +34,7 @@ pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatLit(_) | PatRange(_, _) => true, PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => { - match dm.borrow().find(&pat.id) { + match dm.borrow().get(&pat.id) { Some(&DefVariant(..)) => true, _ => false } @@ -47,7 +47,7 @@ pub fn pat_is_refutable(dm: &resolve::DefMap, pat: &Pat) -> bool { pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatEnum(_, _) | PatIdent(_, _, None) | PatStruct(..) => { - match dm.borrow().find(&pat.id) { + match dm.borrow().get(&pat.id) { Some(&DefVariant(..)) | Some(&DefStruct(..)) => true, _ => false } @@ -59,7 +59,7 @@ pub fn pat_is_variant_or_struct(dm: &resolve::DefMap, pat: &Pat) -> bool { pub fn pat_is_const(dm: &resolve::DefMap, pat: &Pat) -> bool { match pat.node { PatIdent(_, _, None) | PatEnum(..) => { - match dm.borrow().find(&pat.id) { + match dm.borrow().get(&pat.id) { Some(&DefConst(..)) => true, _ => false } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 4fbffa2a819d..24c653e415e5 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -399,7 +399,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { } debug!("privacy - is {} a public method", did); - return match self.tcx.impl_or_trait_items.borrow().find(&did) { + return match self.tcx.impl_or_trait_items.borrow().get(&did) { Some(&ty::MethodTraitItem(ref meth)) => { debug!("privacy - well at least it's a method: {}", *meth); @@ -462,7 +462,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { debug!("privacy - local {} not public all the way down", self.tcx.map.node_to_string(did.node)); // return quickly for things in the same module - if self.parents.find(&did.node) == self.parents.find(&self.curitem) { + if self.parents.get(&did.node) == self.parents.get(&self.curitem) { debug!("privacy - same parent, we're done here"); return Allowable; } @@ -855,7 +855,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } ast::ExprMethodCall(ident, _, _) => { let method_call = MethodCall::expr(expr.id); - match self.tcx.method_map.borrow().find(&method_call) { + match self.tcx.method_map.borrow().get(&method_call) { None => { self.tcx.sess.span_bug(expr.span, "method call not in \ @@ -909,7 +909,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { with private fields"); } }; - match self.tcx.def_map.borrow().find(&expr.id) { + match self.tcx.def_map.borrow().get(&expr.id) { Some(&def::DefStruct(did)) => { guard(if is_local(did) { local_def(self.tcx.map.get_parent(did.node)) @@ -986,7 +986,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } } ty::ty_enum(_, _) => { - match self.tcx.def_map.borrow().find(&pattern.id) { + match self.tcx.def_map.borrow().get(&pattern.id) { Some(&def::DefVariant(_, variant_id, _)) => { for field in fields.iter() { self.check_field(pattern.span, variant_id, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 4506cd7e4634..dbeb2e289fb7 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -106,7 +106,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { match expr.node { ast::ExprPath(_) => { - let def = match self.tcx.def_map.borrow().find(&expr.id) { + let def = match self.tcx.def_map.borrow().get(&expr.id) { Some(&def) => def, None => { self.tcx.sess.span_bug(expr.span, diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 32e373f5851c..d380c35580d1 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -103,7 +103,7 @@ struct RegionResolutionVisitor<'a> { impl RegionMaps { pub fn relate_free_regions(&self, sub: FreeRegion, sup: FreeRegion) { - match self.free_region_map.borrow_mut().find_mut(&sub) { + match self.free_region_map.borrow_mut().get_mut(&sub) { Some(sups) => { if !sups.iter().any(|x| x == &sup) { sups.push(sup); @@ -149,13 +149,13 @@ impl RegionMaps { pub fn opt_encl_scope(&self, id: ast::NodeId) -> Option { //! Returns the narrowest scope that encloses `id`, if any. - self.scope_map.borrow().find(&id).map(|x| *x) + self.scope_map.borrow().get(&id).map(|x| *x) } #[allow(dead_code)] // used in middle::cfg pub fn encl_scope(&self, id: ast::NodeId) -> ast::NodeId { //! Returns the narrowest scope that encloses `id`, if any. - match self.scope_map.borrow().find(&id) { + match self.scope_map.borrow().get(&id) { Some(&r) => r, None => { panic!("no enclosing scope for id {}", id); } } @@ -165,7 +165,7 @@ impl RegionMaps { /*! * Returns the lifetime of the local variable `var_id` */ - match self.var_map.borrow().find(&var_id) { + match self.var_map.borrow().get(&var_id) { Some(&r) => r, None => { panic!("no enclosing scope for id {}", var_id); } } @@ -175,7 +175,7 @@ impl RegionMaps { //! Returns the scope when temp created by expr_id will be cleaned up // check for a designated rvalue scope - match self.rvalue_scopes.borrow().find(&expr_id) { + match self.rvalue_scopes.borrow().get(&expr_id) { Some(&s) => { debug!("temporary_scope({}) = {} [custom]", expr_id, s); return Some(s); @@ -232,7 +232,7 @@ impl RegionMaps { let mut s = subscope; while superscope != s { - match self.scope_map.borrow().find(&s) { + match self.scope_map.borrow().get(&s) { None => { debug!("is_subscope_of({}, {}, s={})=false", subscope, superscope, s); @@ -356,7 +356,7 @@ impl RegionMaps { let mut result = vec!(scope); let mut scope = scope; loop { - match this.scope_map.borrow().find(&scope) { + match this.scope_map.borrow().get(&scope) { None => return result, Some(&superscope) => { result.push(superscope); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index ed7d9296c701..a8adbbe8feca 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -2234,7 +2234,7 @@ impl<'a> Resolver<'a> { let mut import_resolutions = module_.import_resolutions .borrow_mut(); - match import_resolutions.find_mut(&target) { + match import_resolutions.get_mut(&target) { Some(resolution) => { debug!("(building import directive) bumping \ reference"); @@ -2552,7 +2552,7 @@ impl<'a> Resolver<'a> { // Search for direct children of the containing module. self.populate_module_if_necessary(&containing_module); - match containing_module.children.borrow().find(&source) { + match containing_module.children.borrow().get(&source) { None => { // Continue. } @@ -2588,7 +2588,7 @@ impl<'a> Resolver<'a> { } // Now search the exported imports within the containing module. - match containing_module.import_resolutions.borrow().find(&source) { + match containing_module.import_resolutions.borrow().get(&source) { None => { debug!("(resolving single import) no import"); // The containing module definitely doesn't have an @@ -2853,7 +2853,7 @@ impl<'a> Resolver<'a> { // Here we merge two import resolutions. let mut import_resolutions = module_.import_resolutions.borrow_mut(); - match import_resolutions.find_mut(ident) { + match import_resolutions.get_mut(ident) { Some(dest_import_resolution) => { // Merge the two import resolutions at a finer-grained // level. @@ -3046,7 +3046,7 @@ impl<'a> Resolver<'a> { // Check for item conflicts. let children = module.children.borrow(); - let name_bindings = match children.find(&name) { + let name_bindings = match children.get(&name) { None => { // There can't be any conflicts. return @@ -3432,7 +3432,7 @@ impl<'a> Resolver<'a> { // its immediate children. self.populate_module_if_necessary(&module_); - match module_.children.borrow().find(&name) { + match module_.children.borrow().get(&name) { Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => { debug!("top name bindings succeeded"); @@ -3448,7 +3448,7 @@ impl<'a> Resolver<'a> { // all its imports in the usual way; this is because chains of // adjacent import statements are processed as though they mutated the // current scope. - match module_.import_resolutions.borrow().find(&name) { + match module_.import_resolutions.borrow().get(&name) { None => { // Not found; continue. } @@ -3705,7 +3705,7 @@ impl<'a> Resolver<'a> { // First, check the direct children of the module. self.populate_module_if_necessary(&module_); - match module_.children.borrow().find(&name) { + match module_.children.borrow().get(&name) { Some(name_bindings) if name_bindings.defined_in_namespace(namespace) => { debug!("(resolving name in module) found node as child"); @@ -3728,7 +3728,7 @@ impl<'a> Resolver<'a> { } // Check the list of resolved imports. - match module_.import_resolutions.borrow().find(&name) { + match module_.import_resolutions.borrow().get(&name) { Some(import_resolution) if allow_private_imports || import_resolution.is_public => { @@ -3967,7 +3967,7 @@ impl<'a> Resolver<'a> { Some(name) => { self.populate_module_if_necessary(&orig_module); - match orig_module.children.borrow().find(&name) { + match orig_module.children.borrow().get(&name) { None => { debug!("!!! (with scope) didn't find `{}` in `{}`", token::get_name(name), @@ -4691,7 +4691,7 @@ impl<'a> Resolver<'a> { Some(ref trait_ref) => { self.resolve_trait_reference(id, trait_ref, TraitImplementation); - match self.def_map.borrow().find(&trait_ref.ref_id) { + match self.def_map.borrow().get(&trait_ref.ref_id) { Some(def) => { let did = def.def_id(); Some((did, trait_ref.clone())) @@ -4767,7 +4767,7 @@ impl<'a> Resolver<'a> { // a type (shadowing any imported modules or types with this name), leading // to weird user-visible bugs. So we ward this off here. See #15060. TyPath(ref path, _, path_id) => { - match self.def_map.borrow().find(&path_id) { + match self.def_map.borrow().get(&path_id) { // FIXME: should we catch other options and give more precise errors? Some(&DefMod(_)) => { self.resolve_error(path.span, "inherent implementations are not \ @@ -4785,7 +4785,7 @@ impl<'a> Resolver<'a> { fn check_trait_item(&self, name: Name, span: Span) { // If there is a TraitRef in scope for an impl, then the method must be in the trait. for &(did, ref trait_ref) in self.current_trait_ref.iter() { - if self.trait_item_map.find(&(name, did)).is_none() { + if self.trait_item_map.get(&(name, did)).is_none() { let path_str = self.path_names_to_string(&trait_ref.path); self.resolve_error(span, format!("method `{}` is not a member of trait `{}`", @@ -4849,7 +4849,7 @@ impl<'a> Resolver<'a> { let map_i = self.binding_mode_map(&**p); for (&key, &binding_0) in map_0.iter() { - match map_i.find(&key) { + match map_i.get(&key) { None => { self.resolve_error( p.span, @@ -4908,7 +4908,7 @@ impl<'a> Resolver<'a> { // Move down in the graph, if there's an anonymous module rooted here. let orig_module = self.current_module.clone(); - match orig_module.anonymous_children.borrow().find(&block.id) { + match orig_module.anonymous_children.borrow().get(&block.id) { None => { /* Nothing to do. */ } Some(anonymous_module) => { debug!("(resolving block) found anonymous module, moving \ @@ -4943,7 +4943,7 @@ impl<'a> Resolver<'a> { match self.primitive_type_table .primitive_types - .find(&id.name) { + .get(&id.name) { Some(&primitive_type) => { result_def = @@ -5181,7 +5181,7 @@ impl<'a> Resolver<'a> { token::get_ident( ident)) .as_slice()) - } else if bindings_list.find(&renamed) == + } else if bindings_list.get(&renamed) == Some(&pat_id) { // Then this is a duplicate variable in the // same disjunction, which is an error. @@ -5407,7 +5407,7 @@ impl<'a> Resolver<'a> { // First, search children. self.populate_module_if_necessary(&containing_module); - match containing_module.children.borrow().find(&name) { + match containing_module.children.borrow().get(&name) { Some(child_name_bindings) => { match child_name_bindings.def_for_namespace(namespace) { Some(def) => { @@ -5426,7 +5426,7 @@ impl<'a> Resolver<'a> { } // Next, search import resolutions. - match containing_module.import_resolutions.borrow().find(&name) { + match containing_module.import_resolutions.borrow().get(&name) { Some(import_resolution) if import_resolution.is_public => { match (*import_resolution).target_for_namespace(namespace) { Some(target) => { @@ -5715,10 +5715,10 @@ impl<'a> Resolver<'a> { let last_name = name_path.last().unwrap(); if name_path.len() == 1 { - match this.primitive_type_table.primitive_types.find(last_name) { + match this.primitive_type_table.primitive_types.get(last_name) { Some(_) => None, None => { - match this.current_module.children.borrow().find(last_name) { + match this.current_module.children.borrow().get(last_name) { Some(child) => child.get_module_if_available(), None => None } @@ -5746,10 +5746,10 @@ impl<'a> Resolver<'a> { if allowed == Everything { // Look for a field with the same name in the current self_type. - match self.def_map.borrow().find(&node_id) { + match self.def_map.borrow().get(&node_id) { Some(&DefTy(did, _)) | Some(&DefStruct(did)) - | Some(&DefVariant(_, did, _)) => match self.structs.find(&did) { + | Some(&DefVariant(_, did, _)) => match self.structs.get(&did) { None => {} Some(fields) => { if fields.iter().any(|&field_name| name == field_name) { @@ -5765,7 +5765,7 @@ impl<'a> Resolver<'a> { // Look for a method in the current self type's impl module. match get_module(self, path.span, name_path.as_slice()) { - Some(module) => match module.children.borrow().find(&name) { + Some(module) => match module.children.borrow().get(&name) { Some(binding) => { let p_str = self.path_names_to_string(&path); match binding.def_for_namespace(ValueNS) { @@ -5790,7 +5790,7 @@ impl<'a> Resolver<'a> { Some((did, ref trait_ref)) => { let path_str = self.path_names_to_string(&trait_ref.path); - match self.trait_item_map.find(&(name, did)) { + match self.trait_item_map.get(&(name, did)) { Some(&StaticMethodTraitItemKind) => { return TraitMethod(path_str) } @@ -6270,7 +6270,7 @@ impl<'a> Resolver<'a> { "unused import".to_string()); } - let (v_priv, t_priv) = match self.last_private.find(&id) { + let (v_priv, t_priv) = match self.last_private.get(&id) { Some(&LastImport { value_priv: v, value_used: _, diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 09bd0f52985b..7fcc58d8f4e4 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -906,7 +906,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { let cache = self.pick_candidate_cache(&cache_skol_trait_ref); let hashmap = cache.hashmap.borrow(); - hashmap.find(&cache_skol_trait_ref).map(|c| (*c).clone()) + hashmap.get(&cache_skol_trait_ref).map(|c| (*c).clone()) } fn insert_candidate_cache(&mut self, @@ -1032,7 +1032,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self_ty.repr(self.tcx()), obligation.repr(self.tcx())); - let closure_kind = match self.typer.unboxed_closures().borrow().find(&closure_def_id) { + let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) { Some(closure) => closure.kind, None => { self.tcx().sess.span_bug( @@ -1282,7 +1282,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::BoundSync | ty::BoundSend => { - if c.bounds.builtin_bounds.contains_elem(bound) { + if c.bounds.builtin_bounds.contains(&bound) { Ok(If(Vec::new())) } else { Err(Unimplemented) @@ -1306,7 +1306,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::BoundSync | ty::BoundSend => { - if c.bounds.builtin_bounds.contains_elem(bound) { + if c.bounds.builtin_bounds.contains(&bound) { Ok(If(Vec::new())) } else { Err(Unimplemented) @@ -1323,7 +1323,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(Unimplemented) } ty::BoundCopy | ty::BoundSync | ty::BoundSend => { - if bounds.builtin_bounds.contains_elem(bound) { + if bounds.builtin_bounds.contains(&bound) { Ok(If(Vec::new())) } else { Err(Unimplemented) @@ -1428,7 +1428,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // is reserve judgement and then intertwine this // analysis with closure inference. assert_eq!(def_id.krate, ast::LOCAL_CRATE); - match self.tcx().freevars.borrow().find(&def_id.node) { + match self.tcx().freevars.borrow().get(&def_id.node) { None => { // No upvars. Ok(If(Vec::new())) @@ -1690,7 +1690,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { closure_def_id.repr(self.tcx()), substs.repr(self.tcx())); - let closure_type = match self.typer.unboxed_closures().borrow().find(&closure_def_id) { + let closure_type = match self.typer.unboxed_closures().borrow().get(&closure_def_id) { Some(closure) => closure.closure_type.clone(), None => { self.tcx().sess.span_bug( @@ -1973,7 +1973,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::populate_implementations_for_trait_if_necessary(self.tcx(), trait_def_id); - match self.tcx().trait_impls.borrow().find(&trait_def_id) { + match self.tcx().trait_impls.borrow().get(&trait_def_id) { None => Vec::new(), Some(impls) => impls.borrow().clone() } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 70aef4504f03..e148261b1bf2 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -696,13 +696,13 @@ fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: uint) -> bool { match pat.node { ast::PatTup(_) => true, ast::PatStruct(..) => { - match tcx.def_map.borrow().find(&pat.id) { + match tcx.def_map.borrow().get(&pat.id) { Some(&def::DefVariant(..)) => false, _ => true, } } ast::PatEnum(..) | ast::PatIdent(_, _, None) => { - match tcx.def_map.borrow().find(&pat.id) { + match tcx.def_map.borrow().get(&pat.id) { Some(&def::DefStruct(..)) => true, _ => false } diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index d3658e89a2a5..7ff94c28d93b 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -147,7 +147,7 @@ pub fn represent_node(bcx: Block, node: ast::NodeId) -> Rc { /// Decides how to represent a given type. pub fn represent_type(cx: &CrateContext, t: ty::t) -> Rc { debug!("Representing: {}", ty_to_string(cx.tcx(), t)); - match cx.adt_reprs().borrow().find(&t) { + match cx.adt_reprs().borrow().get(&t) { Some(repr) => return repr.clone(), None => {} } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b80425e7ac85..3b3b886c6d06 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -316,7 +316,7 @@ pub fn get_extern_const(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> ValueRef { let name = csearch::get_symbol(&ccx.sess().cstore, did); let ty = type_of(ccx, t); - match ccx.externs().borrow_mut().find(&name) { + match ccx.externs().borrow_mut().get(&name) { Some(n) => return *n, None => () } @@ -409,7 +409,7 @@ pub fn malloc_raw_dyn_proc<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: ty::t) -> Resu // Type descriptor and type glue stuff pub fn get_tydesc(ccx: &CrateContext, t: ty::t) -> Rc { - match ccx.tydescs().borrow().find(&t) { + match ccx.tydescs().borrow().get(&t) { Some(inf) => return inf.clone(), _ => { } } @@ -2100,7 +2100,7 @@ fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, let levels = ccx.tcx().node_lint_levels.borrow(); let lint_id = lint::LintId::of(lint::builtin::VARIANT_SIZE_DIFFERENCES); - let lvlsrc = match levels.find(&(id, lint_id)) { + let lvlsrc = match levels.get(&(id, lint_id)) { None | Some(&(lint::Allow, _)) => return, Some(&lvlsrc) => lvlsrc, }; @@ -2645,7 +2645,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, fn exported_name(ccx: &CrateContext, id: ast::NodeId, ty: ty::t, attrs: &[ast::Attribute]) -> String { - match ccx.external_srcs().borrow().find(&id) { + match ccx.external_srcs().borrow().get(&id) { Some(&did) => { let sym = csearch::get_symbol(&ccx.sess().cstore, did); debug!("found item {} in other crate...", sym); @@ -3123,7 +3123,7 @@ pub fn trans_crate<'tcx>(analysis: CrateAnalysis<'tcx>) .collect(); let mut reachable: Vec = shared_ccx.reachable().iter().filter_map(|id| { - shared_ccx.item_symbols().borrow().find(id).map(|s| s.to_string()) + shared_ccx.item_symbols().borrow().get(id).map(|s| s.to_string()) }).collect(); // For the purposes of LTO, we add to the reachable set all of the upstream diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs index 81428937e4b1..b692b01f765d 100644 --- a/src/librustc/middle/trans/builder.rs +++ b/src/librustc/middle/trans/builder.rs @@ -81,7 +81,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { s.push('/'); s.push_str(category); - let n = match h.find(&s) { + let n = match h.get(&s) { Some(&n) => n, _ => 0u }; diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index decd238627c2..16db4daba46b 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -438,7 +438,7 @@ pub fn get_or_create_declaration_if_unboxed_closure<'blk, 'tcx>(bcx: Block<'blk, params: params }; - match ccx.unboxed_closure_vals().borrow().find(&mono_id) { + match ccx.unboxed_closure_vals().borrow().get(&mono_id) { Some(llfn) => { debug!("get_or_create_declaration_if_unboxed_closure(): found \ closure"); @@ -564,7 +564,7 @@ pub fn get_wrapper_for_bare_fn(ccx: &CrateContext, } }; - match ccx.closure_bare_wrapper_cache().borrow().find(&fn_ptr) { + match ccx.closure_bare_wrapper_cache().borrow().get(&fn_ptr) { Some(&llval) => return llval, None => {} } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 8b5e82ecf901..18501dd9e34c 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -466,7 +466,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> { } pub fn def(&self, nid: ast::NodeId) -> def::Def { - match self.tcx().def_map.borrow().find(&nid) { + match self.tcx().def_map.borrow().get(&nid) { Some(v) => v.clone(), None => { self.tcx().sess.bug(format!( @@ -505,7 +505,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { self.tcx() .method_map .borrow() - .find(&method_call) + .get(&method_call) .map(|method| monomorphize_type(self, method.ty)) } @@ -647,7 +647,7 @@ pub fn C_u8(ccx: &CrateContext, i: uint) -> ValueRef { // our boxed-and-length-annotated strings. pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef { unsafe { - match cx.const_cstr_cache().borrow().find(&s) { + match cx.const_cstr_cache().borrow().get(&s) { Some(&llval) => return llval, None => () } @@ -813,7 +813,7 @@ pub fn fulfill_obligation(ccx: &CrateContext, let trait_ref = ty_fold::erase_regions(tcx, trait_ref); // First check the cache. - match ccx.trait_cache().borrow().find(&trait_ref) { + match ccx.trait_cache().borrow().get(&trait_ref) { Some(vtable) => { info!("Cache hit: {}", trait_ref.repr(ccx.tcx())); return (*vtable).clone(); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index 6ba6ff6fb211..ced6c2f49492 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -90,7 +90,7 @@ pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit) pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef { unsafe { let b = llvm::LLVMConstPointerCast(a, t.ptr_to().to_ref()); - assert!(cx.const_globals().borrow_mut().insert(b as int, a)); + assert!(cx.const_globals().borrow_mut().insert(b as int, a).is_none()); b } } @@ -125,7 +125,7 @@ pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) -> } fn const_deref_ptr(cx: &CrateContext, v: ValueRef) -> ValueRef { - let v = match cx.const_globals().borrow().find(&(v as int)) { + let v = match cx.const_globals().borrow().get(&(v as int)) { Some(&v) => v, None => v }; diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 911ae42e142d..714d5ab248d5 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -421,7 +421,7 @@ pub fn trans_break_cont<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let loop_id = match opt_label { None => fcx.top_loop_scope(), Some(_) => { - match bcx.tcx().def_map.borrow().find(&expr_id) { + match bcx.tcx().def_map.borrow().get(&expr_id) { Some(&def::DefLabel(loop_id)) => loop_id, ref r => { bcx.tcx().sess.bug(format!("{} in def-map for label", diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index ea7f28796f03..c84543773a4a 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -282,7 +282,7 @@ impl TypeMap { cx: &CrateContext, type_: ty::t, metadata: DIType) { - if !self.type_to_metadata.insert(ty::type_id(type_), metadata) { + if self.type_to_metadata.insert(ty::type_id(type_), metadata).is_some() { cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!", ppaux::ty_to_string(cx.tcx(), type_)).as_slice()); } @@ -294,7 +294,7 @@ impl TypeMap { cx: &CrateContext, unique_type_id: UniqueTypeId, metadata: DIType) { - if !self.unique_id_to_metadata.insert(unique_type_id, metadata) { + if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() { let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id); cx.sess().bug(format!("Type metadata for unique id '{}' is already in the TypeMap!", unique_type_id_str.as_slice()).as_slice()); @@ -468,7 +468,7 @@ impl TypeMap { }, ty::ty_unboxed_closure(ref def_id, _, ref substs) => { let closure_ty = cx.tcx().unboxed_closures.borrow() - .find(def_id).unwrap().closure_type.subst(cx.tcx(), substs); + .get(def_id).unwrap().closure_type.subst(cx.tcx(), substs); self.get_unique_type_id_of_closure_type(cx, closure_ty, &mut unique_type_id); @@ -2939,7 +2939,7 @@ fn type_metadata(cx: &CrateContext, } ty::ty_unboxed_closure(ref def_id, _, ref substs) => { let sig = cx.tcx().unboxed_closures.borrow() - .find(def_id).unwrap().closure_type.sig.subst(cx.tcx(), substs); + .get(def_id).unwrap().closure_type.sig.subst(cx.tcx(), substs); subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span) } ty::ty_struct(def_id, ref substs) => { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index a0ba2996334b..b01d891270b1 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -212,7 +212,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Don't skip a conversion from Box to &T, etc. ty::ty_rptr(..) => { let method_call = MethodCall::autoderef(expr.id, adj.autoderefs-1); - let method = bcx.tcx().method_map.borrow().find(&method_call).is_some(); + let method = bcx.tcx().method_map.borrow().get(&method_call).is_some(); if method { // Don't skip an overloaded deref. (adj.autoderefs, true) @@ -601,7 +601,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let method_ty = ccx.tcx() .method_map .borrow() - .find(&method_call) + .get(&method_call) .map(|method| method.ty); let base_datum = unpack_datum!(bcx, trans(bcx, &**base)); @@ -736,7 +736,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let method_ty = ccx.tcx() .method_map .borrow() - .find(&method_call) + .get(&method_call) .map(|method| method.ty); let elt_datum = match method_ty { Some(method_ty) => { @@ -1114,7 +1114,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if ty::type_is_trait(node_id_type(bcx, expr.id)) { let trait_ref = bcx.tcx().object_cast_map.borrow() - .find(&expr.id) + .get(&expr.id) .map(|t| (*t).clone()) .unwrap(); let trait_ref = @@ -1232,7 +1232,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, def::DefUpvar(nid, _, _) => { // Can't move upvars, so this is never a ZeroMemLastUse. let local_ty = node_id_type(bcx, nid); - match bcx.fcx.llupvars.borrow().find(&nid) { + match bcx.fcx.llupvars.borrow().get(&nid) { Some(&val) => Datum::new(val, local_ty, Lvalue), None => { bcx.sess().bug(format!( @@ -1242,7 +1242,7 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } } def::DefLocal(nid) => { - let datum = match bcx.fcx.lllocals.borrow().find(&nid) { + let datum = match bcx.fcx.lllocals.borrow().get(&nid) { Some(&v) => v, None => { bcx.sess().bug(format!( @@ -2089,7 +2089,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Check for overloaded deref. let method_ty = ccx.tcx().method_map.borrow() - .find(&method_call).map(|method| method.ty); + .get(&method_call).map(|method| method.ty); let datum = match method_ty { Some(method_ty) => { // Overloaded. Evaluate `trans_overloaded_op`, which will diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index fb85e6198666..eb6e67efd49a 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -144,7 +144,7 @@ pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef { debug!("make drop glue for {}", ppaux::ty_to_string(ccx.tcx(), t)); let t = get_drop_glue_type(ccx, t); debug!("drop glue type {}", ppaux::ty_to_string(ccx.tcx(), t)); - match ccx.drop_glues().borrow().find(&t) { + match ccx.drop_glues().borrow().get(&t) { Some(&glue) => return glue, _ => { } } @@ -157,7 +157,7 @@ pub fn get_drop_glue(ccx: &CrateContext, t: ty::t) -> ValueRef { let llfnty = Type::glue_fn(ccx, llty); - let (glue, new_sym) = match ccx.available_drop_glues().borrow().find(&t) { + let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) { Some(old_sym) => { let glue = decl_cdecl_fn(ccx, old_sym.as_slice(), llfnty, ty::mk_nil()); (glue, None) diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 048402782a6d..65d7749b4892 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -21,7 +21,7 @@ use syntax::ast_util::{local_def, PostExpansionMethod}; fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId) -> Option { let _icx = push_ctxt("maybe_instantiate_inline"); - match ccx.external().borrow().find(&fn_id) { + match ccx.external().borrow().get(&fn_id) { Some(&Some(node_id)) => { // Already inline debug!("maybe_instantiate_inline({}): already inline as node id {}", diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index fbd4db959ce0..0ae728c71ee6 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -116,7 +116,7 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let (origin, method_ty) = bcx.tcx().method_map .borrow() - .find(&method_call) + .get(&method_call) .map(|method| (method.origin.clone(), method.ty)) .unwrap(); @@ -308,7 +308,7 @@ fn method_with_name(ccx: &CrateContext, impl_id: ast::DefId, name: ast::Name) let impl_items = ccx.tcx().impl_items.borrow(); let impl_items = - impl_items.find(&impl_id) + impl_items.get(&impl_id) .expect("could not find impl while translating"); let meth_did = impl_items.iter() .find(|&did| { @@ -559,7 +559,7 @@ pub fn get_vtable(bcx: Block, // Check the cache. let cache_key = (box_ty, trait_ref.clone()); - match ccx.vtables().borrow().find(&cache_key) { + match ccx.vtables().borrow().get(&cache_key) { Some(&val) => { return val } None => { } } @@ -599,7 +599,7 @@ pub fn get_vtable(bcx: Block, .unboxed_closures .borrow(); let closure_info = - unboxed_closures.find(&closure_def_id) + unboxed_closures.get(&closure_def_id) .expect("get_vtable(): didn't find \ unboxed closure"); if closure_info.kind == ty::FnOnceUnboxedClosureKind { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 258d12e631f2..f9d42240f35b 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -54,7 +54,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, params: real_substs.types.clone() }; - match ccx.monomorphized().borrow().find(&hash_id) { + match ccx.monomorphized().borrow().get(&hash_id) { Some(&val) => { debug!("leaving monomorphic fn {}", ty::item_path_str(ccx.tcx(), fn_id)); @@ -106,7 +106,7 @@ pub fn monomorphic_fn(ccx: &CrateContext, let depth; { let mut monomorphizing = ccx.monomorphizing().borrow_mut(); - depth = match monomorphizing.find(&fn_id) { + depth = match monomorphizing.get(&fn_id) { Some(&d) => d, None => 0 }; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 7b8eb4e02b2b..175b0d7adde0 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -332,7 +332,7 @@ impl TypeNames { pub fn associate_type(&self, s: &str, t: &Type) { assert!(self.named_types.borrow_mut().insert(s.to_string(), - t.to_ref())); + t.to_ref()).is_none()); } pub fn find_type(&self, s: &str) -> Option { diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 649dbbacc698..d1b8f767bc85 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -272,7 +272,7 @@ pub fn type_of(cx: &CrateContext, t: ty::t) -> Type { } // Check the cache. - match cx.lltypes().borrow().find(&t) { + match cx.lltypes().borrow().get(&t) { Some(&llty) => return llty, None => () } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 76caa42b8502..421042a86489 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1080,14 +1080,14 @@ pub enum BuiltinBound { } pub fn empty_builtin_bounds() -> BuiltinBounds { - EnumSet::empty() + EnumSet::new() } pub fn all_builtin_bounds() -> BuiltinBounds { - let mut set = EnumSet::empty(); - set.add(BoundSend); - set.add(BoundSized); - set.add(BoundSync); + let mut set = EnumSet::new(); + set.insert(BoundSend); + set.insert(BoundSized); + set.insert(BoundSync); set } @@ -1584,7 +1584,7 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t { let key = intern_key { sty: &st }; - match cx.interner.borrow().find(&key) { + match cx.interner.borrow().get(&key) { Some(t) => unsafe { return mem::transmute(&t.sty); }, _ => () } @@ -2418,11 +2418,11 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents { // value for the type contents of list. The correct value is // TC::OwnsOwned. This manifested as issue #4821. let ty_id = type_id(ty); - match cache.find(&ty_id) { + match cache.get(&ty_id) { Some(tc) => { return *tc; } None => {} } - match cx.tc_cache.borrow().find(&ty_id) { // Must check both caches! + match cx.tc_cache.borrow().get(&ty_id) { // Must check both caches! Some(tc) => { return *tc; } None => {} } @@ -3192,7 +3192,7 @@ pub fn array_element_ty(t: t) -> Option { } pub fn node_id_to_trait_ref(cx: &ctxt, id: ast::NodeId) -> Rc { - match cx.trait_refs.borrow().find(&id) { + match cx.trait_refs.borrow().get(&id) { Some(t) => t.clone(), None => cx.sess.bug( format!("node_id_to_trait_ref: no trait ref for node `{}`", @@ -3214,14 +3214,14 @@ pub fn node_id_to_type(cx: &ctxt, id: ast::NodeId) -> t { } pub fn node_id_to_type_opt(cx: &ctxt, id: ast::NodeId) -> Option { - match cx.node_types.borrow().find(&(id as uint)) { + match cx.node_types.borrow().get(&(id as uint)) { Some(&t) => Some(t), None => None } } pub fn node_id_item_substs(cx: &ctxt, id: ast::NodeId) -> ItemSubsts { - match cx.item_substs.borrow().find(&id) { + match cx.item_substs.borrow().get(&id) { None => ItemSubsts::empty(), Some(ts) => ts.clone(), } @@ -3361,8 +3361,8 @@ pub fn expr_ty_adjusted(cx: &ctxt, expr: &ast::Expr) -> t { */ adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr), - cx.adjustments.borrow().find(&expr.id), - |method_call| cx.method_map.borrow().find(&method_call).map(|method| method.ty)) + cx.adjustments.borrow().get(&expr.id), + |method_call| cx.method_map.borrow().get(&method_call).map(|method| method.ty)) } pub fn expr_span(cx: &ctxt, id: NodeId) -> Span { @@ -3553,7 +3553,7 @@ pub fn unsize_ty(cx: &ctxt, } pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def { - match tcx.def_map.borrow().find(&expr.id) { + match tcx.def_map.borrow().get(&expr.id) { Some(&def) => def, None => { tcx.sess.span_bug(expr.span, format!( @@ -3690,7 +3690,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { } ast::ExprCast(..) => { - match tcx.node_types.borrow().find(&(expr.id as uint)) { + match tcx.node_types.borrow().get(&(expr.id as uint)) { Some(&t) => { if type_is_trait(t) { RvalueDpsExpr @@ -3736,7 +3736,7 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprBox(ref place, _) => { // Special case `Box` for now: - let definition = match tcx.def_map.borrow().find(&place.id) { + let definition = match tcx.def_map.borrow().get(&place.id) { Some(&def) => def, None => panic!("no def for place"), }; @@ -4003,7 +4003,7 @@ pub fn note_and_explain_type_err(cx: &ctxt, err: &type_err) { } pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option { - cx.provided_method_sources.borrow().find(&id).map(|x| *x) + cx.provided_method_sources.borrow().get(&id).map(|x| *x) } pub fn provided_trait_methods(cx: &ctxt, id: ast::DefId) -> Vec> { @@ -4113,7 +4113,7 @@ pub fn impl_or_trait_item(cx: &ctxt, id: ast::DefId) -> ImplOrTraitItem { pub fn is_associated_type(cx: &ctxt, id: ast::DefId) -> bool { memoized(&cx.associated_types, id, |id: ast::DefId| { if id.krate == ast::LOCAL_CRATE { - match cx.impl_or_trait_items.borrow().find(&id) { + match cx.impl_or_trait_items.borrow().get(&id) { Some(ref item) => { match **item { TypeTraitItem(_) => true, @@ -4198,7 +4198,7 @@ pub fn impl_trait_ref(cx: &ctxt, id: ast::DefId) -> Option> { pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId { let def = *tcx.def_map.borrow() - .find(&tr.ref_id) + .get(&tr.ref_id) .expect("no def-map entry for trait"); def.def_id() } @@ -4215,7 +4215,7 @@ pub fn try_add_builtin_trait( //! is a builtin trait. match tcx.lang_items.to_builtin_kind(trait_def_id) { - Some(bound) => { builtin_bounds.add(bound); true } + Some(bound) => { builtin_bounds.insert(bound); true } None => false } } @@ -4346,7 +4346,7 @@ impl DtorKind { /* If struct_id names a struct with a dtor, return Some(the dtor's id). Otherwise return none. */ pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind { - match cx.destructor_for_type.borrow().find(&struct_id) { + match cx.destructor_for_type.borrow().get(&struct_id) { Some(&method_def_id) => { let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag"); @@ -4569,7 +4569,7 @@ pub fn lookup_field_type(tcx: &ctxt, pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec { if did.krate == ast::LOCAL_CRATE { let struct_fields = cx.struct_fields.borrow(); - match struct_fields.find(&did) { + match struct_fields.get(&did) { Some(fields) => (**fields).clone(), _ => { cx.sess.bug( @@ -4632,7 +4632,7 @@ pub fn unboxed_closure_upvars(tcx: &ctxt, closure_id: ast::DefId, substs: &Subst // implemented. assert!(closure_id.krate == ast::LOCAL_CRATE); let capture_mode = tcx.capture_modes.borrow().get_copy(&closure_id.node); - match tcx.freevars.borrow().find(&closure_id.node) { + match tcx.freevars.borrow().get(&closure_id.node) { None => vec![], Some(ref freevars) => { freevars.iter().map(|freevar| { @@ -4898,7 +4898,7 @@ pub fn required_region_bounds(tcx: &ctxt, all_bounds: &mut Vec) { all_bounds.push_all(region_bounds.as_slice()); - if builtin_bounds.contains_elem(ty::BoundSend) { + if builtin_bounds.contains(&ty::BoundSend) { all_bounds.push(ty::ReStatic); } } @@ -4921,7 +4921,7 @@ pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { pub fn record_trait_implementation(tcx: &ctxt, trait_def_id: DefId, impl_def_id: DefId) { - match tcx.trait_impls.borrow().find(&trait_def_id) { + match tcx.trait_impls.borrow().get(&trait_def_id) { Some(impls_for_trait) => { impls_for_trait.borrow_mut().push(impl_def_id); return; @@ -5094,7 +5094,7 @@ pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option { /// Otherwise, return `None`. pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option { - let impl_item = match tcx.impl_or_trait_items.borrow().find(&def_id) { + let impl_item = match tcx.impl_or_trait_items.borrow().get(&def_id) { Some(m) => m.clone(), None => return None, }; @@ -5449,7 +5449,7 @@ impl<'tcx> mc::Typer<'tcx> for ty::ctxt<'tcx> { } fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option { - self.method_map.borrow().find(&method_call).map(|method| method.ty) + self.method_map.borrow().get(&method_call).map(|method| method.ty) } fn adjustments<'a>(&'a self) -> &'a RefCell> { @@ -5561,7 +5561,7 @@ pub type FreevarMap = NodeMap>; pub type CaptureModeMap = NodeMap; pub fn with_freevars(tcx: &ty::ctxt, fid: ast::NodeId, f: |&[Freevar]| -> T) -> T { - match tcx.freevars.borrow().find(&fid) { + match tcx.freevars.borrow().get(&fid) { None => f(&[]), Some(d) => f(d.as_slice()) } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 7c8d9309df3b..32fd385aa5d0 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -99,7 +99,7 @@ pub trait AstConv<'tcx> { pub fn ast_region_to_region(tcx: &ty::ctxt, lifetime: &ast::Lifetime) -> ty::Region { - let r = match tcx.named_region_map.find(&lifetime.id) { + let r = match tcx.named_region_map.get(&lifetime.id) { None => { // should have been recorded by the `resolve_lifetime` pass tcx.sess.span_bug(lifetime.span, "unresolved lifetime"); @@ -467,7 +467,7 @@ fn check_path_args(tcx: &ty::ctxt, pub fn ast_ty_to_prim_ty(tcx: &ty::ctxt, ast_ty: &ast::Ty) -> Option { match ast_ty.node { ast::TyPath(ref path, _, id) => { - let a_def = match tcx.def_map.borrow().find(&id) { + let a_def = match tcx.def_map.borrow().get(&id) { None => { tcx.sess.span_bug(ast_ty.span, format!("unbound path {}", @@ -524,7 +524,7 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( match ast_ty.node { ast::TyPath(ref path, _, id) => { - let a_def = match this.tcx().def_map.borrow().find(&id) { + let a_def = match this.tcx().def_map.borrow().get(&id) { None => { this.tcx() .sess @@ -675,7 +675,7 @@ fn mk_pointer<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( // Note that the "bounds must be empty if path is not a trait" // restriction is enforced in the below case for ty_path, which // will run after this as long as the path isn't a trait. - match tcx.def_map.borrow().find(&id) { + match tcx.def_map.borrow().get(&id) { Some(&def::DefPrimTy(ast::TyStr)) => { check_path_args(tcx, path, NO_TPS | NO_REGIONS); match ptr_ty { @@ -802,7 +802,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( let tcx = this.tcx(); let mut ast_ty_to_ty_cache = tcx.ast_ty_to_ty_cache.borrow_mut(); - match ast_ty_to_ty_cache.find(&ast_ty.id) { + match ast_ty_to_ty_cache.get(&ast_ty.id) { Some(&ty::atttce_resolved(ty)) => return ty, Some(&ty::atttce_unresolved) => { tcx.sess.span_fatal(ast_ty.span, @@ -900,7 +900,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( ty::mk_err() } ast::TyPath(ref path, ref bounds, id) => { - let a_def = match tcx.def_map.borrow().find(&id) { + let a_def = match tcx.def_map.borrow().get(&id) { None => { tcx.sess .span_bug(ast_ty.span, @@ -990,7 +990,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>( } } ast::TyQPath(ref qpath) => { - match tcx.def_map.borrow().find(&ast_ty.id) { + match tcx.def_map.borrow().get(&ast_ty.id) { None => { tcx.sess.span_bug(ast_ty.span, "unbound qualified path") @@ -1549,7 +1549,7 @@ pub fn partition_bounds<'a>(tcx: &ty::ctxt, ast::TraitTyParamBound(ref b) => { match lookup_def_tcx(tcx, b.path.span, b.ref_id) { def::DefTrait(trait_did) => { - match trait_def_ids.find(&trait_did) { + match trait_def_ids.get(&trait_did) { // Already seen this trait. We forbid // duplicates in the list (for some // reason). diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index a686a5e72a0a..7070f16da3bf 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -324,7 +324,7 @@ pub fn check_pat_struct(pcx: &pat_ctxt, pat: &ast::Pat, let item_substs = fcx .item_substs() - .find(&pat.id) + .get(&pat.id) .map(|substs| substs.substs.clone()) .unwrap_or_else(|| Substs::empty()); diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index f854bc52acd7..557b92d439d9 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -678,7 +678,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { debug!("push_extension_candidates(expr_id={})", expr_id); let mut duplicates = HashSet::new(); - let opt_applicable_traits = self.fcx.ccx.trait_map.find(&expr_id); + let opt_applicable_traits = self.fcx.ccx.trait_map.get(&expr_id); for applicable_traits in opt_applicable_traits.into_iter() { for &trait_did in applicable_traits.iter() { if duplicates.insert(trait_did) { @@ -912,7 +912,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { // metadata if necessary. ty::populate_implementations_for_type_if_necessary(self.tcx(), did); - for impl_infos in self.tcx().inherent_impls.borrow().find(&did).iter() { + for impl_infos in self.tcx().inherent_impls.borrow().get(&did).iter() { for impl_did in impl_infos.iter() { self.push_candidates_from_inherent_impl(*impl_did); } @@ -1627,7 +1627,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { .inh .adjustments .borrow() - .find(&expr.id) { + .get(&expr.id) { Some(&ty::AdjustDerefRef(ty::AutoDerefRef { autoderefs: autoderef_count, autoref: _ @@ -1658,7 +1658,7 @@ impl<'a, 'tcx> LookupContext<'a, 'tcx> { match expr.node { ast::ExprIndex(ref base_expr, _) => { let mut base_adjustment = - match self.fcx.inh.adjustments.borrow().find(&base_expr.id) { + match self.fcx.inh.adjustments.borrow().get(&base_expr.id) { Some(&ty::AdjustDerefRef(ref adr)) => (*adr).clone(), None => ty::AutoDerefRef { autoderefs: 0, autoref: None }, Some(_) => { @@ -1839,7 +1839,7 @@ fn impl_method(tcx: &ty::ctxt, -> Option> { let impl_items = tcx.impl_items.borrow(); - let impl_items = impl_items.find(&impl_def_id).unwrap(); + let impl_items = impl_items.get(&impl_def_id).unwrap(); impl_items .iter() .map(|&did| ty::impl_or_trait_item(tcx, did.def_id())) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index bcb875a6aa83..b83c81cd9863 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> mem_categorization::Typer<'tcx> for FnCtxt<'a, 'tcx> { } fn node_method_ty(&self, method_call: typeck::MethodCall) -> Option { - self.inh.method_map.borrow().find(&method_call).map(|m| m.ty) + self.inh.method_map.borrow().get(&method_call).map(|m| m.ty) } fn adjustments<'a>(&'a self) -> &'a RefCell> { &self.inh.adjustments @@ -1556,7 +1556,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> ty::t { - match self.inh.locals.borrow().find(&nid) { + match self.inh.locals.borrow().get(&nid) { Some(&t) => t, None => { self.tcx().sess.span_bug( @@ -1808,7 +1808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn expr_ty(&self, ex: &ast::Expr) -> ty::t { - match self.inh.node_types.borrow().find(&ex.id) { + match self.inh.node_types.borrow().get(&ex.id) { Some(&t) => t, None => { self.tcx().sess.bug(format!("no type for expr in fcx {}", @@ -1824,7 +1824,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { */ let adjustments = self.inh.adjustments.borrow(); - let adjustment = adjustments.find(&expr.id); + let adjustment = adjustments.get(&expr.id); self.adjust_expr_ty(expr, adjustment) } @@ -1845,12 +1845,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { raw_ty, adjustment, |method_call| self.inh.method_map.borrow() - .find(&method_call) + .get(&method_call) .map(|method| method.ty)) } pub fn node_ty(&self, id: ast::NodeId) -> ty::t { - match self.inh.node_types.borrow().find(&id) { + match self.inh.node_types.borrow().get(&id) { Some(&t) => t, None => { self.tcx().sess.bug( @@ -1868,7 +1868,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn opt_node_ty_substs(&self, id: ast::NodeId, f: |&ty::ItemSubsts|) { - match self.inh.item_substs.borrow().find(&id) { + match self.inh.item_substs.borrow().get(&id) { Some(s) => { f(s) } None => { } } @@ -3554,7 +3554,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, let (bounds, onceness) = match expr.node { ast::ExprProc(..) => { let mut bounds = ty::region_existential_bound(ty::ReStatic); - bounds.builtin_bounds.add(ty::BoundSend); // FIXME + bounds.builtin_bounds.insert(ty::BoundSend); // FIXME (bounds, ast::Once) } _ => { @@ -3763,7 +3763,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, for field in ast_fields.iter() { let mut expected_field_type = ty::mk_err(); - let pair = class_field_map.find(&field.ident.node.name).map(|x| *x); + let pair = class_field_map.get(&field.ident.node.name).map(|x| *x); match pair { None => { fcx.type_error_message( @@ -4422,7 +4422,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt, } ast::ExprStruct(ref path, ref fields, ref base_expr) => { // Resolve the path. - let def = tcx.def_map.borrow().find(&id).map(|i| *i); + let def = tcx.def_map.borrow().get(&id).map(|i| *i); let struct_id = match def { Some(def::DefVariant(enum_id, variant_id, true)) => { check_struct_enum_variant(fcx, id, expr.span, enum_id, @@ -5603,7 +5603,7 @@ pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool { (block_query(b, |e| { match e.node { ast::ExprBreak(Some(_)) => { - match cx.def_map.borrow().find(&e.id) { + match cx.def_map.borrow().get(&e.id) { Some(&def::DefLabel(loop_id)) if id == loop_id => true, _ => false, } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index acc3cf0307b9..014180a11553 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -327,7 +327,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { fn resolve_method_type(&self, method_call: MethodCall) -> Option { let method_ty = self.fcx.inh.method_map.borrow() - .find(&method_call).map(|method| method.ty); + .get(&method_call).map(|method| method.ty); method_ty.map(|method_ty| self.resolve_type(method_ty)) } @@ -339,7 +339,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { } else { let tcx = self.fcx.tcx(); ty::adjust_ty(tcx, expr.span, expr.id, ty_unadjusted, - self.fcx.inh.adjustments.borrow().find(&expr.id), + self.fcx.inh.adjustments.borrow().get(&expr.id), |method_call| self.resolve_method_type(method_call)) } } @@ -351,7 +351,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { // When we enter a function, we can derive let fn_sig_map = self.fcx.inh.fn_sig_map.borrow(); - let fn_sig = match fn_sig_map.find(&id) { + let fn_sig = match fn_sig_map.get(&id) { Some(f) => f, None => { self.tcx().sess.bug( @@ -370,7 +370,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { { debug!("visit_region_obligations: node_id={}", node_id); let region_obligations = self.fcx.inh.region_obligations.borrow(); - match region_obligations.find(&node_id) { + match region_obligations.get(&node_id) { None => { } Some(vec) => { for r_o in vec.iter() { @@ -594,7 +594,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { let has_method_map = rcx.fcx.inh.method_map.borrow().contains_key(&method_call); // Check any autoderefs or autorefs that appear. - for &adjustment in rcx.fcx.inh.adjustments.borrow().find(&expr.id).iter() { + for &adjustment in rcx.fcx.inh.adjustments.borrow().get(&expr.id).iter() { debug!("adjustment={}", adjustment); match *adjustment { ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, autoref: ref opt_autoref}) => { @@ -686,7 +686,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { ast::ExprUnary(ast::UnDeref, ref base) => { // For *a, the lifetime of a must enclose the deref let method_call = MethodCall::expr(expr.id); - let base_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) { + let base_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) { Some(method) => { constrain_call(rcx, expr, Some(&**base), None::.iter(), true); @@ -950,7 +950,7 @@ fn check_expr_fn_block(rcx: &mut Rcx, let raw_var_ty = rcx.resolve_node_type(var_node_id); let upvar_id = ty::UpvarId { var_id: var_node_id, closure_expr_id: expr.id }; - let var_ty = match rcx.fcx.inh.upvar_borrow_map.borrow().find(&upvar_id) { + let var_ty = match rcx.fcx.inh.upvar_borrow_map.borrow().get(&upvar_id) { Some(upvar_borrow) => { ty::mk_rptr(rcx.tcx(), upvar_borrow.region, @@ -1195,7 +1195,7 @@ fn constrain_autoderefs(rcx: &mut Rcx, i, derefs); let method_call = MethodCall::autoderef(deref_expr.id, i); - derefd_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) { + derefd_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) { Some(method) => { // Treat overloaded autoderefs as if an AutoRef adjustment // was applied on the base type, as that is always the case. @@ -1301,7 +1301,7 @@ fn type_of_node_must_outlive( // report errors later on in the writeback phase. let ty0 = rcx.resolve_node_type(id); let ty = ty::adjust_ty(tcx, origin.span(), id, ty0, - rcx.fcx.inh.adjustments.borrow().find(&id), + rcx.fcx.inh.adjustments.borrow().get(&id), |method_call| rcx.resolve_method_type(method_call)); debug!("constrain_regions_in_type_of_node(\ ty={}, ty0={}, id={}, minimum_lifetime={})", @@ -1582,7 +1582,7 @@ fn link_reborrowed_region(rcx: &Rcx, mc::NoteUpvarRef(ref upvar_id) => { let mut upvar_borrow_map = rcx.fcx.inh.upvar_borrow_map.borrow_mut(); - match upvar_borrow_map.find_mut(upvar_id) { + match upvar_borrow_map.get_mut(upvar_id) { Some(upvar_borrow) => { // Adjust mutability that we infer for the upvar // so it can accommodate being borrowed with @@ -1845,7 +1845,7 @@ fn link_upvar_borrow_kind_for_nested_closures(rcx: &mut Rcx, let mut upvar_borrow_map = rcx.fcx.inh.upvar_borrow_map.borrow_mut(); let inner_borrow = upvar_borrow_map.get_copy(&inner_upvar_id); - match upvar_borrow_map.find_mut(&outer_upvar_id) { + match upvar_borrow_map.get_mut(&outer_upvar_id) { Some(outer_borrow) => { adjust_upvar_borrow_kind(rcx, outer_upvar_id, outer_borrow, inner_borrow.kind); } diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index d011e807ce7d..cf78ef162198 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -263,7 +263,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) { - match self.fcx.inh.adjustments.borrow_mut().pop(&id) { + match self.fcx.inh.adjustments.borrow_mut().remove(&id) { None => { debug!("No adjustments for node {}", id); } @@ -275,7 +275,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // FIXME(eddyb) #2190 Allow only statically resolved // bare functions to coerce to a closure to avoid // constructing (slower) indirect call wrappers. - match self.tcx().def_map.borrow().find(&id) { + match self.tcx().def_map.borrow().get(&id) { Some(&def::DefFn(..)) | Some(&def::DefStaticMethod(..)) | Some(&def::DefVariant(..)) | @@ -320,7 +320,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { reason: ResolveReason, method_call: MethodCall) { // Resolve any method map entry - match self.fcx.inh.method_map.borrow_mut().pop(&method_call) { + match self.fcx.inh.method_map.borrow_mut().remove(&method_call) { Some(method) => { debug!("writeback::resolve_method_map_entry(call={}, entry={})", method_call, diff --git a/src/librustc/middle/typeck/coherence/mod.rs b/src/librustc/middle/typeck/coherence/mod.rs index ac18f53de046..19ff82469b51 100644 --- a/src/librustc/middle/typeck/coherence/mod.rs +++ b/src/librustc/middle/typeck/coherence/mod.rs @@ -294,7 +294,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { } fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) { - match self.inherent_impls.borrow().find(&base_def_id) { + match self.inherent_impls.borrow().get(&base_def_id) { Some(implementation_list) => { implementation_list.borrow_mut().push(impl_def_id); return; diff --git a/src/librustc/middle/typeck/coherence/overlap.rs b/src/librustc/middle/typeck/coherence/overlap.rs index ccfa31df8264..933c2c81ac26 100644 --- a/src/librustc/middle/typeck/coherence/overlap.rs +++ b/src/librustc/middle/typeck/coherence/overlap.rs @@ -114,7 +114,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { fn push_impls_of_trait(&self, trait_def_id: ast::DefId, out: &mut Vec) { - match self.tcx.trait_impls.borrow().find(&trait_def_id) { + match self.tcx.trait_impls.borrow().get(&trait_def_id) { Some(impls) => { out.push_all(impls.borrow().as_slice()); } None => { /* no impls */ } } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 0374a64261f0..d137e5536a5f 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -1243,7 +1243,7 @@ pub fn convert_struct(ccx: &CrateCtxt, let result = convert_field(ccx, &pty.generics, f, local_def(id)); if result.name != special_idents::unnamed_field.name { - let dup = match seen_fields.find(&result.name) { + let dup = match seen_fields.get(&result.name) { Some(prev_span) => { span_err!(tcx.sess, f.span, E0124, "field `{}` is already declared", @@ -1386,7 +1386,7 @@ fn get_trait_def(ccx: &CrateCtxt, trait_id: ast::DefId) -> Rc { pub fn trait_def_of_item(ccx: &CrateCtxt, it: &ast::Item) -> Rc { let def_id = local_def(it.id); let tcx = ccx.tcx; - match tcx.trait_defs.borrow().find(&def_id) { + match tcx.trait_defs.borrow().get(&def_id) { Some(def) => return def.clone(), _ => {} } @@ -1486,7 +1486,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item) -> ty::Polytype { let def_id = local_def(it.id); let tcx = ccx.tcx; - match tcx.tcache.borrow().find(&def_id) { + match tcx.tcache.borrow().get(&def_id) { Some(pty) => return pty.clone(), _ => {} } @@ -1528,7 +1528,7 @@ pub fn ty_of_item(ccx: &CrateCtxt, it: &ast::Item) return pty; } ast::ItemTy(ref t, ref generics) => { - match tcx.tcache.borrow_mut().find(&local_def(it.id)) { + match tcx.tcache.borrow_mut().get(&local_def(it.id)) { Some(pty) => return pty.clone(), None => { } } @@ -1933,7 +1933,7 @@ fn get_or_create_type_parameter_def<'tcx,AC>(this: &AC, -> ty::TypeParameterDef where AC: AstConv<'tcx> { - match this.tcx().ty_param_defs.borrow().find(¶m.id) { + match this.tcx().ty_param_defs.borrow().get(¶m.id) { Some(d) => { return (*d).clone(); } None => { } } @@ -2027,13 +2027,13 @@ fn check_bounds_compatible(tcx: &ty::ctxt, span: Span) { // Currently the only bound which is incompatible with other bounds is // Sized/Unsized. - if !param_bounds.builtin_bounds.contains_elem(ty::BoundSized) { + if !param_bounds.builtin_bounds.contains(&ty::BoundSized) { ty::each_bound_trait_and_supertraits( tcx, param_bounds.trait_bounds.as_slice(), |trait_ref| { let trait_def = ty::lookup_trait_def(tcx, trait_ref.def_id); - if trait_def.bounds.builtin_bounds.contains_elem(ty::BoundSized) { + if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) { span_err!(tcx.sess, span, E0129, "incompatible bounds on type parameter `{}`, \ bound `{}` does not allow unsized type", @@ -2136,7 +2136,7 @@ fn merge_param_bounds<'a>(tcx: &ty::ctxt, let predicate_param_id = tcx.def_map .borrow() - .find(&predicate.id) + .get(&predicate.id) .expect("compute_bounds(): resolve didn't resolve the type \ parameter identifier in a `where` clause") .def_id(); diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs index bfa0f94a7475..20c14580b3be 100644 --- a/src/librustc/middle/typeck/infer/error_reporting.rs +++ b/src/librustc/middle/typeck/infer/error_reporting.rs @@ -1240,7 +1240,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { ty_queue.push(&*mut_ty.ty); } ast::TyPath(ref path, ref bounds, id) => { - let a_def = match self.tcx.def_map.borrow().find(&id) { + let a_def = match self.tcx.def_map.borrow().get(&id) { None => { self.tcx .sess diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs index cdc45890c09e..70c4a245b2c2 100644 --- a/src/librustc/middle/typeck/infer/region_inference/mod.rs +++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs @@ -367,7 +367,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { debug!("RegionVarBindings: add_constraint({})", constraint.repr(self.tcx)); - if self.constraints.borrow_mut().insert(constraint, origin) { + if self.constraints.borrow_mut().insert(constraint, origin).is_none() { if self.in_snapshot() { self.undo_log.borrow_mut().push(AddConstraint(constraint)); } @@ -559,7 +559,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { new_r: Region|) -> Region { let vars = TwoRegions { a: a, b: b }; - match self.combine_map(t).borrow().find(&vars) { + match self.combine_map(t).borrow().get(&vars) { Some(&c) => { return ReInfer(ReVar(c)); } @@ -991,7 +991,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { debug!("expansion: constraint={} origin={}", constraint.repr(self.tcx), self.constraints.borrow() - .find(constraint) + .get(constraint) .unwrap() .repr(self.tcx)); match *constraint { @@ -1075,7 +1075,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { debug!("contraction: constraint={} origin={}", constraint.repr(self.tcx), self.constraints.borrow() - .find(constraint) + .get(constraint) .unwrap() .repr(self.tcx)); match *constraint { diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index f44fa1ac1c69..d2f315f2a4b6 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -113,7 +113,7 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> { // e.g., fn:Copy() <: fn(), because the former is a function // that only closes over copyable things, but the latter is // any function at all. - if a.contains(b) { + if a.is_superset(&b) { Ok(a) } else { Err(ty::terr_builtin_bounds(expected_found(self, a, b))) diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index 22898221d9b5..5ca0de47ad50 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -301,7 +301,7 @@ pub fn write_substs_to_tcx(tcx: &ty::ctxt, } } pub fn lookup_def_tcx(tcx:&ty::ctxt, sp: Span, id: ast::NodeId) -> def::Def { - match tcx.def_map.borrow().find(&id) { + match tcx.def_map.borrow().get(&id) { Some(x) => x.clone(), _ => { tcx.sess.span_fatal(sp, "internal error looking up a definition") diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs index 9a90381854a6..4227cc521b48 100644 --- a/src/librustc/middle/typeck/variance.rs +++ b/src/librustc/middle/typeck/variance.rs @@ -322,7 +322,7 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> { index: index, param_id: param_id, term: term }); - let newly_added = self.inferred_map.insert(param_id, inf_index); + let newly_added = self.inferred_map.insert(param_id, inf_index).is_none(); assert!(newly_added); debug!("add_inferred(item_id={}, \ @@ -376,7 +376,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> { if self.num_inferred() == inferreds_on_entry { let newly_added = self.tcx.item_variance_map.borrow_mut().insert( ast_util::local_def(item.id), - self.empty_variances.clone()); + self.empty_variances.clone()).is_none(); assert!(newly_added); } @@ -556,7 +556,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } fn inferred_index(&self, param_id: ast::NodeId) -> InferredIndex { - match self.terms_cx.inferred_map.find(¶m_id) { + match self.terms_cx.inferred_map.get(¶m_id) { Some(&index) => index, None => { self.tcx().sess.bug(format!( @@ -569,7 +569,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn find_binding_for_lifetime(&self, param_id: ast::NodeId) -> ast::NodeId { let tcx = self.terms_cx.tcx; assert!(is_lifetime(&tcx.map, param_id)); - match tcx.named_region_map.find(¶m_id) { + match tcx.named_region_map.get(¶m_id) { Some(&rl::DefEarlyBoundRegion(_, _, lifetime_decl_id)) => lifetime_decl_id, Some(_) => panic!("should not encounter non early-bound cases"), @@ -810,7 +810,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { ty::ty_param(ty::ParamTy { ref def_id, .. }) => { assert_eq!(def_id.krate, ast::LOCAL_CRATE); - match self.terms_cx.inferred_map.find(&def_id.node) { + match self.terms_cx.inferred_map.get(&def_id.node) { Some(&index) => { self.add_constraint(index, variance); } @@ -1060,7 +1060,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> { } let newly_added = tcx.item_variance_map.borrow_mut() - .insert(item_def_id, Rc::new(item_variances)); + .insert(item_def_id, Rc::new(item_variances)).is_none(); assert!(newly_added); } } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index cf807cb22bc2..577d92744e6d 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -139,7 +139,7 @@ pub fn can_reach,T:Eq+Clone+Hash>( let mut queue = vec!(source); let mut i = 0; while i < queue.len() { - match edges_map.find(&queue[i]) { + match edges_map.get(&queue[i]) { Some(edges) => { for target in edges.iter() { if *target == destination { @@ -200,7 +200,7 @@ pub fn memoized_with_key + Eq, U: Clone, S, H: Hasher>( k: |&T| -> K ) -> U { let key = k(&arg); - let result = cache.borrow().find(&key).map(|result| result.clone()); + let result = cache.borrow().get(&key).map(|result| result.clone()); match result { Some(result) => result, None => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 33e141975324..9080b12c5436 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -451,7 +451,7 @@ pub fn ty_to_string(cx: &ctxt, typ: t) -> String { ty_str => "str".to_string(), ty_unboxed_closure(ref did, _, ref substs) => { let unboxed_closures = cx.unboxed_closures.borrow(); - unboxed_closures.find(did).map(|cl| { + unboxed_closures.get(did).map(|cl| { closure_to_string(cx, &cl.closure_type.subst(cx, substs)) }).unwrap_or_else(|| "closure".to_string()) } @@ -1108,7 +1108,7 @@ impl UserString for ty::ParamBounds { impl UserString for ty::ExistentialBounds { fn user_string(&self, tcx: &ctxt) -> String { - if self.builtin_bounds.contains_elem(ty::BoundSend) && + if self.builtin_bounds.contains(&ty::BoundSend) && self.region_bound == ty::ReStatic { // Region bound is implied by builtin bounds: return self.builtin_bounds.repr(tcx); @@ -1277,7 +1277,7 @@ impl UserString for ParamTy { fn user_string(&self, tcx: &ctxt) -> String { let id = self.idx; let did = self.def_id; - let ident = match tcx.ty_param_defs.borrow().find(&did.node) { + let ident = match tcx.ty_param_defs.borrow().get(&did.node) { Some(def) => token::get_name(def.name).get().to_string(), // This can only happen when a type mismatch error happens and diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index d87d8776d4a6..545eeaf7406f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -45,7 +45,7 @@ pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option) Some(tcx) => tcx, None => return None, }; - let def = match tcx.def_map.borrow().find(&id) { + let def = match tcx.def_map.borrow().get(&id) { Some(def) => *def, None => return None, }; @@ -223,7 +223,7 @@ fn build_impls(cx: &DocContext, tcx: &ty::ctxt, ty::populate_implementations_for_type_if_necessary(tcx, did); let mut impls = Vec::new(); - match tcx.inherent_impls.borrow().find(&did) { + match tcx.inherent_impls.borrow().get(&did) { None => {} Some(i) => { impls.extend(i.iter().map(|&did| { build_impl(cx, tcx, did) })); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f96b3916f06d..bd6c696ad746 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1395,7 +1395,7 @@ impl Clean for ty::field_ty { let (name, attrs) = if self.name == unnamed_field.name { (None, None) } else { - (Some(self.name), Some(attr_map.find(&self.id.node).unwrap())) + (Some(self.name), Some(attr_map.get(&self.id.node).unwrap())) }; let ty = ty::lookup_item_type(cx.tcx(), self.id); @@ -2090,7 +2090,7 @@ fn resolve_type(cx: &DocContext, path: Path, None => return Primitive(Bool), }; debug!("searching for {} in defmap", id); - let def = match tcx.def_map.borrow().find(&id) { + let def = match tcx.def_map.borrow().get(&id) { Some(&k) => k, None => panic!("unresolved id not in defmap") }; @@ -2159,7 +2159,7 @@ fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSou fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option { cx.tcx_opt().and_then(|tcx| { - tcx.def_map.borrow().find(&id).map(|&def| register_def(cx, def)) + tcx.def_map.borrow().get(&id).map(|&def| register_def(cx, def)) }) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f9177c8d6157..320f84adea7a 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -208,7 +208,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path, } }, |cache| { - match cache.paths.find(&did) { + match cache.paths.get(&did) { None => None, Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty)) } @@ -313,7 +313,7 @@ fn primitive_link(f: &mut fmt::Formatter, name: &str) -> fmt::Result { let m = cache_key.get().unwrap(); let mut needs_termination = false; - match m.primitive_locations.find(&prim) { + match m.primitive_locations.get(&prim) { Some(&ast::LOCAL_CRATE) => { let loc = current_location_key.get().unwrap(); let len = if loc.len() == 0 {0} else {loc.len() - 1}; diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 3f1590773aa7..9dacee1652a4 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -242,7 +242,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { // Make sure our hyphenated ID is unique for this page let map = used_header_map.get().unwrap(); - let id = match map.borrow_mut().find_mut(&id) { + let id = match map.borrow_mut().get_mut(&id) { None => id, Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) } }; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 9af2b22adea4..fbd2611acb92 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -389,7 +389,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult // has since been learned. for &(pid, ref item) in orphan_methods.iter() { let did = ast_util::local_def(pid); - match paths.find(&did) { + match paths.get(&did) { Some(&(ref fqp, _)) => { search_index.push(IndexItem { ty: shortty(item), @@ -443,7 +443,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult item.desc.to_json().to_string())); match item.parent { Some(nodeid) => { - let pathid = *nodeid_to_pathid.find(&nodeid).unwrap(); + let pathid = *nodeid_to_pathid.get(&nodeid).unwrap(); try!(write!(&mut w, ",{}", pathid)); } None => {} @@ -454,7 +454,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::IoResult try!(write!(&mut w, r#"],"paths":["#)); for (i, &did) in pathid_to_nodeid.iter().enumerate() { - let &(ref fqp, short) = cache.paths.find(&did).unwrap(); + let &(ref fqp, short) = cache.paths.get(&did).unwrap(); if i > 0 { try!(write!(&mut w, ",")); } @@ -543,7 +543,7 @@ fn write_shared(cx: &Context, // // FIXME: this is a vague explanation for why this can't be a `get`, in // theory it should be... - let &(ref remote_path, remote_item_type) = match cache.paths.find(&did) { + let &(ref remote_path, remote_item_type) = match cache.paths.get(&did) { Some(p) => p, None => continue, }; @@ -838,7 +838,7 @@ impl DocFolder for Cache { } else { let last = self.parent_stack.last().unwrap(); let did = *last; - let path = match self.paths.find(&did) { + let path = match self.paths.get(&did) { Some(&(_, item_type::Trait)) => Some(self.stack[..self.stack.len() - 1]), // The current stack not necessarily has correlation for @@ -1170,7 +1170,7 @@ impl Context { &Item{ cx: cx, item: it })); } else { let mut url = "../".repeat(cx.current.len()); - match cache_key.get().unwrap().paths.find(&it.def_id) { + match cache_key.get().unwrap().paths.get(&it.def_id) { Some(&(ref names, _)) => { for name in names[..names.len() - 1].iter() { url.push_str(name.as_slice()); @@ -1735,7 +1735,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,

Implementors

    ")); - match cache.implementors.find(&it.def_id) { + match cache.implementors.get(&it.def_id) { Some(implementors) => { for i in implementors.iter() { try!(writeln!(w, "
  • {}impl{} {} for {}{}
  • ", @@ -1992,7 +1992,7 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item, } fn render_methods(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { - match cache_key.get().unwrap().impls.find(&it.def_id) { + match cache_key.get().unwrap().impls.get(&it.def_id) { Some(v) => { let (non_trait, traits) = v.partitioned(|i| i.impl_.trait_.is_none()); if non_trait.len() > 0 { @@ -2080,7 +2080,7 @@ fn render_impl(w: &mut fmt::Formatter, i: &Impl) -> fmt::Result { match i.impl_.trait_ { Some(clean::ResolvedPath { did, .. }) => { try!({ - match cache_key.get().unwrap().traits.find(&did) { + match cache_key.get().unwrap().traits.get(&did) { Some(t) => try!(render_default_methods(w, t, &i.impl_)), None => {} } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bd3c618a5ed4..5e2f56e00fc0 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -417,7 +417,7 @@ fn json_input(input: &str) -> Result { Ok(json::Object(obj)) => { let mut obj = obj; // Make sure the schema is what we expect - match obj.pop(&"schema".to_string()) { + match obj.remove(&"schema".to_string()) { Some(json::String(version)) => { if version.as_slice() != SCHEMA_VERSION { return Err(format!( @@ -428,7 +428,7 @@ fn json_input(input: &str) -> Result { Some(..) => return Err("malformed json".to_string()), None => return Err("expected a schema version".to_string()), } - let krate = match obj.pop(&"crate".to_string()) { + let krate = match obj.remove(&"crate".to_string()) { Some(json) => { let mut d = json::Decoder::new(json); Decodable::decode(&mut d).unwrap() diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs index 7129f1472091..4a16bcf939e7 100644 --- a/src/librustrt/local_data.rs +++ b/src/librustrt/local_data.rs @@ -186,7 +186,7 @@ impl KeyValue { // The following match takes a mutable borrow on the map. In order to insert // our data if the key isn't present, we need to let the match end first. - let data = match (map.find_mut(&keyval), data) { + let data = match (map.get_mut(&keyval), data) { (None, Some(data)) => { // The key doesn't exist and we need to insert it. To make borrowck // happy, return it up a scope and insert it there. @@ -266,7 +266,7 @@ impl KeyValue { }; let keyval = key_to_key_value(self); - match map.find(&keyval) { + match map.get(&keyval) { Some(slot) => { let value_box = slot.box_ptr as *mut TLDValueBox; if unsafe { *(*value_box).refcount.get() } >= 1 { diff --git a/src/libserialize/collection_impls.rs b/src/libserialize/collection_impls.rs index 79166935a5e7..d2d1f5fa8b09 100644 --- a/src/libserialize/collection_impls.rs +++ b/src/libserialize/collection_impls.rs @@ -39,7 +39,7 @@ impl,T:Decodable> Decodable for DList { d.read_seq(|d, len| { let mut list = DList::new(); for i in range(0u, len) { - list.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + list.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } Ok(list) }) @@ -66,7 +66,7 @@ impl,T:Decodable> Decodable for RingBuf { d.read_seq(|d, len| { let mut deque: RingBuf = RingBuf::new(); for i in range(0u, len) { - deque.push(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); + deque.push_back(try!(d.read_seq_elt(i, |d| Decodable::decode(d)))); } Ok(deque) }) @@ -165,10 +165,10 @@ impl< > Decodable for EnumSet { fn decode(d: &mut D) -> Result, E> { let bits = try!(d.read_uint()); - let mut set = EnumSet::empty(); + let mut set = EnumSet::new(); for bit in range(0, uint::BITS) { if bits & (1 << bit) != 0 { - set.add(CLike::from_uint(1 << bit)); + set.insert(CLike::from_uint(1 << bit)); } } Ok(set) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index dbdfa17bfc22..9f40cd2d277e 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2113,7 +2113,7 @@ impl ::Decoder for Decoder { let name = match self.pop() { String(s) => s, Object(mut o) => { - let n = match o.pop(&"variant".to_string()) { + let n = match o.remove(&"variant".to_string()) { Some(String(s)) => s, Some(val) => { return Err(ExpectedError("String".to_string(), format!("{}", val))) @@ -2122,7 +2122,7 @@ impl ::Decoder for Decoder { return Err(MissingFieldError("variant".to_string())) } }; - match o.pop(&"fields".to_string()) { + match o.remove(&"fields".to_string()) { Some(List(l)) => { for field in l.into_iter().rev() { self.stack.push(field); @@ -2192,7 +2192,7 @@ impl ::Decoder for Decoder { debug!("read_struct_field(name={}, idx={})", name, idx); let mut obj = try!(expect!(self.pop(), Object)); - let value = match obj.pop(&name.to_string()) { + let value = match obj.remove(&name.to_string()) { None => { // Add a Null and try to parse it as an Option<_> // to get None as a default value. @@ -3072,8 +3072,8 @@ mod tests { \"fields\":[\"Henry\", 349]}}"; let mut map: TreeMap = super::decode(s).unwrap(); - assert_eq!(map.pop(&"a".to_string()), Some(Dog)); - assert_eq!(map.pop(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); + assert_eq!(map.remove(&"a".to_string()), Some(Dog)); + assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349))); } #[test] diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index ebf541a63daf..0e75e4610abf 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -627,7 +627,7 @@ pub trait Reader { /// as `Err(IoError)`. See `read()` for more details. fn push(&mut self, len: uint, buf: &mut Vec) -> IoResult { let start_len = buf.len(); - buf.reserve_additional(len); + buf.reserve(len); let n = { let s = unsafe { slice_vec_capacity(buf, start_len, start_len + len) }; @@ -658,7 +658,7 @@ pub trait Reader { } let start_len = buf.len(); - buf.reserve_additional(len); + buf.reserve(len); // we can't just use self.read_at_least(min, slice) because we need to push // successful reads onto the vector before any returned errors. diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs index 493e1b559d7b..698e0a3460f2 100644 --- a/src/libstd/io/process.rs +++ b/src/libstd/io/process.rs @@ -1137,7 +1137,7 @@ mod tests { cmd.env("path", "foo"); cmd.env("Path", "bar"); let env = &cmd.env.unwrap(); - let val = env.find(&EnvKey("PATH".to_c_str())); + let val = env.get(&EnvKey("PATH".to_c_str())); assert!(val.unwrap() == &"bar".to_c_str()); } } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index d9d549f68412..d077fbd7bf00 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -63,7 +63,7 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt, () }); with_used_diagnostics(|diagnostics| { - match diagnostics.swap(code.name, span) { + match diagnostics.insert(code.name, span) { Some(previous_span) => { ecx.span_warn(span, format!( "diagnostic code {} already used", token::get_ident(code).get() @@ -93,7 +93,7 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt, _ => unreachable!() }; with_registered_diagnostics(|diagnostics| { - if !diagnostics.insert(code.name, description) { + if diagnostics.insert(code.name, description).is_some() { ecx.span_err(span, format!( "diagnostic code {} already registered", token::get_ident(*code).get() ).as_slice()); diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 152b89b86e7a..5401da8cd053 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -768,7 +768,7 @@ impl SyntaxEnv { pub fn find(&self, k: &Name) -> Option> { for frame in self.chain.iter().rev() { - match frame.map.find(k) { + match frame.map.get(k) { Some(v) => return Some(v.clone()), None => {} } diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 486ce910e2b6..a28f24e76635 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -252,7 +252,7 @@ impl<'a, 'b> Context<'a, 'b> { } Named(name) => { - let span = match self.names.find(&name) { + let span = match self.names.get(&name) { Some(e) => e.span, None => { let msg = format!("there is no argument named `{}`", name); @@ -260,7 +260,7 @@ impl<'a, 'b> Context<'a, 'b> { return; } }; - self.verify_same(span, &ty, self.name_types.find(&name)); + self.verify_same(span, &ty, self.name_types.get(&name)); if !self.name_types.contains_key(&name) { self.name_types.insert(name.clone(), ty); } @@ -555,11 +555,11 @@ impl<'a, 'b> Context<'a, 'b> { heads.push(self.ecx.expr_addr_of(e.span, e)); } for name in self.name_ordering.iter() { - let e = match self.names.pop(name) { + let e = match self.names.remove(name) { Some(e) => e, None => continue }; - let arg_ty = match self.name_types.find(name) { + let arg_ty = match self.name_types.get(name) { Some(ty) => ty, None => continue }; diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index bebe16286c97..15fe7fc42b27 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -182,7 +182,7 @@ fn resolve_internal(id: Ident, resolve_table: &mut ResolveTable) -> Name { let key = (id.name, id.ctxt); - match resolve_table.find(&key) { + match resolve_table.get(&key) { Some(&name) => return name, None => {} } diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index e6c98a9e3d09..bc6d6d7a5216 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -45,7 +45,7 @@ impl Interner { pub fn intern(&self, val: T) -> Name { let mut map = self.map.borrow_mut(); - match (*map).find(&val) { + match (*map).get(&val) { Some(&idx) => return idx, None => (), } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 74bead9e5f2d..4d6aefb2a178 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1209,7 +1209,7 @@ impl MetricMap { let MetricMap(ref selfmap) = *self; let MetricMap(ref old) = *old; for (k, vold) in old.iter() { - let r = match selfmap.find(k) { + let r = match selfmap.get(k) { None => MetricRemoved, Some(v) => { let delta = v.value - vold.value; @@ -1678,31 +1678,31 @@ mod tests { let diff1 = m2.compare_to_old(&m1, None); - assert_eq!(*(diff1.find(&"in-both-noise".to_string()).unwrap()), LikelyNoise); - assert_eq!(*(diff1.find(&"in-first-noise".to_string()).unwrap()), MetricRemoved); - assert_eq!(*(diff1.find(&"in-second-noise".to_string()).unwrap()), MetricAdded); - assert_eq!(*(diff1.find(&"in-both-want-downwards-but-regressed".to_string()).unwrap()), + assert_eq!(*(diff1.get(&"in-both-noise".to_string()).unwrap()), LikelyNoise); + assert_eq!(*(diff1.get(&"in-first-noise".to_string()).unwrap()), MetricRemoved); + assert_eq!(*(diff1.get(&"in-second-noise".to_string()).unwrap()), MetricAdded); + assert_eq!(*(diff1.get(&"in-both-want-downwards-but-regressed".to_string()).unwrap()), Regression(100.0)); - assert_eq!(*(diff1.find(&"in-both-want-downwards-and-improved".to_string()).unwrap()), + assert_eq!(*(diff1.get(&"in-both-want-downwards-and-improved".to_string()).unwrap()), Improvement(50.0)); - assert_eq!(*(diff1.find(&"in-both-want-upwards-but-regressed".to_string()).unwrap()), + assert_eq!(*(diff1.get(&"in-both-want-upwards-but-regressed".to_string()).unwrap()), Regression(50.0)); - assert_eq!(*(diff1.find(&"in-both-want-upwards-and-improved".to_string()).unwrap()), + assert_eq!(*(diff1.get(&"in-both-want-upwards-and-improved".to_string()).unwrap()), Improvement(100.0)); assert_eq!(diff1.len(), 7); let diff2 = m2.compare_to_old(&m1, Some(200.0)); - assert_eq!(*(diff2.find(&"in-both-noise".to_string()).unwrap()), LikelyNoise); - assert_eq!(*(diff2.find(&"in-first-noise".to_string()).unwrap()), MetricRemoved); - assert_eq!(*(diff2.find(&"in-second-noise".to_string()).unwrap()), MetricAdded); - assert_eq!(*(diff2.find(&"in-both-want-downwards-but-regressed".to_string()).unwrap()), + assert_eq!(*(diff2.get(&"in-both-noise".to_string()).unwrap()), LikelyNoise); + assert_eq!(*(diff2.get(&"in-first-noise".to_string()).unwrap()), MetricRemoved); + assert_eq!(*(diff2.get(&"in-second-noise".to_string()).unwrap()), MetricAdded); + assert_eq!(*(diff2.get(&"in-both-want-downwards-but-regressed".to_string()).unwrap()), LikelyNoise); - assert_eq!(*(diff2.find(&"in-both-want-downwards-and-improved".to_string()).unwrap()), + assert_eq!(*(diff2.get(&"in-both-want-downwards-and-improved".to_string()).unwrap()), LikelyNoise); - assert_eq!(*(diff2.find(&"in-both-want-upwards-but-regressed".to_string()).unwrap()), + assert_eq!(*(diff2.get(&"in-both-want-upwards-but-regressed".to_string()).unwrap()), LikelyNoise); - assert_eq!(*(diff2.find(&"in-both-want-upwards-and-improved".to_string()).unwrap()), + assert_eq!(*(diff2.get(&"in-both-want-upwards-and-improved".to_string()).unwrap()), LikelyNoise); assert_eq!(diff2.len(), 7); } @@ -1727,29 +1727,29 @@ mod tests { let (diff1, ok1) = m2.ratchet(&pth, None); assert_eq!(ok1, false); assert_eq!(diff1.len(), 2); - assert_eq!(*(diff1.find(&"runtime".to_string()).unwrap()), Regression(10.0)); - assert_eq!(*(diff1.find(&"throughput".to_string()).unwrap()), LikelyNoise); + assert_eq!(*(diff1.get(&"runtime".to_string()).unwrap()), Regression(10.0)); + assert_eq!(*(diff1.get(&"throughput".to_string()).unwrap()), LikelyNoise); // Check that it was not rewritten. let m3 = MetricMap::load(&pth); let MetricMap(m3) = m3; assert_eq!(m3.len(), 2); - assert_eq!(*(m3.find(&"runtime".to_string()).unwrap()), Metric::new(1000.0, 2.0)); - assert_eq!(*(m3.find(&"throughput".to_string()).unwrap()), Metric::new(50.0, 2.0)); + assert_eq!(*(m3.get(&"runtime".to_string()).unwrap()), Metric::new(1000.0, 2.0)); + assert_eq!(*(m3.get(&"throughput".to_string()).unwrap()), Metric::new(50.0, 2.0)); // Ask for a ratchet with an explicit noise-percentage override, // that should advance. let (diff2, ok2) = m2.ratchet(&pth, Some(10.0)); assert_eq!(ok2, true); assert_eq!(diff2.len(), 2); - assert_eq!(*(diff2.find(&"runtime".to_string()).unwrap()), LikelyNoise); - assert_eq!(*(diff2.find(&"throughput".to_string()).unwrap()), LikelyNoise); + assert_eq!(*(diff2.get(&"runtime".to_string()).unwrap()), LikelyNoise); + assert_eq!(*(diff2.get(&"throughput".to_string()).unwrap()), LikelyNoise); // Check that it was rewritten. let m4 = MetricMap::load(&pth); let MetricMap(m4) = m4; assert_eq!(m4.len(), 2); - assert_eq!(*(m4.find(&"runtime".to_string()).unwrap()), Metric::new(1100.0, 2.0)); - assert_eq!(*(m4.find(&"throughput".to_string()).unwrap()), Metric::new(50.0, 2.0)); + assert_eq!(*(m4.get(&"runtime".to_string()).unwrap()), Metric::new(1100.0, 2.0)); + assert_eq!(*(m4.get(&"throughput".to_string()).unwrap()), Metric::new(50.0, 2.0)); } } diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs index 3933a33446d6..ac6104cc38b0 100644 --- a/src/test/bench/core-map.rs +++ b/src/test/bench/core-map.rs @@ -30,18 +30,18 @@ trait MutableMap { impl MutableMap for TreeMap { fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } - fn remove(&mut self, k: &uint) -> bool { self.remove(k) } - fn find(&self, k: &uint) -> Option<&uint> { self.find(k) } + fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() } + fn find(&self, k: &uint) -> Option<&uint> { self.get(k) } } impl MutableMap for HashMap { fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } - fn remove(&mut self, k: &uint) -> bool { self.remove(k) } - fn find(&self, k: &uint) -> Option<&uint> { self.find(k) } + fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() } + fn find(&self, k: &uint) -> Option<&uint> { self.get(k) } } impl MutableMap for TrieMap { fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); } - fn remove(&mut self, k: &uint) -> bool { self.remove(k) } - fn find(&self, k: &uint) -> Option<&uint> { self.find(k) } + fn remove(&mut self, k: &uint) -> bool { self.remove(k).is_some() } + fn find(&self, k: &uint) -> Option<&uint> { self.get(k) } } fn ascending(map: &mut M, n_keys: uint) { diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index abcd9f903334..191f70ac4921 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -197,8 +197,8 @@ fn rendezvous(nn: uint, set: Vec) { creatures_met += 2; - to_creature.get_mut(fst_creature.name).send(snd_creature); - to_creature.get_mut(snd_creature.name).send(fst_creature); + to_creature[fst_creature.name].send(snd_creature); + to_creature[snd_creature.name].send(fst_creature); } // tell each creature to stop diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs index e151369ff38a..0a3370fa487e 100644 --- a/src/test/bench/shootout-fasta-redux.rs +++ b/src/test/bench/shootout-fasta-redux.rs @@ -100,7 +100,7 @@ fn sum_and_scale(a: &'static [AminoAcid]) -> Vec { result.push(a_i); } let result_len = result.len(); - result.get_mut(result_len - 1).p = LOOKUP_SCALE; + result[result_len - 1].p = LOOKUP_SCALE; result } diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index d0e6aacdbb2a..6ada34a5a584 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -171,13 +171,13 @@ impl Table { next: None, }; c.f(&mut *entry); - *self.items.get_mut(index as uint) = Some(entry); + self.items[index as uint] = Some(entry); return; } } { - let entry = self.items.get_mut(index as uint).as_mut().unwrap(); + let entry = self.items[index as uint].as_mut().unwrap(); if entry.code == key { c.f(&mut **entry); return; diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index 47e1969172d2..d8df3eea83b0 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -194,7 +194,7 @@ fn is_board_unfeasible(board: u64, masks: &Vec>>) -> bool { fn filter_masks(masks: &mut Vec>>) { for i in range(0, masks.len()) { for j in range(0, (*masks)[i].len()) { - *masks.get_mut(i).get_mut(j) = + masks[i][j] = (*masks)[i][j].iter().map(|&m| m) .filter(|&m| !is_board_unfeasible(m, masks)) .collect(); @@ -217,7 +217,7 @@ fn to_vec(raw_sol: &List) -> Vec { let id = '0' as u8 + get_id(m); for i in range(0u, 50) { if m & 1 << i != 0 { - *sol.get_mut(i) = id; + sol[i] = id; } } } diff --git a/src/test/bench/shootout-regex-dna.rs b/src/test/bench/shootout-regex-dna.rs index dccdafe9cf83..81de7a126906 100644 --- a/src/test/bench/shootout-regex-dna.rs +++ b/src/test/bench/shootout-regex-dna.rs @@ -114,7 +114,7 @@ fn main() { } for (i, variant) in variant_strs.iter().enumerate() { - println!("{} {}", variant, counts.get_mut(i).get()); + println!("{} {}", variant, counts[i].get()); } println!(""); println!("{}", ilen); diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 5ce1b2fc40d0..d7d8e94c8a7d 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -112,14 +112,15 @@ fn read_to_end(r: &mut R) -> IoResult> { let mut vec = Vec::with_capacity(CHUNK); loop { // workaround: very fast growing - if vec.capacity() - vec.len() < CHUNK { + let len = vec.len(); + if vec.capacity() - len < CHUNK { let cap = vec.capacity(); let mult = if cap < 256 * 1024 * 1024 { 16 } else { 2 }; - vec.reserve_exact(mult * cap); + vec.reserve_exact(mult * cap - len); } match r.push_at_least(1, CHUNK, &mut vec) { Ok(_) => {} diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index ae7594ea8a20..54824d7259fa 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -79,7 +79,7 @@ impl Sudoku { if comps.len() == 3u { let row = from_str::(comps[0]).unwrap() as u8; let col = from_str::(comps[1]).unwrap() as u8; - *g.get_mut(row as uint).get_mut(col as uint) = + g[row as uint][col as uint] = from_str::(comps[2]).unwrap() as u8; } else { @@ -139,10 +139,10 @@ impl Sudoku { // find first remaining color that is available let next = avail.next(); - *self.grid.get_mut(row as uint).get_mut(col as uint) = next; + self.grid[row as uint][col as uint] = next; return 0u8 != next; } - *self.grid.get_mut(row as uint).get_mut(col as uint) = 0u8; + self.grid[row as uint][col as uint] = 0u8; return false; } diff --git a/src/test/compile-fail/borrowck-assign-comp-idx.rs b/src/test/compile-fail/borrowck-assign-comp-idx.rs index 5bc2edba3013..e14911d3508d 100644 --- a/src/test/compile-fail/borrowck-assign-comp-idx.rs +++ b/src/test/compile-fail/borrowck-assign-comp-idx.rs @@ -19,7 +19,7 @@ fn a() { // Create an immutable pointer into p's contents: let q: &int = &p[0]; - *p.get_mut(0) = 5; //~ ERROR cannot borrow + p[0] = 5; //~ ERROR cannot borrow println!("{}", *q); } @@ -34,7 +34,7 @@ fn b() { borrow( p.as_slice(), - || *p.get_mut(0) = 5); //~ ERROR cannot borrow `p` as mutable + || p[0] = 5); //~ ERROR cannot borrow `p` as mutable } fn c() { @@ -42,7 +42,7 @@ fn c() { // modification: let mut p = vec!(1); borrow(p.as_slice(), ||{}); - *p.get_mut(0) = 5; + p[0] = 5; } fn main() { diff --git a/src/test/compile-fail/borrowck-for-loop-head-linkage.rs b/src/test/compile-fail/borrowck-for-loop-head-linkage.rs index cdfb384d47ca..d71281058920 100644 --- a/src/test/compile-fail/borrowck-for-loop-head-linkage.rs +++ b/src/test/compile-fail/borrowck-for-loop-head-linkage.rs @@ -13,7 +13,7 @@ fn main() { for &x in vector.iter() { let cap = vector.capacity(); vector.grow(cap, 0u); //~ ERROR cannot borrow - *vector.get_mut(1u) = 5u; //~ ERROR cannot borrow + vector[1u] = 5u; //~ ERROR cannot borrow } } diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs index 31b5c44df666..200d208d140b 100644 --- a/src/test/compile-fail/borrowck-loan-vec-content.rs +++ b/src/test/compile-fail/borrowck-loan-vec-content.rs @@ -26,7 +26,7 @@ fn has_mut_vec_but_tries_to_change_it() { takes_imm_elt( &v[0], || { //~ ERROR cannot borrow `v` as mutable - *v.get_mut(1) = 4; + v[1] = 4; }) } diff --git a/src/test/run-pass/foreach-nested.rs b/src/test/run-pass/foreach-nested.rs index af6ca3c93d5c..2a54f22ee665 100644 --- a/src/test/run-pass/foreach-nested.rs +++ b/src/test/run-pass/foreach-nested.rs @@ -15,7 +15,7 @@ pub fn main() { let mut a: Vec = vec!(-1, -1, -1, -1); let mut p: int = 0; two(|i| { - two(|j| { *a.get_mut(p as uint) = 10 * i + j; p += 1; }) + two(|j| { a[p as uint] = 10 * i + j; p += 1; }) }); assert_eq!(a[0], 0); assert_eq!(a[1], 1); diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs index 87afd1601f6b..4a6a6782fb3d 100644 --- a/src/test/run-pass/hashmap-memory.rs +++ b/src/test/run-pass/hashmap-memory.rs @@ -83,7 +83,7 @@ mod map_reduce { mapper_done => { num_mappers -= 1; } find_reducer(k, cc) => { let mut c; - match reducers.find(&str::from_utf8( + match reducers.get(&str::from_utf8( k.as_slice()).unwrap().to_string()) { Some(&_c) => { c = _c; } None => { c = 0; } diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs index 84f303de7057..4e330b9a0e7d 100644 --- a/src/test/run-pass/issue-3563-3.rs +++ b/src/test/run-pass/issue-3563-3.rs @@ -86,8 +86,8 @@ impl AsciiArt { // element is: // 1) potentially large // 2) needs to be modified - let row = self.lines.get_mut(v); - *row.get_mut(h) = self.fill; + let row = &mut self.lines[v]; + row[h] = self.fill; } } } diff --git a/src/test/run-pass/issue-3991.rs b/src/test/run-pass/issue-3991.rs index da22da31d5b5..37144fb9cce7 100644 --- a/src/test/run-pass/issue-3991.rs +++ b/src/test/run-pass/issue-3991.rs @@ -15,7 +15,7 @@ struct HasNested { impl HasNested { fn method_push_local(&mut self) { - self.nest.get_mut(0).push(0); + self.nest[0].push(0); } } diff --git a/src/test/run-pass/overloaded-deref.rs b/src/test/run-pass/overloaded-deref.rs index b63db29cf916..ca820830f023 100644 --- a/src/test/run-pass/overloaded-deref.rs +++ b/src/test/run-pass/overloaded-deref.rs @@ -44,8 +44,8 @@ pub fn main() { assert_eq!(*(*p).borrow(), Point {x: 3, y: 5}); let v = Rc::new(RefCell::new(vec!(1i, 2, 3))); - *(*(*v).borrow_mut()).get_mut(0) = 3; - *(*(*v).borrow_mut()).get_mut(1) += 3; + (*(*v).borrow_mut())[0] = 3; + (*(*v).borrow_mut())[1] += 3; assert_eq!(((*(*v).borrow())[0], (*(*v).borrow())[1], (*(*v).borrow())[2]), (3, 5, 3)); diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs index 1edce811bcb2..55003a07b5bb 100644 --- a/src/test/run-pass/send_str_hashmap.rs +++ b/src/test/run-pass/send_str_hashmap.rs @@ -16,37 +16,37 @@ use std::option::Some; pub fn main() { let mut map: HashMap = HashMap::new(); - assert!(map.insert(Slice("foo"), 42)); - assert!(!map.insert(Owned("foo".to_string()), 42)); - assert!(!map.insert(Slice("foo"), 42)); - assert!(!map.insert(Owned("foo".to_string()), 42)); + assert!(map.insert(Slice("foo"), 42).is_none()); + assert!(map.insert(Owned("foo".to_string()), 42).is_some()); + assert!(map.insert(Slice("foo"), 42).is_some()); + assert!(map.insert(Owned("foo".to_string()), 42).is_some()); - assert!(!map.insert(Slice("foo"), 43)); - assert!(!map.insert(Owned("foo".to_string()), 44)); - assert!(!map.insert(Slice("foo"), 45)); - assert!(!map.insert(Owned("foo".to_string()), 46)); + assert!(map.insert(Slice("foo"), 43).is_some()); + assert!(map.insert(Owned("foo".to_string()), 44).is_some()); + assert!(map.insert(Slice("foo"), 45).is_some()); + assert!(map.insert(Owned("foo".to_string()), 46).is_some()); let v = 46; - assert_eq!(map.find(&Owned("foo".to_string())), Some(&v)); - assert_eq!(map.find(&Slice("foo")), Some(&v)); + assert_eq!(map.get(&Owned("foo".to_string())), Some(&v)); + assert_eq!(map.get(&Slice("foo")), Some(&v)); let (a, b, c, d) = (50, 51, 52, 53); - assert!(map.insert(Slice("abc"), a)); - assert!(map.insert(Owned("bcd".to_string()), b)); - assert!(map.insert(Slice("cde"), c)); - assert!(map.insert(Owned("def".to_string()), d)); + assert!(map.insert(Slice("abc"), a).is_none()); + assert!(map.insert(Owned("bcd".to_string()), b).is_none()); + assert!(map.insert(Slice("cde"), c).is_none()); + assert!(map.insert(Owned("def".to_string()), d).is_none()); - assert!(!map.insert(Slice("abc"), a)); - assert!(!map.insert(Owned("bcd".to_string()), b)); - assert!(!map.insert(Slice("cde"), c)); - assert!(!map.insert(Owned("def".to_string()), d)); + assert!(map.insert(Slice("abc"), a).is_some()); + assert!(map.insert(Owned("bcd".to_string()), b).is_some()); + assert!(map.insert(Slice("cde"), c).is_some()); + assert!(map.insert(Owned("def".to_string()), d).is_some()); - assert!(!map.insert(Owned("abc".to_string()), a)); - assert!(!map.insert(Slice("bcd"), b)); - assert!(!map.insert(Owned("cde".to_string()), c)); - assert!(!map.insert(Slice("def"), d)); + assert!(map.insert(Owned("abc".to_string()), a).is_some()); + assert!(map.insert(Slice("bcd"), b).is_some()); + assert!(map.insert(Owned("cde".to_string()), c).is_some()); + assert!(map.insert(Slice("def"), d).is_some()); assert_eq!(map.find_equiv("abc"), Some(&a)); assert_eq!(map.find_equiv("bcd"), Some(&b)); diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index f73ab8f52d7e..c52f9458f99d 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -17,49 +17,49 @@ use std::option::Some; pub fn main() { let mut map: TreeMap = TreeMap::new(); - assert!(map.insert(Slice("foo"), 42)); - assert!(!map.insert(Owned("foo".to_string()), 42)); - assert!(!map.insert(Slice("foo"), 42)); - assert!(!map.insert(Owned("foo".to_string()), 42)); + assert!(map.insert(Slice("foo"), 42).is_none()); + assert!(map.insert(Owned("foo".to_string()), 42).is_some()); + assert!(map.insert(Slice("foo"), 42).is_some()); + assert!(map.insert(Owned("foo".to_string()), 42).is_some()); - assert!(!map.insert(Slice("foo"), 43)); - assert!(!map.insert(Owned("foo".to_string()), 44)); - assert!(!map.insert(Slice("foo"), 45)); - assert!(!map.insert(Owned("foo".to_string()), 46)); + assert!(map.insert(Slice("foo"), 43).is_some()); + assert!(map.insert(Owned("foo".to_string()), 44).is_some()); + assert!(map.insert(Slice("foo"), 45).is_some()); + assert!(map.insert(Owned("foo".to_string()), 46).is_some()); let v = 46; - assert_eq!(map.find(&Owned("foo".to_string())), Some(&v)); - assert_eq!(map.find(&Slice("foo")), Some(&v)); + assert_eq!(map.get(&Owned("foo".to_string())), Some(&v)); + assert_eq!(map.get(&Slice("foo")), Some(&v)); let (a, b, c, d) = (50, 51, 52, 53); - assert!(map.insert(Slice("abc"), a)); - assert!(map.insert(Owned("bcd".to_string()), b)); - assert!(map.insert(Slice("cde"), c)); - assert!(map.insert(Owned("def".to_string()), d)); + assert!(map.insert(Slice("abc"), a).is_none()); + assert!(map.insert(Owned("bcd".to_string()), b).is_none()); + assert!(map.insert(Slice("cde"), c).is_none()); + assert!(map.insert(Owned("def".to_string()), d).is_none()); - assert!(!map.insert(Slice("abc"), a)); - assert!(!map.insert(Owned("bcd".to_string()), b)); - assert!(!map.insert(Slice("cde"), c)); - assert!(!map.insert(Owned("def".to_string()), d)); + assert!(map.insert(Slice("abc"), a).is_some()); + assert!(map.insert(Owned("bcd".to_string()), b).is_some()); + assert!(map.insert(Slice("cde"), c).is_some()); + assert!(map.insert(Owned("def".to_string()), d).is_some()); - assert!(!map.insert(Owned("abc".to_string()), a)); - assert!(!map.insert(Slice("bcd"), b)); - assert!(!map.insert(Owned("cde".to_string()), c)); - assert!(!map.insert(Slice("def"), d)); + assert!(map.insert(Owned("abc".to_string()), a).is_some()); + assert!(map.insert(Slice("bcd"), b).is_some()); + assert!(map.insert(Owned("cde".to_string()), c).is_some()); + assert!(map.insert(Slice("def"), d).is_some()); - assert_eq!(map.find(&Slice("abc")), Some(&a)); - assert_eq!(map.find(&Slice("bcd")), Some(&b)); - assert_eq!(map.find(&Slice("cde")), Some(&c)); - assert_eq!(map.find(&Slice("def")), Some(&d)); + assert_eq!(map.get(&Slice("abc")), Some(&a)); + assert_eq!(map.get(&Slice("bcd")), Some(&b)); + assert_eq!(map.get(&Slice("cde")), Some(&c)); + assert_eq!(map.get(&Slice("def")), Some(&d)); - assert_eq!(map.find(&Owned("abc".to_string())), Some(&a)); - assert_eq!(map.find(&Owned("bcd".to_string())), Some(&b)); - assert_eq!(map.find(&Owned("cde".to_string())), Some(&c)); - assert_eq!(map.find(&Owned("def".to_string())), Some(&d)); + assert_eq!(map.get(&Owned("abc".to_string())), Some(&a)); + assert_eq!(map.get(&Owned("bcd".to_string())), Some(&b)); + assert_eq!(map.get(&Owned("cde".to_string())), Some(&c)); + assert_eq!(map.get(&Owned("def".to_string())), Some(&d)); - assert!(map.pop(&Slice("foo")).is_some()); + assert!(map.remove(&Slice("foo")).is_some()); assert_eq!(map.into_iter().map(|(k, v)| format!("{}{}", k, v)) .collect::>() .concat(), diff --git a/src/test/run-pass/swap-2.rs b/src/test/run-pass/swap-2.rs index 4eb9274551f9..3c0f9505736a 100644 --- a/src/test/run-pass/swap-2.rs +++ b/src/test/run-pass/swap-2.rs @@ -16,7 +16,7 @@ pub fn main() { assert_eq!(a[2], 4); assert_eq!(a[4], 2); let mut n = 42; - swap(&mut n, a.get_mut(0)); + swap(&mut n, &mut a[0]); assert_eq!(a[0], 42); assert_eq!(n, 0); } diff --git a/src/test/run-pass/unique-in-vec-copy.rs b/src/test/run-pass/unique-in-vec-copy.rs index 33a28ddb2fca..577a8f1430b2 100644 --- a/src/test/run-pass/unique-in-vec-copy.rs +++ b/src/test/run-pass/unique-in-vec-copy.rs @@ -17,7 +17,7 @@ pub fn main() { assert_eq!(*b[0], 10); // This should only modify the value in a, not b - **a.get_mut(0) = 20; + *a[0] = 20; assert_eq!(*a[0], 20); assert_eq!(*b[0], 10); From f230e788e06ae6c37616c484209e77e75ac082b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabrice=20Desr=C3=A9?= Date: Thu, 6 Nov 2014 09:37:54 -0800 Subject: [PATCH 28/37] Fix a couple of build warnings --- src/libunicode/tables.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs index 87ee3220ee58..d79a7e493fed 100644 --- a/src/libunicode/tables.rs +++ b/src/libunicode/tables.rs @@ -10,7 +10,7 @@ // NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly -#![allow(missing_doc, non_uppercase_statics, non_snake_case)] +#![allow(missing_docs, non_uppercase_globals, non_snake_case)] /// The version of [Unicode](http://www.unicode.org/) /// that the `UnicodeChar` and `UnicodeStrSlice` traits are based on. From c4fe78176334bcf23f0f3387cfcdf040a9316e61 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Thu, 6 Nov 2014 10:19:53 -0500 Subject: [PATCH 29/37] link to raw string docs in libregex docs Fixes #17023 --- src/libregex/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs index f3633a006b13..b849afbbf54e 100644 --- a/src/libregex/lib.rs +++ b/src/libregex/lib.rs @@ -41,7 +41,8 @@ //! it to match anywhere in the text. Anchors can be used to ensure that the //! full text matches an expression. //! -//! This example also demonstrates the utility of raw strings in Rust, which +//! This example also demonstrates the utility of [raw +//! strings](../reference.html#character-and-string-literals) in Rust, which //! are just like regular strings except they are prefixed with an `r` and do //! not process any escape sequences. For example, `"\\d"` is the same //! expression as `r"\d"`. From 679eb9191dd06a2e0dacf3602da56765211fd76a Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 6 Nov 2014 11:25:09 -0500 Subject: [PATCH 30/37] DTSify libserialize traits - ToBase64 - FromBase64 - ToHex - FromHex - ToJson - Encodable --- src/libserialize/base64.rs | 10 +++++----- src/libserialize/hex.rs | 8 ++++---- src/libserialize/json.rs | 4 ++-- src/libserialize/serialize.rs | 21 ++++++++++++++------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs index e69a0ea7929c..f287fb99750a 100644 --- a/src/libserialize/base64.rs +++ b/src/libserialize/base64.rs @@ -54,13 +54,13 @@ static URLSAFE_CHARS: &'static[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\ 0123456789-_"; /// A trait for converting a value to base64 encoding. -pub trait ToBase64 { +pub trait ToBase64 for Sized? { /// Converts the value of `self` to a base64 value following the specified /// format configuration, returning the owned string. fn to_base64(&self, config: Config) -> String; } -impl<'a> ToBase64 for &'a [u8] { +impl ToBase64 for [u8] { /** * Turn a vector of `u8` bytes into a base64 string. * @@ -155,7 +155,7 @@ impl<'a> ToBase64 for &'a [u8] { } /// A trait for converting from base64 encoded values. -pub trait FromBase64 { +pub trait FromBase64 for Sized? { /// Converts the value of `self`, interpreted as base64 encoded data, into /// an owned vector of bytes, returning the vector. fn from_base64(&self) -> Result, FromBase64Error>; @@ -192,7 +192,7 @@ impl error::Error for FromBase64Error { } } -impl<'a> FromBase64 for &'a str { +impl FromBase64 for str { /** * Convert any base64 encoded string (literal, `@`, `&`, or `~`) * to the byte values it encodes. @@ -227,7 +227,7 @@ impl<'a> FromBase64 for &'a str { } } -impl<'a> FromBase64 for &'a [u8] { +impl FromBase64 for [u8] { fn from_base64(&self) -> Result, FromBase64Error> { let mut r = Vec::new(); let mut buf: u32 = 0; diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs index b591d35c67c0..e045f94c08e6 100644 --- a/src/libserialize/hex.rs +++ b/src/libserialize/hex.rs @@ -16,7 +16,7 @@ use std::string; use std::error; /// A trait for converting a value to hexadecimal encoding -pub trait ToHex { +pub trait ToHex for Sized? { /// Converts the value of `self` to a hex value, returning the owned /// string. fn to_hex(&self) -> String; @@ -24,7 +24,7 @@ pub trait ToHex { static CHARS: &'static[u8] = b"0123456789abcdef"; -impl<'a> ToHex for &'a [u8] { +impl ToHex for [u8] { /** * Turn a vector of `u8` bytes into a hexadecimal string. * @@ -54,7 +54,7 @@ impl<'a> ToHex for &'a [u8] { } /// A trait for converting hexadecimal encoded values -pub trait FromHex { +pub trait FromHex for Sized? { /// Converts the value of `self`, interpreted as hexadecimal encoded data, /// into an owned vector of bytes, returning the vector. fn from_hex(&self) -> Result, FromHexError>; @@ -92,7 +92,7 @@ impl error::Error for FromHexError { } -impl<'a> FromHex for &'a str { +impl FromHex for str { /** * Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`) * to the byte values it encodes. diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index dbdfa17bfc22..7093fefeb8f3 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2303,7 +2303,7 @@ impl ::Decoder for Decoder { } /// A trait for converting values to JSON -pub trait ToJson { +pub trait ToJson for Sized? { /// Converts the value of `self` to an instance of JSON fn to_json(&self) -> Json; } @@ -2389,7 +2389,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I, J} tuple_impl!{A, B, C, D, E, F, G, H, I, J, K} tuple_impl!{A, B, C, D, E, F, G, H, I, J, K, L} -impl<'a, A: ToJson> ToJson for &'a [A] { +impl ToJson for [A] { fn to_json(&self) -> Json { List(self.iter().map(|elt| elt.to_json()).collect()) } } diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index b7c37defbfa4..7539a6dc3486 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -169,7 +169,7 @@ pub trait Decoder { fn error(&mut self, err: &str) -> E; } -pub trait Encodable, E> { +pub trait Encodable, E> for Sized? { fn encode(&self, s: &mut S) -> Result<(), E>; } @@ -297,9 +297,9 @@ impl> Decodable for i64 { } } -impl<'a, E, S:Encoder> Encodable for &'a str { +impl> Encodable for str { fn encode(&self, s: &mut S) -> Result<(), E> { - s.emit_str(*self) + s.emit_str(self) } } @@ -375,24 +375,31 @@ impl> Decodable for () { } } -impl<'a, E, S:Encoder,T:Encodable> Encodable for &'a T { +impl<'a, E, S: Encoder, Sized? T: Encodable> Encodable for &'a T { fn encode(&self, s: &mut S) -> Result<(), E> { (**self).encode(s) } } -impl,T:Encodable> Encodable for Box { +impl, Sized? T: Encodable> Encodable for Box { fn encode(&self, s: &mut S) -> Result<(), E> { (**self).encode(s) } } -impl,T:Decodable> Decodable for Box { +impl, T: Decodable> Decodable for Box { fn decode(d: &mut D) -> Result, E> { Ok(box try!(Decodable::decode(d))) } } +impl, T: Decodable> Decodable for Box<[T]> { + fn decode(d: &mut D) -> Result, E> { + let v: Vec = try!(Decodable::decode(d)); + Ok(v.into_boxed_slice()) + } +} + impl,T:Encodable> Encodable for Rc { #[inline] fn encode(&self, s: &mut S) -> Result<(), E> { @@ -407,7 +414,7 @@ impl,T:Decodable> Decodable for Rc { } } -impl<'a, E, S:Encoder,T:Encodable> Encodable for &'a [T] { +impl,T:Encodable> Encodable for [T] { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_seq(self.len(), |s| { for (i, e) in self.iter().enumerate() { From 73b86e47786e14938048b7c298a70bc5ff536a88 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 6 Nov 2014 12:52:45 -0500 Subject: [PATCH 31/37] Implement Default for Box<[T]> --- src/liballoc/boxed.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index d1fc921ffdab..0a06f7c0005f 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -48,6 +48,10 @@ impl Default for Box { fn default() -> Box { box Default::default() } } +impl Default for Box<[T]> { + fn default() -> Box<[T]> { box [] } +} + #[unstable] impl Clone for Box { /// Returns a copy of the owned box. From 5272e6c4c6ed57cd0faafea2925995d9b3023105 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 6 Nov 2014 11:49:08 -0500 Subject: [PATCH 32/37] Add tests --- src/test/run-pass/deriving-default-box.rs | 22 ++++++++++++++++ .../deriving-encodable-decodable-box.rs | 26 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/test/run-pass/deriving-default-box.rs create mode 100644 src/test/run-pass/deriving-encodable-decodable-box.rs diff --git a/src/test/run-pass/deriving-default-box.rs b/src/test/run-pass/deriving-default-box.rs new file mode 100644 index 000000000000..aeef55fbbacd --- /dev/null +++ b/src/test/run-pass/deriving-default-box.rs @@ -0,0 +1,22 @@ +// Copyright 2013-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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::default::Default; + +#[deriving(Default)] +struct A { + foo: Box<[bool]>, +} + +pub fn main() { + let a: A = Default::default(); + let b: Box<[_]> = box []; + assert_eq!(a.foo, b); +} diff --git a/src/test/run-pass/deriving-encodable-decodable-box.rs b/src/test/run-pass/deriving-encodable-decodable-box.rs new file mode 100644 index 000000000000..e21f64cd74c8 --- /dev/null +++ b/src/test/run-pass/deriving-encodable-decodable-box.rs @@ -0,0 +1,26 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate serialize; + +use serialize::{Encodable, Decodable}; +use serialize::json; + +#[deriving(Encodable, Decodable)] +struct A { + foo: Box<[bool]>, +} + +fn main() { + let obj = A { foo: box [true, false] }; + let s = json::encode(&obj); + let obj2: A = json::decode(s.as_slice()).unwrap(); + assert!(obj.foo == obj2.foo); +} From 31ce92d910d68c7abff741df3d07808ac238fa89 Mon Sep 17 00:00:00 2001 From: qwitwa Date: Thu, 6 Nov 2014 19:25:00 +0000 Subject: [PATCH 33/37] 14.3 - helpfully implied code sample is broken As a new user, I spent a while confused when flycheck told me the code sample I'd typed in was invalid. I ended up figuring out some of what comes after the code sample more painfully by myself because there was no indication that it was broken in the text beforehand. This one line change makes it clear that the code following it is an experiment that may not work rather than something to assume just works. --- src/doc/guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/guide.md b/src/doc/guide.md index 9a1a42478d37..ad51e0544bc6 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -1901,8 +1901,8 @@ result is a link to click on that result, we'll be taken to its documentation page. This page shows us a few things: the type signature of the function, some -explanatory text, and then an example. Let's modify our code to add in the -`random` function: +explanatory text, and then an example. Let's try to modify our code to add in the +`random` function and see what happens: ```{rust,ignore} use std::io; From bb5f03b900146d5e7f4fda849a38531d7f124441 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 6 Nov 2014 11:29:49 -0800 Subject: [PATCH 34/37] mk: Add -C prefer-dynamic to stage3 libs Right now the windows nightlies are failing because they're encountering a linker error when producing stage3 libs. The stage3 libs aren't actually used in general, and we primarily just want to generate a static stage3 binary, not static stage3 dylibs. --- mk/main.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/mk/main.mk b/mk/main.mk index 7ed134d60fb8..aba02088eabe 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -155,6 +155,7 @@ endif RUSTFLAGS_STAGE0 += -C prefer-dynamic RUSTFLAGS_STAGE1 += -C prefer-dynamic RUST_LIB_FLAGS_ST2 += -C prefer-dynamic +RUST_LIB_FLAGS_ST3 += -C prefer-dynamic # Landing pads require a lot of codegen. We can get through bootstrapping faster # by not emitting them. From b39f1dcba0d79fa9b791e6d0735b411795f44979 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 4 Nov 2014 11:22:32 -0800 Subject: [PATCH 35/37] Remove rlibc from the distribution To make progress on #18585 we're paring down the distribution to theoretically "only libstd", and this commit makes progress on this by removing the rlibc crate from the distribution. The crate has now been moved into an external cargo package located in the rust lang organization [1]. This is a breaking change due to this removal, and existing crates depending on `rlibc` should use the Cargo crate instead. [1]: https://github.com/rust-lang/rlibc [breaking-change] cc #18585 --- mk/crates.mk | 4 +- src/librlibc/lib.rs | 202 -------------------------------------------- 2 files changed, 1 insertion(+), 205 deletions(-) delete mode 100644 src/librlibc/lib.rs diff --git a/mk/crates.mk b/mk/crates.mk index 00c00b3d3595..771c1821e380 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -51,7 +51,7 @@ TARGET_CRATES := libc std green native flate arena term \ serialize sync getopts collections test time rand \ - log regex graphviz core rbml rlibc alloc rustrt \ + log regex graphviz core rbml alloc rustrt \ unicode HOST_CRATES := syntax rustc rustdoc regex_macros fmt_macros \ rustc_llvm rustc_back @@ -60,7 +60,6 @@ TOOLS := compiletest rustdoc rustc DEPS_core := DEPS_libc := core -DEPS_rlibc := core DEPS_unicode := core DEPS_alloc := core libc native:jemalloc DEPS_rustrt := alloc core libc collections native:rustrt_native @@ -104,7 +103,6 @@ TOOL_SOURCE_rustc := $(S)src/driver/driver.rs ONLY_RLIB_core := 1 ONLY_RLIB_libc := 1 -ONLY_RLIB_rlibc := 1 ONLY_RLIB_alloc := 1 ONLY_RLIB_rand := 1 ONLY_RLIB_collections := 1 diff --git a/src/librlibc/lib.rs b/src/librlibc/lib.rs deleted file mode 100644 index 128243187757..000000000000 --- a/src/librlibc/lib.rs +++ /dev/null @@ -1,202 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A bare-metal library supplying functions rustc may lower code to -//! -//! This library is not intended for general use, and is superseded by a system -//! libc if one is available. In a freestanding context, however, common -//! functions such as memset, memcpy, etc are not implemented. This library -//! provides an implementation of these functions which are either required by -//! libcore or called by rustc implicitly. -//! -//! This library is never included by default, and must be manually included if -//! necessary. It is an error to include this library when also linking with -//! the system libc library. - -#![crate_name = "rlibc"] -#![experimental] -#![license = "MIT/ASL2"] -#![crate_type = "rlib"] -#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", - html_root_url = "http://doc.rust-lang.org/nightly/")] - -#![feature(import_shadowing, intrinsics, phase)] -#![no_std] - -// This library defines the builtin functions, so it would be a shame for -// LLVM to optimize these function calls to themselves! -#![no_builtins] - -#[phase(plugin, link)] extern crate core; - -#[cfg(test)] extern crate native; -#[cfg(test)] extern crate test; - -#[cfg(test)] #[phase(plugin, link)] extern crate std; - -// Require the offset intrinsics for LLVM to properly optimize the -// implementations below. If pointer arithmetic is done through integers the -// optimizations start to break down. -extern "rust-intrinsic" { - fn offset(dst: *const T, offset: int) -> *const T; -} - -#[no_mangle] -pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, - n: uint) -> *mut u8 { - let mut i = 0; - while i < n { - *(offset(dest as *const u8, i as int) as *mut u8) = - *offset(src, i as int); - i += 1; - } - return dest; -} - -#[no_mangle] -pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, - n: uint) -> *mut u8 { - if src < dest as *const u8 { // copy from end - let mut i = n; - while i != 0 { - i -= 1; - *(offset(dest as *const u8, i as int) as *mut u8) = - *offset(src, i as int); - } - } else { // copy from beginning - let mut i = 0; - while i < n { - *(offset(dest as *const u8, i as int) as *mut u8) = - *offset(src, i as int); - i += 1; - } - } - return dest; -} - -#[no_mangle] -pub unsafe extern "C" fn memset(s: *mut u8, c: i32, n: uint) -> *mut u8 { - let mut i = 0; - while i < n { - *(offset(s as *const u8, i as int) as *mut u8) = c as u8; - i += 1; - } - return s; -} - -#[no_mangle] -pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: uint) -> i32 { - let mut i = 0; - while i < n { - let a = *offset(s1, i as int); - let b = *offset(s2, i as int); - if a != b { - return a as i32 - b as i32 - } - i += 1; - } - return 0; -} - -#[cfg(test)] -mod test { - use core::str::StrPrelude; - use core::slice::{SlicePrelude}; - - use super::{memcmp, memset, memcpy, memmove}; - - #[test] - fn memcmp_single_byte_pointers() { - unsafe { - assert_eq!(memcmp(&0xFAu8, &0xFAu8, 1), 0x00); - assert!(memcmp(&0xEFu8, &0xFEu8, 1) < 0x00); - } - } - - #[test] - fn memcmp_strings() { - { - let (x, z) = ("Hello!", "Good Bye."); - let l = x.len(); - unsafe { - assert_eq!(memcmp(x.as_ptr(), x.as_ptr(), l), 0); - assert!(memcmp(x.as_ptr(), z.as_ptr(), l) > 0); - assert!(memcmp(z.as_ptr(), x.as_ptr(), l) < 0); - } - } - { - let (x, z) = ("hey!", "hey."); - let l = x.len(); - unsafe { - assert!(memcmp(x.as_ptr(), z.as_ptr(), l) < 0); - } - } - } - - #[test] - fn memset_single_byte_pointers() { - let mut x: u8 = 0xFF; - unsafe { - memset(&mut x, 0xAA, 1); - assert_eq!(x, 0xAA); - memset(&mut x, 0x00, 1); - assert_eq!(x, 0x00); - x = 0x01; - memset(&mut x, 0x12, 0); - assert_eq!(x, 0x01); - } - } - - #[test] - fn memset_array() { - let mut buffer = [b'X', .. 100]; - unsafe { - memset(buffer.as_mut_ptr(), b'#' as i32, buffer.len()); - } - for byte in buffer.iter() { assert_eq!(*byte, b'#'); } - } - - #[test] - fn memcpy_and_memcmp_arrays() { - let (src, mut dst) = ([b'X', .. 100], [b'Y', .. 100]); - unsafe { - assert!(memcmp(src.as_ptr(), dst.as_ptr(), 100) != 0); - let _ = memcpy(dst.as_mut_ptr(), src.as_ptr(), 100); - assert_eq!(memcmp(src.as_ptr(), dst.as_ptr(), 100), 0); - } - } - - #[test] - fn memmove_overlapping() { - { - let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ]; - unsafe { - memmove(&mut buffer[4], &buffer[0], 6); - let mut i = 0; - for byte in b"0123012345".iter() { - assert_eq!(buffer[i], *byte); - i += 1; - } - } - } - { - let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ]; - unsafe { - memmove(&mut buffer[0], &buffer[4], 6); - let mut i = 0; - for byte in b"4567896789".iter() { - assert_eq!(buffer[i], *byte); - i += 1; - } - } - } - } -} From 65805bffe7524a79de6e275d6d9172f6e5ff99eb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 6 Nov 2014 13:54:32 -0800 Subject: [PATCH 36/37] Test fixes and rebase conflicts --- src/libstd/rand/os.rs | 2 +- src/libunicode/tables.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs index e648a6185163..6bf259d201e6 100644 --- a/src/libstd/rand/os.rs +++ b/src/libstd/rand/os.rs @@ -22,7 +22,7 @@ mod imp { use rand::Rng; use rand::reader::ReaderRng; use result::{Ok, Err}; - use slice::{ImmutableSlice, MutableSlice}; + use slice::SlicePrelude; use mem; use os::errno; diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs index c665ac3748be..797523540492 100644 --- a/src/libunicode/tables.rs +++ b/src/libunicode/tables.rs @@ -10,7 +10,7 @@ // NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly -#![allow(missing_docs, non_uppercase_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case)] /// The version of [Unicode](http://www.unicode.org/) /// that the `UnicodeChar` and `UnicodeStrPrelude` traits are based on. From 2655abdd399661fbbcac3c9bde23444ccea64a63 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 6 Nov 2014 15:41:50 -0800 Subject: [PATCH 37/37] fix EnumSet::is_subset Fix by @Gankro! --- src/libcollections/enum_set.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 454d4f1ca872..77eee98ecd8d 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -100,7 +100,7 @@ impl EnumSet { /// Returns `true` if this `EnumSet` is included in the given `EnumSet`. #[unstable = "matches collection reform specification, waiting for dust to settle"] pub fn is_subset(&self, other: &EnumSet) -> bool { - other.is_subset(self) + other.is_superset(self) } /// Returns the union of both `EnumSets`. @@ -302,8 +302,13 @@ mod test { e2.insert(A); e2.insert(B); - assert!(!e1.is_superset(&e2)); + let mut e3: EnumSet = EnumSet::new(); + e3.insert(C); + + assert!(e1.is_subset(&e2)); assert!(e2.is_superset(&e1)); + assert!(!e3.is_superset(&e2)) + assert!(!e2.is_superset(&e3)) } #[test]