]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #23549: aturon/stab-num
authorAlex Crichton <alex@alexcrichton.com>
Tue, 31 Mar 2015 17:15:26 +0000 (10:15 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 31 Mar 2015 17:15:26 +0000 (10:15 -0700)
This commit stabilizes the `std::num` module:

* The `Int` and `Float` traits are deprecated in favor of (1) the
  newly-added inherent methods and (2) the generic traits available in
  rust-lang/num.

* The `Zero` and `One` traits are reintroduced in `std::num`, which
  together with various other traits allow you to recover the most
  common forms of generic programming.

* The `FromStrRadix` trait, and associated free function, is deprecated
  in favor of inherent implementations.

* A wide range of methods and constants for both integers and floating
  point numbers are now `#[stable]`, having been adjusted for integer
  guidelines.

* `is_positive` and `is_negative` are renamed to `is_sign_positive` and
  `is_sign_negative`, in order to address #22985

* The `Wrapping` type is moved to `std::num` and stabilized;
  `WrappingOps` is deprecated in favor of inherent methods on the
  integer types, and direct implementation of operations on
  `Wrapping<X>` for each concrete integer type `X`.

Closes #22985
Closes #21069

[breaking-change]

r? @alexcrichton

1  2 
src/liballoc/heap.rs
src/libcollections/slice.rs
src/libcollections/vec_deque.rs
src/librbml/lib.rs
src/librustc/metadata/decoder.rs
src/librustc/middle/ty.rs
src/librustc_back/sha2.rs
src/librustc_lint/builtin.rs
src/librustc_typeck/check/mod.rs
src/libstd/io/cursor.rs
src/libstd/sys/common/wtf8.rs

diff --combined src/liballoc/heap.rs
index c6c86e46b444306de395553422060d277aa36d6a,a2adef60cb12d4fa35b27a8ed1c12196109bffa8..57baa811b9d4740f82be7a272ae0fe2d44eaaad0
@@@ -189,7 -189,6 +189,6 @@@ mod imp 
      use core::option::Option;
      use core::option::Option::None;
      use core::ptr::{null_mut, null};
-     use core::num::Int;
      use libc::{c_char, c_int, c_void, size_t};
      use super::MIN_ALIGN;
  
@@@ -301,7 -300,7 +300,7 @@@ mod imp 
              libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
          } else {
              let new_ptr = allocate(size, align);
 -            ptr::copy(new_ptr, ptr, cmp::min(size, old_size));
 +            ptr::copy(ptr, new_ptr, cmp::min(size, old_size));
              deallocate(ptr, old_size, align);
              new_ptr
          }
index 0ca297765ff6d6fa82b5a5913a271c8324248197,d9824f65824e19ccc25c3b3290a5fa5bc4e6cb0c..050997f2dd3f085459575ea13b65c79725e5c636
@@@ -89,6 -89,7 +89,7 @@@ use core::iter::MultiplicativeIterator
  use core::marker::Sized;
  use core::mem::size_of;
  use core::mem;
+ #[cfg(stage0)]
  use core::num::wrapping::WrappingOps;
  use core::ops::FnMut;
  use core::option::Option::{self, Some, None};
@@@ -1320,10 -1321,10 +1321,10 @@@ fn insertion_sort<T, F>(v: &mut [T], mu
  
              if i != j {
                  let tmp = ptr::read(read_ptr);
 -                ptr::copy(buf_v.offset(j + 1),
 -                          &*buf_v.offset(j),
 +                ptr::copy(&*buf_v.offset(j),
 +                          buf_v.offset(j + 1),
                            (i - j) as usize);
 -                ptr::copy_nonoverlapping(buf_v.offset(j), &tmp, 1);
 +                ptr::copy_nonoverlapping(&tmp, buf_v.offset(j), 1);
                  mem::forget(tmp);
              }
          }
@@@ -1396,10 -1397,10 +1397,10 @@@ fn merge_sort<T, F>(v: &mut [T], mut co
                  // j + 1 could be `len` (for the last `i`), but in
                  // that case, `i == j` so we don't copy. The
                  // `.offset(j)` is always in bounds.
 -                ptr::copy(buf_dat.offset(j + 1),
 -                          &*buf_dat.offset(j),
 +                ptr::copy(&*buf_dat.offset(j),
 +                          buf_dat.offset(j + 1),
                            i - j as usize);
 -                ptr::copy_nonoverlapping(buf_dat.offset(j), read_ptr, 1);
 +                ptr::copy_nonoverlapping(read_ptr, buf_dat.offset(j), 1);
              }
          }
      }
                      if left == right_start {
                          // the number remaining in this run.
                          let elems = (right_end as usize - right as usize) / mem::size_of::<T>();
 -                        ptr::copy_nonoverlapping(out, &*right, elems);
 +                        ptr::copy_nonoverlapping(&*right, out, elems);
                          break;
                      } else if right == right_end {
                          let elems = (right_start as usize - left as usize) / mem::size_of::<T>();
 -                        ptr::copy_nonoverlapping(out, &*left, elems);
 +                        ptr::copy_nonoverlapping(&*left, out, elems);
                          break;
                      }
  
                      } else {
                          step(&mut left)
                      };
 -                    ptr::copy_nonoverlapping(out, &*to_copy, 1);
 +                    ptr::copy_nonoverlapping(&*to_copy, out, 1);
                      step(&mut out);
                  }
              }
      // write the result to `v` in one go, so that there are never two copies
      // of the same object in `v`.
      unsafe {
 -        ptr::copy_nonoverlapping(v.as_mut_ptr(), &*buf_dat, len);
 +        ptr::copy_nonoverlapping(&*buf_dat, v.as_mut_ptr(), len);
      }
  
      // increment the pointer, returning the old pointer.
index abe8e7cf3aa0fd9de1df96657391104ac3b381f2,a4cd6dbdf01f5662064e5d55e7df5e9e29819bdb..392e5092e3b6a9845b0929e83da10f23ff959c77
@@@ -25,6 -25,7 +25,7 @@@ use core::default::Default
  use core::fmt;
  use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
  use core::mem;
+ #[cfg(stage0)]
  use core::num::wrapping::WrappingOps;
  use core::ops::{Index, IndexMut};
  use core::ptr::{self, Unique};
@@@ -142,8 -143,8 +143,8 @@@ impl<T> VecDeque<T> 
          debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
                        self.cap);
          ptr::copy(
 -            self.ptr.offset(dst as isize),
              self.ptr.offset(src as isize),
 +            self.ptr.offset(dst as isize),
              len);
      }
  
          debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
                        self.cap);
          ptr::copy_nonoverlapping(
 -            self.ptr.offset(dst as isize),
              self.ptr.offset(src as isize),
 +            self.ptr.offset(dst as isize),
              len);
      }
  }
@@@ -1361,21 -1362,21 +1362,21 @@@ impl<T> VecDeque<T> 
                  // `at` lies in the first half.
                  let amount_in_first = first_len - at;
  
 -                ptr::copy_nonoverlapping(*other.ptr,
 -                                         first_half.as_ptr().offset(at as isize),
 +                ptr::copy_nonoverlapping(first_half.as_ptr().offset(at as isize),
 +                                         *other.ptr,
                                           amount_in_first);
  
                  // just take all of the second half.
 -                ptr::copy_nonoverlapping(other.ptr.offset(amount_in_first as isize),
 -                                         second_half.as_ptr(),
 +                ptr::copy_nonoverlapping(second_half.as_ptr(),
 +                                         other.ptr.offset(amount_in_first as isize),
                                           second_len);
              } else {
                  // `at` lies in the second half, need to factor in the elements we skipped
                  // in the first half.
                  let offset = at - first_len;
                  let amount_in_second = second_len - offset;
 -                ptr::copy_nonoverlapping(*other.ptr,
 -                                         second_half.as_ptr().offset(offset as isize),
 +                ptr::copy_nonoverlapping(second_half.as_ptr().offset(offset as isize),
 +                                         *other.ptr,
                                           amount_in_second);
              }
          }
diff --combined src/librbml/lib.rs
index 80341fa1a7a2f886f904fc96cd9e9da46750e60b,133b04a9f74b8a35b1e0c913d5c1abcf0b8c1396..092cd780ec7c7cfb02efc8e16e996c3f8d5ae1d7
@@@ -241,7 -241,6 +241,6 @@@ pub mod reader 
  
      use std::isize;
      use std::mem::transmute;
-     use std::num::Int;
      use std::slice::bytes;
  
      use serialize;
  
          unsafe {
              let ptr = data.as_ptr().offset(start as isize) as *const u32;
-             let val = Int::from_be(*ptr);
+             let val = u32::from_be(*ptr);
  
              let i = (val >> 28) as usize;
              let (shift, mask) = SHIFT_MASK_TABLE[i];
      pub fn doc_as_u16(d: Doc) -> u16 {
          assert_eq!(d.end, d.start + 2);
          let mut b = [0; 2];
 -        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
 +        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
          unsafe { (*(b.as_ptr() as *const u16)).to_be() }
      }
  
      pub fn doc_as_u32(d: Doc) -> u32 {
          assert_eq!(d.end, d.start + 4);
          let mut b = [0; 4];
 -        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
 +        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
          unsafe { (*(b.as_ptr() as *const u32)).to_be() }
      }
  
      pub fn doc_as_u64(d: Doc) -> u64 {
          assert_eq!(d.end, d.start + 8);
          let mut b = [0; 8];
 -        bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
 +        bytes::copy_memory(&d.data[d.start..d.end], &mut b);
          unsafe { (*(b.as_ptr() as *const u64)).to_be() }
      }
  
  
  pub mod writer {
      use std::mem;
-     use std::num::Int;
      use std::io::prelude::*;
      use std::io::{self, SeekFrom, Cursor};
      use std::slice::bytes;
                  {
                      let last_size_pos = last_size_pos as usize;
                      let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as usize];
 -                    bytes::copy_memory(&mut buf, data);
 +                    bytes::copy_memory(data, &mut buf);
                  }
  
                  // overwrite the size and data and continue
index 1cff7c448a96277892835fe32a8c8c91ae17836a,1833d6b7e666ff150a62aacccb6f7d5f92ced944..92810b407f039dde41f2dc16ee97e6878585ed43
@@@ -35,7 -35,7 +35,7 @@@ use std::collections::HashMap
  use std::hash::{self, Hash, SipHasher};
  use std::io::prelude::*;
  use std::io;
- use std::num::{FromPrimitive, Int};
+ use std::num::FromPrimitive;
  use std::rc::Rc;
  use std::slice::bytes;
  use std::str;
@@@ -62,7 -62,7 +62,7 @@@ pub type Cmd<'a> = &'a crate_metadata
  
  fn u32_from_be_bytes(bytes: &[u8]) -> u32 {
      let mut b = [0; 4];
 -    bytes::copy_memory(&mut b, &bytes[..4]);
 +    bytes::copy_memory(&bytes[..4], &mut b);
      unsafe { (*(b.as_ptr() as *const u32)).to_be() }
  }
  
index a788386d2424fec79dd3215cb3acc09553883b9d,7df4cc4b44f99a054c9c6c5c170e449ac2a7169b..161fae11ea6d42c1f254f80f5db9e700c447e72e
@@@ -3039,10 -3039,6 +3039,10 @@@ pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -
      mk_tup(cx, Vec::new())
  }
  
 +pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
 +    mk_t(cx, ty_bool)
 +}
 +
  pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
                          opt_def_id: Option<ast::DefId>,
                          fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
@@@ -3410,12 -3406,8 +3410,12 @@@ pub fn type_is_scalar(ty: Ty) -> bool 
  /// Returns true if this type is a floating point type and false otherwise.
  pub fn type_is_floating_point(ty: Ty) -> bool {
      match ty.sty {
 -        ty_float(_) => true,
 -        _ => false,
 +        ty_float(_) |
 +        ty_infer(FloatVar(_)) =>
 +            true,
 +
 +        _ =>
 +            false,
      }
  }
  
@@@ -5491,7 -5483,6 +5491,6 @@@ pub fn type_is_empty(cx: &ctxt, ty: Ty
  
  pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
                             -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
-     use std::num::Int; // For checked_add
      memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
          if ast::LOCAL_CRATE != id.krate {
              Rc::new(csearch::get_enum_variants(cx, id))
@@@ -5813,6 -5804,78 +5812,6 @@@ pub fn closure_upvars<'tcx>(typer: &mc:
      }
  }
  
 -pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool {
 -    #![allow(non_upper_case_globals)]
 -    const tycat_other: isize = 0;
 -    const tycat_bool: isize = 1;
 -    const tycat_char: isize = 2;
 -    const tycat_int: isize = 3;
 -    const tycat_float: isize = 4;
 -    const tycat_raw_ptr: isize = 6;
 -
 -    const opcat_add: isize = 0;
 -    const opcat_sub: isize = 1;
 -    const opcat_mult: isize = 2;
 -    const opcat_shift: isize = 3;
 -    const opcat_rel: isize = 4;
 -    const opcat_eq: isize = 5;
 -    const opcat_bit: isize = 6;
 -    const opcat_logic: isize = 7;
 -    const opcat_mod: isize = 8;
 -
 -    fn opcat(op: ast::BinOp) -> isize {
 -        match op.node {
 -          ast::BiAdd => opcat_add,
 -          ast::BiSub => opcat_sub,
 -          ast::BiMul => opcat_mult,
 -          ast::BiDiv => opcat_mult,
 -          ast::BiRem => opcat_mod,
 -          ast::BiAnd => opcat_logic,
 -          ast::BiOr => opcat_logic,
 -          ast::BiBitXor => opcat_bit,
 -          ast::BiBitAnd => opcat_bit,
 -          ast::BiBitOr => opcat_bit,
 -          ast::BiShl => opcat_shift,
 -          ast::BiShr => opcat_shift,
 -          ast::BiEq => opcat_eq,
 -          ast::BiNe => opcat_eq,
 -          ast::BiLt => opcat_rel,
 -          ast::BiLe => opcat_rel,
 -          ast::BiGe => opcat_rel,
 -          ast::BiGt => opcat_rel
 -        }
 -    }
 -
 -    fn tycat<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> isize {
 -        if type_is_simd(cx, ty) {
 -            return tycat(cx, simd_type(cx, ty))
 -        }
 -        match ty.sty {
 -          ty_char => tycat_char,
 -          ty_bool => tycat_bool,
 -          ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
 -          ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
 -          ty_ptr(_) => tycat_raw_ptr,
 -          _ => tycat_other
 -        }
 -    }
 -
 -    const t: bool = true;
 -    const f: bool = false;
 -
 -    let tbl = [
 -    //           +, -, *, shift, rel, ==, bit, logic, mod
 -    /*other*/   [f, f, f, f,     f,   f,  f,   f,     f],
 -    /*bool*/    [f, f, f, f,     t,   t,  t,   t,     f],
 -    /*char*/    [f, f, f, f,     t,   t,  f,   f,     f],
 -    /*isize*/     [t, t, t, t,     t,   t,  t,   f,     t],
 -    /*float*/   [t, t, t, f,     t,   t,  f,   f,     f],
 -    /*bot*/     [t, t, t, t,     t,   t,  t,   t,     t],
 -    /*raw ptr*/ [f, f, f, f,     t,   t,  f,   f,     f]];
 -
 -    return tbl[tycat(cx, ty) as usize ][opcat(op) as usize];
 -}
 -
  // Returns the repeat count for a repeating vector expression.
  pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> usize {
      match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.usize)) {
index f0e1427e6db60a80a258a62a7719c754663239de,0fba2e700a648121cc62342f374b96dfa26ee449..8f0387059e4a9d2418026461782f3d9c585f4008
@@@ -64,7 -64,7 +64,7 @@@ impl ToBits for u64 
  fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
      let (new_high_bits, new_low_bits) = bytes.to_bits();
  
-     if new_high_bits > Int::zero() {
+     if new_high_bits > T::zero() {
          panic!("numeric overflow occurred.")
      }
  
@@@ -139,15 -139,15 +139,15 @@@ impl FixedBuffer for FixedBuffer64 
              let buffer_remaining = size - self.buffer_idx;
              if input.len() >= buffer_remaining {
                      copy_memory(
 -                        &mut self.buffer[self.buffer_idx..size],
 -                        &input[..buffer_remaining]);
 +                        &input[..buffer_remaining],
 +                        &mut self.buffer[self.buffer_idx..size]);
                  self.buffer_idx = 0;
                  func(&self.buffer);
                  i += buffer_remaining;
              } else {
                  copy_memory(
 -                    &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()],
 -                    input);
 +                    input,
 +                    &mut self.buffer[self.buffer_idx..self.buffer_idx + input.len()]);
                  self.buffer_idx += input.len();
                  return;
              }
          // be empty.
          let input_remaining = input.len() - i;
          copy_memory(
 -            &mut self.buffer[..input_remaining],
 -            &input[i..]);
 +            &input[i..],
 +            &mut self.buffer[..input_remaining]);
          self.buffer_idx += input_remaining;
      }
  
@@@ -537,7 -537,7 +537,7 @@@ mod tests 
      use self::rand::isaac::IsaacRng;
      use serialize::hex::FromHex;
      use std::iter::repeat;
-     use std::num::Int;
+     use std::u64;
      use super::{Digest, Sha256, FixedBuffer};
  
      // A normal addition - no overflow occurs
      #[test]
      #[should_panic]
      fn test_add_bytes_to_bits_overflow() {
-         super::add_bytes_to_bits::<u64>(Int::max_value(), 1);
+         super::add_bytes_to_bits::<u64>(u64::MAX, 1);
      }
  
      struct Test {
index 586a1eb085c1c4e841dcba8ef76680913c872d23,b765c484bff64679d96bcb96639f24dd4d7e7480..e7443af3013aeff4519b5eae2585187b7257782f
@@@ -39,9 -39,8 +39,8 @@@ use util::ppaux::ty_to_string
  use util::nodemap::{FnvHashMap, NodeSet};
  use lint::{Level, Context, LintPass, LintArray, Lint};
  
 -use std::collections::BitSet;
 +use std::collections::{HashSet, BitSet};
  use std::collections::hash_map::Entry::{Occupied, Vacant};
- use std::num::SignedInt;
  use std::{cmp, slice};
  use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
  
@@@ -1437,9 -1436,6 +1436,9 @@@ pub struct MissingDoc 
      /// Stack of whether #[doc(hidden)] is set
      /// at each level which has lint attributes.
      doc_hidden_stack: Vec<bool>,
 +
 +    /// Private traits or trait items that leaked through. Don't check their methods.
 +    private_traits: HashSet<ast::NodeId>,
  }
  
  impl MissingDoc {
              struct_def_stack: vec!(),
              in_variant: false,
              doc_hidden_stack: vec!(false),
 +            private_traits: HashSet::new(),
          }
      }
  
@@@ -1535,46 -1530,18 +1534,46 @@@ impl LintPass for MissingDoc 
              ast::ItemMod(..) => "a module",
              ast::ItemEnum(..) => "an enum",
              ast::ItemStruct(..) => "a struct",
 -            ast::ItemTrait(..) => "a trait",
 +            ast::ItemTrait(_, _, _, ref items) => {
 +                // Issue #11592, traits are always considered exported, even when private.
 +                if it.vis == ast::Visibility::Inherited {
 +                    self.private_traits.insert(it.id);
 +                    for itm in items {
 +                        self.private_traits.insert(itm.id);
 +                    }
 +                    return
 +                }
 +                "a trait"
 +            },
              ast::ItemTy(..) => "a type alias",
 +            ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
 +                // If the trait is private, add the impl items to private_traits so they don't get
 +                // reported for missing docs.
 +                let real_trait = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
 +                match cx.tcx.map.find(real_trait.node) {
 +                    Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited {
 +                        for itm in impl_items {
 +                            self.private_traits.insert(itm.id);
 +                        }
 +                    },
 +                    _ => { }
 +                }
 +                return
 +            },
              _ => return
          };
 +
          self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
      }
  
      fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
 +        if self.private_traits.contains(&trait_item.id) { return }
 +
          let desc = match trait_item.node {
              ast::MethodTraitItem(..) => "a trait method",
              ast::TypeTraitItem(..) => "an associated type"
          };
 +
          self.check_missing_docs_attrs(cx, Some(trait_item.id),
                                        &trait_item.attrs,
                                        trait_item.span, desc);
index 8a61142c1731611c0cd896010d4883bb098fa18b,51da3fa6f8197f814bf09b8958fdbfea41afd204..16501ec280791d2886daffee7a0d39d9e71d4645
@@@ -79,6 -79,7 +79,6 @@@ type parameter)
  pub use self::LvaluePreference::*;
  pub use self::Expectation::*;
  pub use self::compare_method::compare_impl_method;
 -use self::IsBinopAssignment::*;
  use self::TupleArgumentsFlag::*;
  
  use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
@@@ -141,7 -142,6 +141,7 @@@ pub mod wf
  mod closure;
  mod callee;
  mod compare_method;
 +mod op;
  
  /// closures defined within the function.  For example:
  ///
@@@ -288,6 -288,15 +288,6 @@@ impl UnsafetyState 
      }
  }
  
 -/// Whether `check_binop` is part of an assignment or not.
 -/// Used to know whether we allow user overloads and to print
 -/// better messages on error.
 -#[derive(PartialEq)]
 -enum IsBinopAssignment{
 -    SimpleBinop,
 -    BinopAssignment,
 -}
 -
  #[derive(Clone)]
  pub struct FnCtxt<'a, 'tcx: 'a> {
      body_id: ast::NodeId,
@@@ -1316,18 -1325,14 +1316,18 @@@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> 
      /// version, this version will also select obligations if it seems
      /// useful, in an effort to get more type information.
      fn resolve_type_vars_if_possible(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
 +        debug!("resolve_type_vars_if_possible(ty={})", ty.repr(self.tcx()));
 +
          // No ty::infer()? Nothing needs doing.
          if !ty::type_has_ty_infer(ty) {
 +            debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
              return ty;
          }
  
          // If `ty` is a type variable, see whether we already know what it is.
          ty = self.infcx().resolve_type_vars_if_possible(&ty);
          if !ty::type_has_ty_infer(ty) {
 +            debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
              return ty;
          }
  
          vtable::select_new_fcx_obligations(self);
          ty = self.infcx().resolve_type_vars_if_possible(&ty);
          if !ty::type_has_ty_infer(ty) {
 +            debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
              return ty;
          }
  
          // indirect dependencies that don't seem worth tracking
          // precisely.
          vtable::select_fcx_obligations_where_possible(self);
 -        self.infcx().resolve_type_vars_if_possible(&ty)
 +        ty = self.infcx().resolve_type_vars_if_possible(&ty);
 +
 +        debug!("resolve_type_vars_if_possible: ty={}", ty.repr(self.tcx()));
 +        ty
      }
  
      /// Resolves all type variables in `t` and then, if any were left
@@@ -2091,17 -2092,24 +2091,17 @@@ fn make_overloaded_lvalue_return_type<'
  {
      match method {
          Some(method) => {
 -            let ref_ty = // invoked methods have all LB regions instantiated
 -                ty::no_late_bound_regions(
 -                    fcx.tcx(), &ty::ty_fn_ret(method.ty)).unwrap();
 -            match method_call {
 -                Some(method_call) => {
 -                    fcx.inh.method_map.borrow_mut().insert(method_call,
 -                                                           method);
 -                }
 -                None => {}
 -            }
 -            match ref_ty {
 -                ty::FnConverging(ref_ty) => {
 -                    ty::deref(ref_ty, true)
 -                }
 -                ty::FnDiverging => {
 -                    fcx.tcx().sess.bug("index/deref traits do not define a `!` return")
 -                }
 +            // extract method method return type, which will be &T;
 +            // all LB regions should have been instantiated during method lookup
 +            let ret_ty = ty::ty_fn_ret(method.ty);
 +            let ret_ty = ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap();
 +
 +            if let Some(method_call) = method_call {
 +                fcx.inh.method_map.borrow_mut().insert(method_call, method);
              }
 +
 +            // method returns &T, but the type as visible to user is T, so deref
 +            ty::deref(ret_ty, true)
          }
          None => None,
      }
@@@ -2230,6 -2238,7 +2230,6 @@@ fn check_method_argument_types<'a, 'tcx
                                           method_fn_ty: Ty<'tcx>,
                                           callee_expr: &'tcx ast::Expr,
                                           args_no_rcvr: &'tcx [P<ast::Expr>],
 -                                         autoref_args: AutorefArgs,
                                           tuple_arguments: TupleArgumentsFlag,
                                           expected: Expectation<'tcx>)
                                           -> ty::FnOutput<'tcx> {
                               &err_inputs[..],
                               &[],
                               args_no_rcvr,
 -                             autoref_args,
                               false,
                               tuple_arguments);
          ty::FnConverging(fcx.tcx().types.err)
                                       &fty.sig.0.inputs[1..],
                                       &expected_arg_tys[..],
                                       args_no_rcvr,
 -                                     autoref_args,
                                       fty.sig.0.variadic,
                                       tuple_arguments);
                  fty.sig.0.output
@@@ -2282,6 -2293,7 +2282,6 @@@ fn check_argument_types<'a, 'tcx>(fcx: 
                                    fn_inputs: &[Ty<'tcx>],
                                    expected_arg_tys: &[Ty<'tcx>],
                                    args: &'tcx [P<ast::Expr>],
 -                                  autoref_args: AutorefArgs,
                                    variadic: bool,
                                    tuple_arguments: TupleArgumentsFlag) {
      let tcx = fcx.ccx.tcx;
  
              if is_block == check_blocks {
                  debug!("checking the argument");
 -                let mut formal_ty = formal_tys[i];
 -
 -                match autoref_args {
 -                    AutorefArgs::Yes => {
 -                        match formal_ty.sty {
 -                            ty::ty_rptr(_, mt) => formal_ty = mt.ty,
 -                            ty::ty_err => (),
 -                            _ => {
 -                                // So we hit this case when one implements the
 -                                // operator traits but leaves an argument as
 -                                // just T instead of &T. We'll catch it in the
 -                                // mismatch impl/trait method phase no need to
 -                                // ICE here.
 -                                // See: #11450
 -                                formal_ty = tcx.types.err;
 -                            }
 -                        }
 -                    }
 -                    AutorefArgs::No => {}
 -                }
 +                let formal_ty = formal_tys[i];
  
                  // The special-cased logic below has three functions:
                  // 1. Provide as good of an expected type as possible.
@@@ -2591,6 -2622,14 +2591,6 @@@ pub fn impl_self_ty<'a, 'tcx>(fcx: &FnC
      TypeAndSubsts { substs: substs, ty: substd_ty }
  }
  
 -// Controls whether the arguments are automatically referenced. This is useful
 -// for overloaded binary and unary operators.
 -#[derive(Copy, PartialEq)]
 -pub enum AutorefArgs {
 -    Yes,
 -    No,
 -}
 -
  /// Controls whether the arguments are tupled. This is used for the call
  /// operator.
  ///
@@@ -2716,6 -2755,7 +2716,6 @@@ fn check_expr_with_unifier<'a, 'tcx, F>
                                                   fn_ty,
                                                   expr,
                                                   &args[1..],
 -                                                 AutorefArgs::No,
                                                   DontTupleArguments,
                                                   expected);
  
          fcx.write_ty(id, if_ty);
      }
  
 -    fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
 -                                     op_ex: &'tcx ast::Expr,
 -                                     lhs_ty: Ty<'tcx>,
 -                                     opname: ast::Name,
 -                                     trait_did: Option<ast::DefId>,
 -                                     lhs: &'a ast::Expr,
 -                                     rhs: Option<&'tcx P<ast::Expr>>,
 -                                     unbound_method: F,
 -                                     autoref_args: AutorefArgs) -> Ty<'tcx> where
 -        F: FnOnce(),
 -    {
 -        let method = match trait_did {
 -            Some(trait_did) => {
 -                // We do eager coercions to make using operators
 -                // more ergonomic:
 -                //
 -                // - If the input is of type &'a T (resp. &'a mut T),
 -                //   then reborrow it to &'b T (resp. &'b mut T) where
 -                //   'b <= 'a.  This makes things like `x == y`, where
 -                //   `x` and `y` are both region pointers, work.  We
 -                //   could also solve this with variance or different
 -                //   traits that don't force left and right to have same
 -                //   type.
 -                let (adj_ty, adjustment) = match lhs_ty.sty {
 -                    ty::ty_rptr(r_in, mt) => {
 -                        let r_adj = fcx.infcx().next_region_var(infer::Autoref(lhs.span));
 -                        fcx.mk_subr(infer::Reborrow(lhs.span), r_adj, *r_in);
 -                        let adjusted_ty = ty::mk_rptr(fcx.tcx(), fcx.tcx().mk_region(r_adj), mt);
 -                        let autoptr = ty::AutoPtr(r_adj, mt.mutbl, None);
 -                        let adjustment = ty::AutoDerefRef { autoderefs: 1, autoref: Some(autoptr) };
 -                        (adjusted_ty, adjustment)
 -                    }
 -                    _ => {
 -                        (lhs_ty, ty::AutoDerefRef { autoderefs: 0, autoref: None })
 -                    }
 -                };
 -
 -                debug!("adjusted_ty={} adjustment={:?}",
 -                       adj_ty.repr(fcx.tcx()),
 -                       adjustment);
 -
 -                method::lookup_in_trait_adjusted(fcx, op_ex.span, Some(lhs), opname,
 -                                                 trait_did, adjustment, adj_ty, None)
 -            }
 -            None => None
 -        };
 -        let args = match rhs {
 -            Some(rhs) => slice::ref_slice(rhs),
 -            None => &[][..]
 -        };
 -        match method {
 -            Some(method) => {
 -                let method_ty = method.ty;
 -                // HACK(eddyb) Fully qualified path to work around a resolve bug.
 -                let method_call = ::middle::ty::MethodCall::expr(op_ex.id);
 -                fcx.inh.method_map.borrow_mut().insert(method_call, method);
 -                match check_method_argument_types(fcx,
 -                                                  op_ex.span,
 -                                                  method_ty,
 -                                                  op_ex,
 -                                                  args,
 -                                                  autoref_args,
 -                                                  DontTupleArguments,
 -                                                  NoExpectation) {
 -                    ty::FnConverging(result_type) => result_type,
 -                    ty::FnDiverging => fcx.tcx().types.err
 -                }
 -            }
 -            None => {
 -                unbound_method();
 -                // Check the args anyway
 -                // so we get all the error messages
 -                let expected_ty = fcx.tcx().types.err;
 -                check_method_argument_types(fcx,
 -                                            op_ex.span,
 -                                            expected_ty,
 -                                            op_ex,
 -                                            args,
 -                                            autoref_args,
 -                                            DontTupleArguments,
 -                                            NoExpectation);
 -                fcx.tcx().types.err
 -            }
 -        }
 -    }
 -
 -    // could be either an expr_binop or an expr_assign_binop
 -    fn check_binop<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
 -                            expr: &'tcx ast::Expr,
 -                            op: ast::BinOp,
 -                            lhs: &'tcx ast::Expr,
 -                            rhs: &'tcx P<ast::Expr>,
 -                            is_binop_assignment: IsBinopAssignment) {
 -        let tcx = fcx.ccx.tcx;
 -
 -        let lvalue_pref = match is_binop_assignment {
 -            BinopAssignment => PreferMutLvalue,
 -            SimpleBinop => NoPreference
 -        };
 -        check_expr_with_lvalue_pref(fcx, lhs, lvalue_pref);
 -
 -        // Callee does bot / err checking
 -        let lhs_t =
 -            structurally_resolve_type_or_else(fcx, lhs.span, fcx.expr_ty(lhs), || {
 -                if ast_util::is_symmetric_binop(op.node) {
 -                    // Try RHS first
 -                    check_expr(fcx, &**rhs);
 -                    fcx.expr_ty(&**rhs)
 -                } else {
 -                    fcx.tcx().types.err
 -                }
 -            });
 -
 -        if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op.node) {
 -            // Shift is a special case: rhs must be usize, no matter what lhs is
 -            check_expr(fcx, &**rhs);
 -            let rhs_ty = fcx.expr_ty(&**rhs);
 -            let rhs_ty = structurally_resolved_type(fcx, rhs.span, rhs_ty);
 -            if ty::type_is_integral(rhs_ty) {
 -                fcx.write_ty(expr.id, lhs_t);
 -            } else {
 -                fcx.type_error_message(
 -                    expr.span,
 -                    |actual| {
 -                        format!(
 -                            "right-hand-side of a shift operation must have integral type, \
 -                             not `{}`",
 -                            actual)
 -                    },
 -                    rhs_ty,
 -                    None);
 -                fcx.write_ty(expr.id, fcx.tcx().types.err);
 -            }
 -            return;
 -        }
 -
 -        if ty::is_binopable(tcx, lhs_t, op) {
 -            let tvar = fcx.infcx().next_ty_var();
 -            demand::suptype(fcx, expr.span, tvar, lhs_t);
 -            check_expr_has_type(fcx, &**rhs, tvar);
 -
 -            let result_t = match op.node {
 -                ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe |
 -                ast::BiGt => {
 -                    if ty::type_is_simd(tcx, lhs_t) {
 -                        if ty::type_is_fp(ty::simd_type(tcx, lhs_t)) {
 -                            fcx.type_error_message(expr.span,
 -                                |actual| {
 -                                    format!("binary comparison \
 -                                             operation `{}` not \
 -                                             supported for floating \
 -                                             point SIMD vector `{}`",
 -                                            ast_util::binop_to_string(op.node),
 -                                            actual)
 -                                },
 -                                lhs_t,
 -                                None
 -                            );
 -                            fcx.tcx().types.err
 -                        } else {
 -                            lhs_t
 -                        }
 -                    } else {
 -                        fcx.tcx().types.bool
 -                    }
 -                },
 -                _ => lhs_t,
 -            };
 -
 -            fcx.write_ty(expr.id, result_t);
 -            return;
 -        }
 -
 -        if op.node == ast::BiOr || op.node == ast::BiAnd {
 -            // This is an error; one of the operands must have the wrong
 -            // type
 -            fcx.write_error(expr.id);
 -            fcx.write_error(rhs.id);
 -            fcx.type_error_message(expr.span,
 -                                   |actual| {
 -                    format!("binary operation `{}` cannot be applied \
 -                             to type `{}`",
 -                            ast_util::binop_to_string(op.node),
 -                            actual)
 -                },
 -                lhs_t,
 -                None)
 -        }
 -
 -        // Check for overloaded operators if not an assignment.
 -        let result_t = if is_binop_assignment == SimpleBinop {
 -            check_user_binop(fcx, expr, lhs, lhs_t, op, rhs)
 -        } else {
 -            fcx.type_error_message(expr.span,
 -                                   |actual| {
 -                                        format!("binary assignment \
 -                                                 operation `{}=` \
 -                                                 cannot be applied to \
 -                                                 type `{}`",
 -                                                ast_util::binop_to_string(op.node),
 -                                                actual)
 -                                   },
 -                                   lhs_t,
 -                                   None);
 -            check_expr(fcx, &**rhs);
 -            fcx.tcx().types.err
 -        };
 -
 -        fcx.write_ty(expr.id, result_t);
 -        if ty::type_is_error(result_t) {
 -            fcx.write_ty(rhs.id, result_t);
 -        }
 -    }
 -
 -    fn check_user_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 -                                  ex: &'tcx ast::Expr,
 -                                  lhs_expr: &'tcx ast::Expr,
 -                                  lhs_resolved_t: Ty<'tcx>,
 -                                  op: ast::BinOp,
 -                                  rhs: &'tcx P<ast::Expr>) -> Ty<'tcx> {
 -        let tcx = fcx.ccx.tcx;
 -        let lang = &tcx.lang_items;
 -        let (name, trait_did) = match op.node {
 -            ast::BiAdd => ("add", lang.add_trait()),
 -            ast::BiSub => ("sub", lang.sub_trait()),
 -            ast::BiMul => ("mul", lang.mul_trait()),
 -            ast::BiDiv => ("div", lang.div_trait()),
 -            ast::BiRem => ("rem", lang.rem_trait()),
 -            ast::BiBitXor => ("bitxor", lang.bitxor_trait()),
 -            ast::BiBitAnd => ("bitand", lang.bitand_trait()),
 -            ast::BiBitOr => ("bitor", lang.bitor_trait()),
 -            ast::BiShl => ("shl", lang.shl_trait()),
 -            ast::BiShr => ("shr", lang.shr_trait()),
 -            ast::BiLt => ("lt", lang.ord_trait()),
 -            ast::BiLe => ("le", lang.ord_trait()),
 -            ast::BiGe => ("ge", lang.ord_trait()),
 -            ast::BiGt => ("gt", lang.ord_trait()),
 -            ast::BiEq => ("eq", lang.eq_trait()),
 -            ast::BiNe => ("ne", lang.eq_trait()),
 -            ast::BiAnd | ast::BiOr => {
 -                check_expr(fcx, &**rhs);
 -                return tcx.types.err;
 -            }
 -        };
 -        lookup_op_method(fcx, ex, lhs_resolved_t, token::intern(name),
 -                         trait_did, lhs_expr, Some(rhs), || {
 -            fcx.type_error_message(ex.span, |actual| {
 -                format!("binary operation `{}` cannot be applied to type `{}`",
 -                        ast_util::binop_to_string(op.node),
 -                        actual)
 -            }, lhs_resolved_t, None)
 -        }, if ast_util::is_by_value_binop(op.node) { AutorefArgs::No } else { AutorefArgs::Yes })
 -    }
 -
 -    fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 -                                 op_str: &str,
 -                                 mname: &str,
 -                                 trait_did: Option<ast::DefId>,
 -                                 ex: &'tcx ast::Expr,
 -                                 rhs_expr: &'tcx ast::Expr,
 -                                 rhs_t: Ty<'tcx>,
 -                                 op: ast::UnOp) -> Ty<'tcx> {
 -       lookup_op_method(fcx, ex, rhs_t, token::intern(mname),
 -                        trait_did, rhs_expr, None, || {
 -            fcx.type_error_message(ex.span, |actual| {
 -                format!("cannot apply unary operator `{}` to type `{}`",
 -                        op_str, actual)
 -            }, rhs_t, None);
 -        }, if ast_util::is_by_value_unop(op) { AutorefArgs::No } else { AutorefArgs::Yes })
 -    }
 -
      // Check field access expressions
      fn check_field<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
                              expr: &'tcx ast::Expr,
          fcx.write_ty(id, typ);
        }
        ast::ExprBinary(op, ref lhs, ref rhs) => {
 -        check_binop(fcx, expr, op, &**lhs, rhs, SimpleBinop);
 -
 -        let lhs_ty = fcx.expr_ty(&**lhs);
 -        let rhs_ty = fcx.expr_ty(&**rhs);
 -        if ty::type_is_error(lhs_ty) ||
 -            ty::type_is_error(rhs_ty) {
 -            fcx.write_error(id);
 -        }
 +        op::check_binop(fcx, expr, op, lhs, rhs);
        }
        ast::ExprAssignOp(op, ref lhs, ref rhs) => {
 -        check_binop(fcx, expr, op, &**lhs, rhs, BinopAssignment);
 -
 -        let lhs_t = fcx.expr_ty(&**lhs);
 -        let result_t = fcx.expr_ty(expr);
 -        demand::suptype(fcx, expr.span, result_t, lhs_t);
 -
 -        let tcx = fcx.tcx();
 -        if !ty::expr_is_lval(tcx, &**lhs) {
 -            span_err!(tcx.sess, lhs.span, E0067, "illegal left-hand side expression");
 -        }
 -
 -        fcx.require_expr_have_sized_type(&**lhs, traits::AssignmentLhsSized);
 -
 -        // Overwrite result of check_binop...this preserves existing behavior
 -        // but seems quite dubious with regard to user-defined methods
 -        // and so forth. - Niko
 -        if !ty::type_is_error(result_t) {
 -            fcx.write_nil(expr.id);
 -        }
 +        op::check_binop_assign(fcx, expr, op, lhs, rhs);
        }
        ast::ExprUnary(unop, ref oprnd) => {
          let expected_inner = expected.to_option(fcx).map_or(NoExpectation, |ty| {
                                                           oprnd_t);
                      if !(ty::type_is_integral(oprnd_t) ||
                           oprnd_t.sty == ty::ty_bool) {
 -                        oprnd_t = check_user_unop(fcx, "!", "not",
 -                                                  tcx.lang_items.not_trait(),
 -                                                  expr, &**oprnd, oprnd_t, unop);
 +                        oprnd_t = op::check_user_unop(fcx, "!", "not",
 +                                                      tcx.lang_items.not_trait(),
 +                                                      expr, &**oprnd, oprnd_t, unop);
                      }
                  }
                  ast::UnNeg => {
                                                           oprnd_t);
                      if !(ty::type_is_integral(oprnd_t) ||
                           ty::type_is_fp(oprnd_t)) {
 -                        oprnd_t = check_user_unop(fcx, "-", "neg",
 -                                                  tcx.lang_items.neg_trait(),
 -                                                  expr, &**oprnd, oprnd_t, unop);
 +                        oprnd_t = op::check_user_unop(fcx, "-", "neg",
 +                                                      tcx.lang_items.neg_trait(),
 +                                                      expr, &**oprnd, oprnd_t, unop);
                      }
                  }
              }
  
                    match result {
                        Some((index_ty, element_ty)) => {
 -                          // FIXME: we've already checked idx above, we should
 -                          // probably just demand subtype or something here.
 -                          check_expr_has_type(fcx, &**idx, index_ty);
 +                          let idx_expr_ty = fcx.expr_ty(idx);
 +                          demand::eqtype(fcx, expr.span, index_ty, idx_expr_ty);
                            fcx.write_ty(id, element_ty);
                        }
                        _ => {
@@@ -4285,7 -4622,7 +4285,7 @@@ pub fn check_enum_variants<'a,'tcx>(ccx
                            id: ast::NodeId,
                            hint: attr::ReprAttr)
                            -> Vec<Rc<ty::VariantInfo<'tcx>>> {
-         use std::num::Int;
+         #![allow(trivial_numeric_casts)]
  
          let rty = ty::node_id_to_type(ccx.tcx, id);
          let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
@@@ -5080,21 -5417,7 +5080,21 @@@ pub fn check_intrinsic_type(ccx: &Crate
                     mutbl: ast::MutImmutable
                 }))
              }
 -            "copy" | "copy_nonoverlapping" |
 +            "copy" | "copy_nonoverlapping" => {
 +              (1,
 +               vec!(
 +                  ty::mk_ptr(tcx, ty::mt {
 +                      ty: param(ccx, 0),
 +                      mutbl: ast::MutImmutable
 +                  }),
 +                  ty::mk_ptr(tcx, ty::mt {
 +                      ty: param(ccx, 0),
 +                      mutbl: ast::MutMutable
 +                  }),
 +                  tcx.types.usize,
 +               ),
 +               ty::mk_nil(tcx))
 +            }
              "volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
                (1,
                 vec!(
diff --combined src/libstd/io/cursor.rs
index c8a41beecbc2248d78cf5178954eb0c1a4a1b41f,43b5cbbafdd415d4b353dec2c63e28e772eeee2b..d8e403376bdc734a6d7a4db7988cf785c675d6ea
@@@ -14,7 -14,6 +14,6 @@@ use io::prelude::*
  use cmp;
  use io::{self, SeekFrom, Error, ErrorKind};
  use iter::repeat;
- use num::Int;
  use slice;
  
  /// A `Cursor` is a type which wraps a non-I/O object to provide a `Seek`
@@@ -151,7 -150,7 +150,7 @@@ impl Write for Cursor<Vec<u8>> 
          // there (left), and what will be appended on the end (right)
          let space = self.inner.len() - pos as usize;
          let (left, right) = buf.split_at(cmp::min(space, buf.len()));
 -        slice::bytes::copy_memory(&mut self.inner[(pos as usize)..], left);
 +        slice::bytes::copy_memory(left, &mut self.inner[(pos as usize)..]);
          self.inner.push_all(right);
  
          // Bump us forward
index 8f788988e557adfd7f8cfe481a397b9a4b03492a,91aa0622e5a043adf589548a8d420e46fef61017..987a12293da50c0a465cb43c9d3037b76117301f
@@@ -37,6 -37,7 +37,7 @@@ use fmt
  use hash::{Hash, Hasher};
  use iter::{FromIterator, IntoIterator};
  use mem;
+ #[allow(deprecated)] // Int
  use num::Int;
  use ops;
  use slice;
@@@ -344,8 -345,8 +345,8 @@@ impl Wtf8Buf 
                  Some((surrogate_pos, _)) => {
                      pos = surrogate_pos + 3;
                      slice::bytes::copy_memory(
 +                        UTF8_REPLACEMENT_CHARACTER,
                          &mut self.bytes[surrogate_pos .. pos],
 -                        UTF8_REPLACEMENT_CHARACTER
                      );
                  },
                  None => return unsafe { String::from_utf8_unchecked(self.bytes) }