Skip to content

Commit

Permalink
Auto merge of #33376 - Manishearth:rollup, r=Manishearth
Browse files Browse the repository at this point in the history
Rollup of 14 pull requests

- Successful merges: #33277, #33294, #33314, #33322, #33333, #33338, #33339, #33340, #33343, #33357, #33363, #33365, #33371, #33372
- Failed merges:
  • Loading branch information
bors committed May 4, 2016
2 parents 3157691 + 631e7b4 commit 7a0ccc4
Show file tree
Hide file tree
Showing 17 changed files with 305 additions and 95 deletions.
8 changes: 4 additions & 4 deletions src/doc/book/getting-started.md
Expand Up @@ -8,7 +8,7 @@ we’ll talk about Cargo, Rust’s build system and package manager.

The first step to using Rust is to install it. Generally speaking, you’ll need
an Internet connection to run the commands in this section, as we’ll be
downloading Rust from the internet.
downloading Rust from the Internet.

We’ll be showing off a number of commands using a terminal, and those lines all
start with `$`. We don't need to type in the `$`s, they are there to indicate
Expand Down Expand Up @@ -399,13 +399,13 @@ Let’s convert the Hello World program to Cargo. To Cargo-fy a project, you nee
to do three things:

1. Put your source file in the right directory.
2. Get rid of the old executable (`main.exe` on Windows, `main` everywhere else)
and make a new one.
2. Get rid of the old executable (`main.exe` on Windows, `main` everywhere
else).
3. Make a Cargo configuration file.

Let's get started!

### Creating a new Executable and Source Directory
### Creating a Source Directory and Removing the Old Executable

First, go back to your terminal, move to your *hello_world* directory, and
enter the following commands:
Expand Down
13 changes: 9 additions & 4 deletions src/libcollections/fmt.rs
Expand Up @@ -333,7 +333,7 @@
//! precision := count | '*'
//! type := identifier | ''
//! count := parameter | integer
//! parameter := integer '$'
//! parameter := argument '$'
//! ```
//!
//! # Formatting Parameters
Expand Down Expand Up @@ -403,11 +403,12 @@
//! println!("Hello {:5}!", "x");
//! println!("Hello {:1$}!", "x", 5);
//! println!("Hello {1:0$}!", 5, "x");
//! println!("Hello {:width$}!", "x", width = 5);
//! ```
//!
//! Referring to an argument with the dollar syntax does not affect the "next
//! argument" counter, so it's usually a good idea to refer to all arguments by
//! their position explicitly.
//! argument" counter, so it's usually a good idea to refer to arguments by
//! position, or use named arguments.
//!
//! ## Precision
//!
Expand All @@ -426,7 +427,7 @@
//!
//! the integer `N` itself is the precision.
//!
//! 2. An integer followed by dollar sign `.N$`:
//! 2. An integer or name followed by dollar sign `.N$`:
//!
//! use format *argument* `N` (which must be a `usize`) as the precision.
//!
Expand Down Expand Up @@ -456,6 +457,10 @@
//! // Hello {next arg (x)} is {arg 2 (0.01) with precision
//! // specified in its predecessor (5)}
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
//!
//! // Hello {next arg (x)} is {arg "number" (0.01) with precision specified
//! // in arg "prec" (5)}
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
//! ```
//!
//! All print the same thing:
Expand Down
1 change: 1 addition & 0 deletions src/libcore/mem.rs
Expand Up @@ -110,6 +110,7 @@ pub use intrinsics::transmute;
/// }
/// }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn forget<T>(t: T) {
unsafe { intrinsics::forget(t) }
Expand Down
77 changes: 76 additions & 1 deletion src/librustc_borrowck/diagnostics.rs
Expand Up @@ -314,6 +314,82 @@ let c = &i; // still ok!
```
"##,

E0501: r##"
This error indicates that a mutable variable is being used while it is still
captured by a closure. Because the closure has borrowed the variable, it is not
available for use until the closure goes out of scope.
Note that a capture will either move or borrow a variable, but in this
situation, the closure is borrowing the variable. Take a look at
http://rustbyexample.com/fn/closures/capture.html for more information about
capturing.
Example of erroneous code:
```compile_fail
fn inside_closure(x: &mut i32) {
// Actions which require unique access
}
fn outside_closure(x: &mut i32) {
// Actions which require unique access
}
fn foo(a: &mut i32) {
let bar = || {
inside_closure(a)
};
outside_closure(a); // error: cannot borrow `*a` as mutable because previous
// closure requires unique access.
}
```
To fix this error, you can place the closure in its own scope:
```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
{
let bar = || {
inside_closure(a)
};
} // borrow on `a` ends.
outside_closure(a); // ok!
}
```
Or you can pass the variable as a parameter to the closure:
```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
let bar = |s: &mut i32| {
inside_closure(s)
};
outside_closure(a);
bar(a);
}
```
It may be possible to define the closure later:
```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}
fn foo(a: &mut i32) {
outside_closure(a);
let bar = || {
inside_closure(a)
};
}
```
"##,

E0507: r##"
You tried to move out of a value which was borrowed. Erroneous code example:
Expand Down Expand Up @@ -436,7 +512,6 @@ register_diagnostics! {
E0388, // {} in a static location
E0389, // {} in a `&` reference
E0500, // closure requires unique access to `..` but .. is already borrowed
E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
E0503, // cannot use `..` because it was mutably borrowed
E0504, // cannot move `..` into closure because it is borrowed
Expand Down
85 changes: 37 additions & 48 deletions src/librustc_const_eval/eval.rs
Expand Up @@ -377,13 +377,6 @@ pub enum ErrKind {
NotOn(ConstVal),
CallOn(ConstVal),

NegateWithOverflow(i64),
AddiWithOverflow(i64, i64),
SubiWithOverflow(i64, i64),
MuliWithOverflow(i64, i64),
AdduWithOverflow(u64, u64),
SubuWithOverflow(u64, u64),
MuluWithOverflow(u64, u64),
DivideByZero,
DivideWithOverflow,
ModuloByZero,
Expand Down Expand Up @@ -415,6 +408,7 @@ pub enum ErrKind {
TypeMismatch(String, ConstInt),
BadType(ConstVal),
ErroneousReferencedConstant(Box<ConstEvalErr>),
CharCast(ConstInt),
}

impl From<ConstMathErr> for ErrKind {
Expand All @@ -439,13 +433,6 @@ impl ConstEvalErr {
NotOn(ref const_val) => format!("not on {}", const_val.description()).into_cow(),
CallOn(ref const_val) => format!("call on {}", const_val.description()).into_cow(),

NegateWithOverflow(..) => "attempted to negate with overflow".into_cow(),
AddiWithOverflow(..) => "attempted to add with overflow".into_cow(),
SubiWithOverflow(..) => "attempted to sub with overflow".into_cow(),
MuliWithOverflow(..) => "attempted to mul with overflow".into_cow(),
AdduWithOverflow(..) => "attempted to add with overflow".into_cow(),
SubuWithOverflow(..) => "attempted to sub with overflow".into_cow(),
MuluWithOverflow(..) => "attempted to mul with overflow".into_cow(),
DivideByZero => "attempted to divide by zero".into_cow(),
DivideWithOverflow => "attempted to divide with overflow".into_cow(),
ModuloByZero => "attempted remainder with a divisor of zero".into_cow(),
Expand Down Expand Up @@ -482,6 +469,9 @@ impl ConstEvalErr {
},
BadType(ref i) => format!("value of wrong type: {:?}", i).into_cow(),
ErroneousReferencedConstant(_) => "could not evaluate referenced constant".into_cow(),
CharCast(ref got) => {
format!("only `u8` can be cast as `char`, not `{}`", got.description()).into_cow()
},
}
}
}
Expand Down Expand Up @@ -824,7 +814,10 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
debug!("const call({:?})", call_args);
eval_const_expr_partial(tcx, &result, ty_hint, Some(&call_args))?
},
hir::ExprLit(ref lit) => lit_to_const(&lit.node, tcx, ety, lit.span)?,
hir::ExprLit(ref lit) => match lit_to_const(&lit.node, tcx, ety, lit.span) {
Ok(val) => val,
Err(err) => signal!(e, err),
},
hir::ExprBlock(ref block) => {
match block.expr {
Some(ref expr) => eval_const_expr_partial(tcx, &expr, ty_hint, fn_args)?,
Expand Down Expand Up @@ -930,7 +923,10 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &TyCtxt<'tcx>,
};

match (ety.map(|t| &t.sty), result) {
(Some(ref ty_hint), Integral(i)) => Ok(Integral(infer(i, tcx, ty_hint, e.span)?)),
(Some(ref ty_hint), Integral(i)) => match infer(i, tcx, ty_hint) {
Ok(inferred) => Ok(Integral(inferred)),
Err(err) => signal!(e, err),
},
(_, result) => Ok(result),
}
}
Expand All @@ -939,15 +935,9 @@ fn infer<'tcx>(
i: ConstInt,
tcx: &TyCtxt<'tcx>,
ty_hint: &ty::TypeVariants<'tcx>,
span: Span
) -> Result<ConstInt, ConstEvalErr> {
) -> Result<ConstInt, ErrKind> {
use syntax::ast::*;

let err = |e| ConstEvalErr {
span: span,
kind: e,
};

match (ty_hint, i) {
(&ty::TyInt(IntTy::I8), result @ I8(_)) => Ok(result),
(&ty::TyInt(IntTy::I16), result @ I16(_)) => Ok(result),
Expand Down Expand Up @@ -993,17 +983,17 @@ fn infer<'tcx>(
Err(_) => Ok(Usize(ConstUsize::Us32(i as u32))),
}
},
(&ty::TyUint(_), InferSigned(_)) => Err(err(IntermediateUnsignedNegative)),
(&ty::TyUint(_), InferSigned(_)) => Err(IntermediateUnsignedNegative),

(&ty::TyInt(ity), i) => Err(err(TypeMismatch(ity.to_string(), i))),
(&ty::TyUint(ity), i) => Err(err(TypeMismatch(ity.to_string(), i))),
(&ty::TyInt(ity), i) => Err(TypeMismatch(ity.to_string(), i)),
(&ty::TyUint(ity), i) => Err(TypeMismatch(ity.to_string(), i)),

(&ty::TyEnum(ref adt, _), i) => {
let hints = tcx.lookup_repr_hints(adt.did);
let int_ty = tcx.enum_repr_type(hints.iter().next());
infer(i, tcx, &int_ty.to_ty(tcx).sty, span)
infer(i, tcx, &int_ty.to_ty(tcx).sty)
},
(_, i) => Err(err(BadType(ConstVal::Integral(i)))),
(_, i) => Err(BadType(ConstVal::Integral(i))),
}
}

Expand Down Expand Up @@ -1089,23 +1079,22 @@ fn cast_const_int<'tcx>(tcx: &TyCtxt<'tcx>, val: ConstInt, ty: ty::Ty) -> CastRe
Err(_) => Ok(Integral(Usize(ConstUsize::Us32(v as u32)))),
}
},
ty::TyFloat(ast::FloatTy::F64) if val.is_negative() => {
// FIXME: this could probably be prettier
// there's no easy way to turn an `Infer` into a f64
let val = (-val).map_err(Math)?;
let val = val.to_u64().unwrap() as f64;
let val = -val;
Ok(Float(val))
ty::TyFloat(ast::FloatTy::F64) => match val.erase_type() {
Infer(u) => Ok(Float(u as f64)),
InferSigned(i) => Ok(Float(i as f64)),
_ => bug!("ConstInt::erase_type returned something other than Infer/InferSigned"),
},
ty::TyFloat(ast::FloatTy::F64) => Ok(Float(val.to_u64().unwrap() as f64)),
ty::TyFloat(ast::FloatTy::F32) if val.is_negative() => {
let val = (-val).map_err(Math)?;
let val = val.to_u64().unwrap() as f32;
let val = -val;
Ok(Float(val as f64))
ty::TyFloat(ast::FloatTy::F32) => match val.erase_type() {
Infer(u) => Ok(Float(u as f32 as f64)),
InferSigned(i) => Ok(Float(i as f32 as f64)),
_ => bug!("ConstInt::erase_type returned something other than Infer/InferSigned"),
},
ty::TyFloat(ast::FloatTy::F32) => Ok(Float(val.to_u64().unwrap() as f32 as f64)),
ty::TyRawPtr(_) => Err(ErrKind::UnimplementedConstVal("casting an address to a raw ptr")),
ty::TyChar => match infer(val, tcx, &ty::TyUint(ast::UintTy::U8)) {
Ok(U8(u)) => Ok(Char(u as char)),
// can only occur before typeck, typeck blocks `T as char` for `T` != `u8`
_ => Err(CharCast(val)),
},
_ => Err(CannotCast),
}
}
Expand Down Expand Up @@ -1136,36 +1125,36 @@ fn lit_to_const<'tcx>(lit: &ast::LitKind,
tcx: &TyCtxt<'tcx>,
ty_hint: Option<Ty<'tcx>>,
span: Span,
) -> Result<ConstVal, ConstEvalErr> {
) -> Result<ConstVal, ErrKind> {
use syntax::ast::*;
use syntax::ast::LitIntType::*;
match *lit {
LitKind::Str(ref s, _) => Ok(Str((*s).clone())),
LitKind::ByteStr(ref data) => Ok(ByteStr(data.clone())),
LitKind::Byte(n) => Ok(Integral(U8(n))),
LitKind::Int(n, Signed(ity)) => {
infer(InferSigned(n as i64), tcx, &ty::TyInt(ity), span).map(Integral)
infer(InferSigned(n as i64), tcx, &ty::TyInt(ity)).map(Integral)
},

LitKind::Int(n, Unsuffixed) => {
match ty_hint.map(|t| &t.sty) {
Some(&ty::TyInt(ity)) => {
infer(InferSigned(n as i64), tcx, &ty::TyInt(ity), span).map(Integral)
infer(InferSigned(n as i64), tcx, &ty::TyInt(ity)).map(Integral)
},
Some(&ty::TyUint(uty)) => {
infer(Infer(n), tcx, &ty::TyUint(uty), span).map(Integral)
infer(Infer(n), tcx, &ty::TyUint(uty)).map(Integral)
},
None => Ok(Integral(Infer(n))),
Some(&ty::TyEnum(ref adt, _)) => {
let hints = tcx.lookup_repr_hints(adt.did);
let int_ty = tcx.enum_repr_type(hints.iter().next());
infer(Infer(n), tcx, &int_ty.to_ty(tcx).sty, span).map(Integral)
infer(Infer(n), tcx, &int_ty.to_ty(tcx).sty).map(Integral)
},
Some(ty_hint) => bug!("bad ty_hint: {:?}, {:?}", ty_hint, lit),
}
},
LitKind::Int(n, Unsigned(ity)) => {
infer(Infer(n), tcx, &ty::TyUint(ity), span).map(Integral)
infer(Infer(n), tcx, &ty::TyUint(ity)).map(Integral)
},

LitKind::Float(ref n, _) |
Expand Down

0 comments on commit 7a0ccc4

Please sign in to comment.