Auto merge of #39470 - GuillaumeGomez:rollup, r=GuillaumeGomez

Rollup of 9 pull requests

- Successful merges: #38823, #39196, #39299, #39319, #39373, #39383, #39416, #39420, #39427
- Failed merges:
This commit is contained in:
bors 2017-02-02 21:58:10 +00:00
commit eedaa94e33
17 changed files with 75 additions and 137 deletions

View File

@ -167,6 +167,7 @@ Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.c
Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>
Peter Elmers <peter.elmers@yahoo.com> <peter.elmers@rice.edu>
Peter Liniker <peter.liniker+github@gmail.com>
Peter Zotov <whitequark@whitequark.org>
Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com>
Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>

View File

@ -499,6 +499,10 @@ be imported in every test with `mod common;`
That's all there is to the `tests` directory. The `tests` module isn't needed
here, since the whole thing is focused on tests.
Note, when building integration tests, cargo will not pass the `test` attribute
to the compiler. It means that all parts in `cfg(test)` won't be included in
the build used in your integration tests.
Let's finally check out that third section: documentation tests.
# Documentation tests

View File

@ -199,24 +199,42 @@ assert (unsafely) that a generic type's destructor is *guaranteed* to
not access any expired data, even if its type gives it the capability
to do so.
That attribute is called `unsafe_destructor_blind_to_params`.
That attribute is called `may_dangle` and was introduced in [RFC 1327]
(https://github.com/rust-lang/rfcs/blob/master/text/1327-dropck-param-eyepatch.md).
To deploy it on the Inspector example from above, we would write:
```rust,ignore
struct Inspector<'a>(&'a u8, &'static str);
impl<'a> Drop for Inspector<'a> {
#[unsafe_destructor_blind_to_params]
unsafe impl<#[may_dangle] 'a> Drop for Inspector<'a> {
fn drop(&mut self) {
println!("Inspector(_, {}) knows when *not* to inspect.", self.1);
}
}
```
This attribute has the word `unsafe` in it because the compiler is not
checking the implicit assertion that no potentially expired data
Use of this attribute requires the `Drop` impl to be marked `unsafe` because the
compiler is not checking the implicit assertion that no potentially expired data
(e.g. `self.0` above) is accessed.
The attribute can be applied to any number of lifetime and type parameters. In
the following example, we assert that we access no data behind a reference of
lifetime `'b` and that the only uses of `T` will be moves or drops, but omit
the attribute from `'a` and `U`, because we do access data with that lifetime
and that type:
```rust,ignore
use std::fmt::Display;
struct Inspector<'a, 'b, T, U: Display>(&'a u8, &'b u8, T, U);
unsafe impl<'a, #[may_dangle] 'b, #[may_dangle] T, U: Display> Drop for Inspector<'a, 'b, T, U> {
fn drop(&mut self) {
println!("Inspector({}, _, _, {})", self.0, self.3);
}
}
```
It is sometimes obvious that no such access can occur, like the case above.
However, when dealing with a generic type parameter, such access can
occur indirectly. Examples of such indirect access are:
@ -263,7 +281,7 @@ some other method invoked by the destructor, rather than being written
directly within it.
In all of the above cases where the `&'a u8` is accessed in the
destructor, adding the `#[unsafe_destructor_blind_to_params]`
destructor, adding the `#[may_dangle]`
attribute makes the type vulnerable to misuse that the borrower
checker will not catch, inviting havoc. It is better to avoid adding
the attribute.

View File

@ -17,9 +17,11 @@
//! pointer to the same value in the heap. When the last [`Rc`] pointer to a
//! given value is destroyed, the pointed-to value is also destroyed.
//!
//! Shared references in Rust disallow mutation by default, and `Rc` is no
//! exception. If you need to mutate through an [`Rc`], use [`Cell`] or
//! [`RefCell`].
//! Shared references in Rust disallow mutation by default, and [`Rc`]
//! is no exception: you cannot obtain a mutable reference to
//! something inside an [`Rc`]. If you need mutability, put a [`Cell`]
//! or [`RefCell`] inside the [`Rc`]; see [an example of mutability
//! inside an Rc][mutability].
//!
//! [`Rc`] uses non-atomic reference counting. This means that overhead is very
//! low, but an [`Rc`] cannot be sent between threads, and consequently [`Rc`]
@ -214,6 +216,7 @@
//! [upgrade]: struct.Weak.html#method.upgrade
//! [`None`]: ../../std/option/enum.Option.html#variant.None
//! [assoc]: ../../book/method-syntax.html#associated-functions
//! [mutability]: ../../std/cell/index.html#introducing-mutability-inside-of-something-immutable
#![stable(feature = "rust1", since = "1.0.0")]

View File

@ -109,7 +109,6 @@ pub mod util {
pub mod common;
pub mod ppaux;
pub mod nodemap;
pub mod num;
pub mod fs;
}

View File

@ -1,98 +0,0 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub trait ToPrimitive {
fn to_i8(&self) -> Option<i8>;
fn to_i16(&self) -> Option<i16>;
fn to_i32(&self) -> Option<i32>;
fn to_i64(&self) -> Option<i64>;
fn to_u8(&self) -> Option<u8>;
fn to_u16(&self) -> Option<u16>;
fn to_u32(&self) -> Option<u32>;
fn to_u64(&self) -> Option<u64>;
}
impl ToPrimitive for i64 {
fn to_i8(&self) -> Option<i8> {
if *self < i8::min_value() as i64 || *self > i8::max_value() as i64 {
None
} else {
Some(*self as i8)
}
}
fn to_i16(&self) -> Option<i16> {
if *self < i16::min_value() as i64 || *self > i16::max_value() as i64 {
None
} else {
Some(*self as i16)
}
}
fn to_i32(&self) -> Option<i32> {
if *self < i32::min_value() as i64 || *self > i32::max_value() as i64 {
None
} else {
Some(*self as i32)
}
}
fn to_i64(&self) -> Option<i64> {
Some(*self)
}
fn to_u8(&self) -> Option<u8> {
if *self < 0 || *self > u8::max_value() as i64 {
None
} else {
Some(*self as u8)
}
}
fn to_u16(&self) -> Option<u16> {
if *self < 0 || *self > u16::max_value() as i64 {
None
} else {
Some(*self as u16)
}
}
fn to_u32(&self) -> Option<u32> {
if *self < 0 || *self > u32::max_value() as i64 {
None
} else {
Some(*self as u32)
}
}
fn to_u64(&self) -> Option<u64> {
if *self < 0 {None} else {Some(*self as u64)}
}
}
impl ToPrimitive for u64 {
fn to_i8(&self) -> Option<i8> {
if *self > i8::max_value() as u64 {None} else {Some(*self as i8)}
}
fn to_i16(&self) -> Option<i16> {
if *self > i16::max_value() as u64 {None} else {Some(*self as i16)}
}
fn to_i32(&self) -> Option<i32> {
if *self > i32::max_value() as u64 {None} else {Some(*self as i32)}
}
fn to_i64(&self) -> Option<i64> {
if *self > i64::max_value() as u64 {None} else {Some(*self as i64)}
}
fn to_u8(&self) -> Option<u8> {
if *self > u8::max_value() as u64 {None} else {Some(*self as u8)}
}
fn to_u16(&self) -> Option<u16> {
if *self > u16::max_value() as u64 {None} else {Some(*self as u16)}
}
fn to_u32(&self) -> Option<u32> {
if *self > u32::max_value() as u64 {None} else {Some(*self as u32)}
}
fn to_u64(&self) -> Option<u64> {
Some(*self)
}
}

View File

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//#![allow(non_camel_case_types)]
use rustc::middle::const_val::ConstVal::*;
use rustc::middle::const_val::ConstVal;
use self::ErrKind::*;

View File

@ -804,7 +804,7 @@ extern "C" {
Name: *const c_char)
-> ValueRef;
pub fn LLVMRustAddHandler(CatchSwitch: ValueRef, Handler: BasicBlockRef);
pub fn LLVMRustSetPersonalityFn(B: BuilderRef, Pers: ValueRef);
pub fn LLVMSetPersonalityFn(Func: ValueRef, Pers: ValueRef);
// Add a case to the switch instruction
pub fn LLVMAddCase(Switch: ValueRef, OnVal: ValueRef, Dest: BasicBlockRef);

View File

@ -16,8 +16,6 @@ use rustc::hir;
impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
pub fn ast_block(&mut self,
destination: &Lvalue<'tcx>,
// FIXME(#32959): temporary measure for the issue
dest_is_unit: bool,
mut block: BasicBlock,
ast_block: &'tcx hir::Block)
-> BlockAnd<()> {
@ -83,8 +81,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// of the block.
if let Some(expr) = expr {
unpack!(block = this.into(destination, block, expr));
} else if dest_is_unit {
// FIXME(#31472)
} else {
let source_info = this.source_info(span);
this.cfg.push_assign_unit(block, source_info, destination);
}

View File

@ -40,7 +40,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
this.in_scope(extent, block, |this| this.into(destination, block, value))
}
ExprKind::Block { body: ast_block } => {
this.ast_block(destination, expr.ty.is_nil(), block, ast_block)
this.ast_block(destination, block, ast_block)
}
ExprKind::Match { discriminant, arms } => {
this.match_expr(destination, expr_span, block, discriminant, arms)

View File

@ -1107,7 +1107,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
pub fn set_personality_fn(&self, personality: ValueRef) {
unsafe {
llvm::LLVMRustSetPersonalityFn(self.llbuilder, personality);
llvm::LLVMSetPersonalityFn(self.llfn(), personality);
}
}

View File

@ -319,7 +319,9 @@ pub fn trans_mir<'a, 'tcx: 'a>(
mircx.cleanup_kinds.iter_enumerated().map(|(bb, cleanup_kind)| {
if let CleanupKind::Funclet = *cleanup_kind {
let bcx = mircx.get_builder(bb);
bcx.set_personality_fn(mircx.ccx.eh_personality());
unsafe {
llvm::LLVMSetPersonalityFn(mircx.llfn, mircx.ccx.eh_personality());
}
if base::wants_msvc_seh(ccx.sess()) {
return Some(Funclet::new(bcx.cleanup_pad(None, &[])));
}

View File

@ -1806,12 +1806,13 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
String::new()
};
let mut unsafety_flag = "";
if let clean::FunctionItem(ref func) = myitem.inner {
if func.unsafety == hir::Unsafety::Unsafe {
unsafety_flag = "<a title='unsafe function' href='#'><sup>⚠</sup></a>";
let unsafety_flag = match myitem.inner {
clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func)
if func.unsafety == hir::Unsafety::Unsafe => {
"<a title='unsafe function' href='#'><sup>⚠</sup></a>"
}
}
_ => "",
};
let doc_value = myitem.doc_value().unwrap_or("");
write!(w, "

View File

@ -2456,9 +2456,21 @@ impl<'a> Parser<'a> {
Some(f) => f,
None => continue,
};
err.help(&format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
float.trunc() as usize,
format!(".{}", fstr.splitn(2, ".").last().unwrap())));
let sugg = pprust::to_string(|s| {
use print::pprust::PrintState;
use print::pp::word;
s.popen()?;
s.print_expr(&e)?;
word(&mut s.s, ".")?;
s.print_usize(float.trunc() as usize)?;
s.pclose()?;
word(&mut s.s, ".")?;
word(&mut s.s, fstr.splitn(2, ".").last().unwrap())
});
err.span_suggestion(
prev_span,
"try parenthesizing the first index",
sugg);
}
return Err(err);
@ -3900,7 +3912,14 @@ impl<'a> Parser<'a> {
if self.eat(&token::Semi) {
stmt_span.hi = self.prev_span.hi;
}
e.span_help(stmt_span, "try placing this code inside a block");
let sugg = pprust::to_string(|s| {
use print::pprust::{PrintState, INDENT_UNIT};
s.ibox(INDENT_UNIT)?;
s.bopen()?;
s.print_stmt(&stmt)?;
s.bclose_maybe_open(stmt.span, INDENT_UNIT, false)
});
e.span_suggestion(stmt_span, "try placing this code inside a block", sugg);
}
Err(mut e) => {
self.recover_stmt_(SemiColonMode::Break);

View File

@ -1082,14 +1082,6 @@ extern "C" void LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
#endif
}
extern "C" void LLVMRustSetPersonalityFn(LLVMBuilderRef B,
LLVMValueRef Personality) {
#if LLVM_VERSION_GE(3, 8)
unwrap(B)->GetInsertBlock()->getParent()->setPersonalityFn(
cast<Function>(unwrap(Personality)));
#endif
}
#if LLVM_VERSION_GE(3, 8)
extern "C" OperandBundleDef *LLVMRustBuildOperandBundleDef(const char *Name,
LLVMValueRef *Inputs,

View File

@ -15,6 +15,7 @@ fn main() {
{
if (foo)
bar; //~ ERROR expected `{`, found `bar`
//^ HELP try placing this code inside a block
//~^ HELP try placing this code inside a block
//~| SUGGESTION { bar; }
}
}

View File

@ -12,5 +12,6 @@
fn main () {
(1, (2, 3)).1.1; //~ ERROR unexpected token
//~^ HELP try parenthesizing the first index; e.g., `(foo.1).1`
//~^ HELP try parenthesizing the first index
//~| SUGGESTION ((1, (2, 3)).1).1
}