Skip to content

Commit

Permalink
Auto merge of #37937 - GuillaumeGomez:rollup, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

- Successful merges: #37442, #37760, #37836, #37851, #37859, #37913, #37925
- Failed merges:
  • Loading branch information
bors authored Nov 23, 2016
2 parents 9fba8df + d2c600a commit 127a83d
Show file tree
Hide file tree
Showing 11 changed files with 415 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ the language.

[**The Rust Reference**][ref]. While Rust does not have a
specification, the reference tries to describe its working in
detail. It tends to be out of date.
detail. It is accurate, but not necessarily complete.

[**Standard Library API Reference**][api]. Documentation for the
standard library.
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use syntax::symbol::{Symbol, InternedString};
use syntax_pos::{DUMMY_SP, Span};

use rustc_const_math::ConstInt;
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;

use hir;
use hir::itemlikevisit::ItemLikeVisitor;
Expand Down Expand Up @@ -1887,7 +1888,7 @@ impl<'tcx> TyS<'tcx> {
/// Iterator that walks the immediate children of `self`. Hence
/// `Foo<Bar<i32>, u32>` yields the sequence `[Bar<i32>, u32]`
/// (but not `i32`, like `walk`).
pub fn walk_shallow(&'tcx self) -> IntoIter<Ty<'tcx>> {
pub fn walk_shallow(&'tcx self) -> AccIntoIter<walk::TypeWalkerArray<'tcx>> {
walk::walk_shallow(self)
}

Expand Down
21 changes: 13 additions & 8 deletions src/librustc/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@
//! WARNING: this does not keep track of the region depth.
use ty::{self, Ty};
use std::iter::Iterator;
use std::vec::IntoIter;
use rustc_data_structures::small_vec::SmallVec;
use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;

// The TypeWalker's stack is hot enough that it's worth going to some effort to
// avoid heap allocations.
pub type TypeWalkerArray<'tcx> = [Ty<'tcx>; 8];
pub type TypeWalkerStack<'tcx> = SmallVec<TypeWalkerArray<'tcx>>;

pub struct TypeWalker<'tcx> {
stack: Vec<Ty<'tcx>>,
stack: TypeWalkerStack<'tcx>,
last_subtree: usize,
}

impl<'tcx> TypeWalker<'tcx> {
pub fn new(ty: Ty<'tcx>) -> TypeWalker<'tcx> {
TypeWalker { stack: vec![ty], last_subtree: 1, }
TypeWalker { stack: SmallVec::one(ty), last_subtree: 1, }
}

/// Skips the subtree of types corresponding to the last type
Expand Down Expand Up @@ -61,8 +66,8 @@ impl<'tcx> Iterator for TypeWalker<'tcx> {
}
}

pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
let mut stack = vec![];
pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> AccIntoIter<TypeWalkerArray<'tcx>> {
let mut stack = SmallVec::new();
push_subtypes(&mut stack, ty);
stack.into_iter()
}
Expand All @@ -73,7 +78,7 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
// known to be significant to any code, but it seems like the
// natural order one would expect (basically, the order of the
// types as they are written).
fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
match parent_ty.sty {
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => {
Expand Down Expand Up @@ -112,7 +117,7 @@ fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
}
}

fn push_sig_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, sig: &ty::PolyFnSig<'tcx>) {
fn push_sig_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, sig: &ty::PolyFnSig<'tcx>) {
stack.push(sig.0.output);
stack.extend(sig.0.inputs.iter().cloned().rev());
}
12 changes: 12 additions & 0 deletions src/librustc_data_structures/small_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,18 @@ impl<A: Array> SmallVec<A> {
self.set_len(len + 1);
}
}

pub fn truncate(&mut self, len: usize) {
unsafe {
while len < self.len() {
// Decrement len before the drop_in_place(), so a panic on Drop
// doesn't re-drop the just-failed value.
let newlen = self.len() - 1;
self.set_len(newlen);
::std::ptr::drop_in_place(self.get_unchecked_mut(newlen));
}
}
}
}

impl<A: Array> Deref for SmallVec<A> {
Expand Down
44 changes: 42 additions & 2 deletions src/librustc_typeck/check/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ enum CastError {
/// Cast of thin to fat raw ptr (eg. `*const () as *const [u8]`)
SizedUnsizedCast,
IllegalCast,
NeedDeref,
NeedViaPtr,
NeedViaThinPtr,
NeedViaInt,
Expand Down Expand Up @@ -138,6 +139,25 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {

fn report_cast_error(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>, e: CastError) {
match e {
CastError::NeedDeref => {
let cast_ty = fcx.ty_to_string(self.cast_ty);
let mut err = fcx.type_error_struct(self.cast_span,
|actual| {
format!("casting `{}` as `{}` is invalid",
actual,
cast_ty)
},
self.expr_ty);
err.span_label(self.expr.span,
&format!("cannot cast `{}` as `{}`",
fcx.ty_to_string(self.expr_ty),
cast_ty));
if let Ok(snippet) = fcx.sess().codemap().span_to_snippet(self.expr.span) {
err.span_label(self.expr.span,
&format!("did you mean `*{}`?", snippet));
}
err.emit();
}
CastError::NeedViaThinPtr |
CastError::NeedViaPtr => {
let mut err = fcx.type_error_struct(self.span,
Expand Down Expand Up @@ -390,8 +410,28 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
(Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
(FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
(RPtr(_), Int(_)) |
(RPtr(_), Float) => Err(CastError::NeedViaPtr),
(RPtr(p), Int(_)) |
(RPtr(p), Float) => {
match p.ty.sty {
ty::TypeVariants::TyInt(_) |
ty::TypeVariants::TyUint(_) |
ty::TypeVariants::TyFloat(_) => {
Err(CastError::NeedDeref)
}
ty::TypeVariants::TyInfer(t) => {
match t {
ty::InferTy::IntVar(_) |
ty::InferTy::FloatVar(_) |
ty::InferTy::FreshIntTy(_) |
ty::InferTy::FreshFloatTy(_) => {
Err(CastError::NeedDeref)
}
_ => Err(CastError::NeedViaPtr),
}
}
_ => Err(CastError::NeedViaPtr),
}
}
// * -> ptr
(Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
Expand Down
18 changes: 13 additions & 5 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,17 +546,23 @@ pub fn current_exe() -> io::Result<PathBuf> {
os_imp::current_exe()
}

/// An iterator over the arguments of a process, yielding a `String` value
/// An iterator over the arguments of a process, yielding a [`String`] value
/// for each argument.
///
/// This structure is created through the `std::env::args` method.
/// This structure is created through the [`std::env::args`] method.
///
/// [`String`]: ../string/struct.String.html
/// [`std::env::args`]: ./fn.args.html
#[stable(feature = "env", since = "1.0.0")]
pub struct Args { inner: ArgsOs }

/// An iterator over the arguments of a process, yielding an `OsString` value
/// An iterator over the arguments of a process, yielding an [`OsString`] value
/// for each argument.
///
/// This structure is created through the `std::env::args_os` method.
/// This structure is created through the [`std::env::args_os`] method.
///
/// [`OsString`]: ../ffi/struct.OsString.html
/// [`std::env::args_os`]: ./fn.args_os.html
#[stable(feature = "env", since = "1.0.0")]
pub struct ArgsOs { inner: sys::args::Args }

Expand All @@ -571,7 +577,7 @@ pub struct ArgsOs { inner: sys::args::Args }
///
/// The returned iterator will panic during iteration if any argument to the
/// process is not valid unicode. If this is not desired,
/// use the `args_os` function instead.
/// use the [`args_os`] function instead.
///
/// # Examples
///
Expand All @@ -583,6 +589,8 @@ pub struct ArgsOs { inner: sys::args::Args }
/// println!("{}", argument);
/// }
/// ```
///
/// [`args_os`]: ./fn.args_os.html
#[stable(feature = "env", since = "1.0.0")]
pub fn args() -> Args {
Args { inner: args_os() }
Expand Down
46 changes: 46 additions & 0 deletions src/libstd/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ impl SocketAddr {

impl SocketAddrV4 {
/// Creates a new socket address from the (ip, port) pair.
///
/// # Examples
///
/// ```
/// use std::net::{SocketAddrV4, Ipv4Addr};
///
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
SocketAddrV4 {
Expand All @@ -207,6 +215,15 @@ impl SocketAddrV4 {
}

/// Returns the IP address associated with this socket address.
///
/// # Examples
///
/// ```
/// use std::net::{SocketAddrV4, Ipv4Addr};
///
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn ip(&self) -> &Ipv4Addr {
unsafe {
Expand All @@ -215,18 +232,47 @@ impl SocketAddrV4 {
}

/// Change the IP address associated with this socket address.
///
/// # Examples
///
/// ```
/// use std::net::{SocketAddrV4, Ipv4Addr};
///
/// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
/// socket.set_ip(Ipv4Addr::new(192, 168, 0, 1));
/// assert_eq!(socket.ip(), &Ipv4Addr::new(192, 168, 0, 1));
/// ```
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_ip(&mut self, new_ip: Ipv4Addr) {
self.inner.sin_addr = *new_ip.as_inner()
}

/// Returns the port number associated with this socket address.
///
/// # Examples
///
/// ```
/// use std::net::{SocketAddrV4, Ipv4Addr};
///
/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
/// assert_eq!(socket.port(), 8080);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 {
ntoh(self.inner.sin_port)
}

/// Change the port number associated with this socket address.
///
/// # Examples
///
/// ```
/// use std::net::{SocketAddrV4, Ipv4Addr};
///
/// let mut socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
/// socket.set_port(4242);
/// assert_eq!(socket.port(), 4242);
/// ```
#[stable(feature = "sockaddr_setters", since = "1.9.0")]
pub fn set_port(&mut self, new_port: u16) {
self.inner.sin_port = hton(new_port);
Expand Down
5 changes: 5 additions & 0 deletions src/test/compile-fail/cast-rfc0401.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,9 @@ fn main()
let _ = cf as *const Bar;
//~^ ERROR casting
//~^^ NOTE vtable kinds

vec![0.0].iter().map(|s| s as f32).collect::<Vec<f32>>();
//~^ ERROR casting `&{float}` as `f32` is invalid
//~| NOTE cannot cast `&{float}` as `f32`
//~| NOTE did you mean `*s`?
}
Loading

0 comments on commit 127a83d

Please sign in to comment.