Auto merge of #38594 - steveklabnik:rollup, r=steveklabnik

Rollup of 14 pull requests

- Successful merges: #37956, #38013, #38297, #38480, #38497, #38502, #38505, #38513, #38521, #38549, #38554, #38557, #38568, #38572
- Failed merges:
This commit is contained in:
bors 2016-12-24 21:14:17 +00:00
commit e60aa62ffe
18 changed files with 848 additions and 48 deletions

View File

@ -142,7 +142,7 @@ incremental builds:
```
The `--incremental` flag will store incremental compilation artifacts
in `build/stage0-incremental`. Note that we only use incremental
in `build/<host>/stage0-incremental`. Note that we only use incremental
compilation for the stage0 -> stage1 compilation -- this is because
the stage1 compiler is changing, and we don't try to cache and reuse
incremental artifacts across different versions of the compiler. For

View File

@ -16,18 +16,18 @@ function result.
The most common case of coercion is removing mutability from a reference:
* `&mut T` to `&T`
* `&mut T` to `&T`
An analogous conversion is to remove mutability from a
[raw pointer](raw-pointers.md):
* `*mut T` to `*const T`
* `*mut T` to `*const T`
References can also be coerced to raw pointers:
* `&T` to `*const T`
* `&T` to `*const T`
* `&mut T` to `*mut T`
* `&mut T` to `*mut T`
Custom coercions may be defined using [`Deref`](deref-coercions.md).
@ -59,11 +59,11 @@ A cast `e as U` is valid if `e` has type `T` and `T` *coerces* to `U`.
A cast `e as U` is also valid in any of the following cases:
* `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
* `e` is a C-like enum (with no data attached to the variants),
and `U` is an integer type; *enum-cast*
* `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
* `e` has type `u8` and `U` is `char`; *u8-char-cast*
* `e` has type `T` and `T` and `U` are any numeric types; *numeric-cast*
* `e` is a C-like enum (with no data attached to the variants),
and `U` is an integer type; *enum-cast*
* `e` has type `bool` or `char` and `U` is an integer type; *prim-int-cast*
* `e` has type `u8` and `U` is `char`; *u8-char-cast*
For example

View File

@ -460,8 +460,9 @@ not actually pass as a test.
```
The `no_run` attribute will compile your code, but not run it. This is
important for examples such as "Here's how to start up a network service,"
which you would want to make sure compile, but might run in an infinite loop!
important for examples such as "Here's how to retrieve a web page,"
which you would want to ensure compiles, but might be run in a test
environment that has no network access.
### Documenting modules

View File

@ -589,11 +589,10 @@ please see the [Documentation chapter](documentation.html).
# Testing and concurrency
One thing that is important to note when writing tests is that they may be run
concurrently using threads. For this reason you should take care that your tests
are written in such a way as to not depend on each-other, or on any shared
state. "Shared state" can also include the environment, such as the current
working directory, or environment variables.
It is important to note that tests are run concurrently using threads. For this
reason, care should be taken to ensure your tests do not depend on each-other,
or on any shared state. "Shared state" can also include the environment, such
as the current working directory, or environment variables.
If this is an issue it is possible to control this concurrency, either by
setting the environment variable `RUST_TEST_THREADS`, or by passing the argument

View File

@ -10,8 +10,15 @@
//! A doubly-linked list with owned nodes.
//!
//! The `LinkedList` allows pushing and popping elements at either end and is thus
//! efficiently usable as a double-ended queue.
//! The `LinkedList` allows pushing and popping elements at either end
//! in constant time.
//!
//! Almost always it is better to use `Vec` or [`VecDeque`] instead of
//! [`LinkedList`]. In general, array-based containers are faster,
//! more memory efficient and make better use of CPU cache.
//!
//! [`LinkedList`]: ../linked_list/struct.LinkedList.html
//! [`VecDeque`]: ../vec_deque/struct.VecDeque.html
#![stable(feature = "rust1", since = "1.0.0")]
@ -27,7 +34,14 @@
use super::SpecExtend;
/// A doubly-linked list.
/// A doubly-linked list with owned nodes.
///
/// The `LinkedList` allows pushing and popping elements at either end
/// in constant time.
///
/// Almost always it is better to use `Vec` or `VecDeque` instead of
/// `LinkedList`. In general, array-based containers are faster,
/// more memory efficient and make better use of CPU cache.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct LinkedList<T> {
head: Option<Shared<Node<T>>>,

View File

@ -28,7 +28,7 @@
use rustc::hir::intravisit as visit;
use rustc::ty::TyCtxt;
use rustc_data_structures::fnv;
use std::hash::Hash;
use std::hash::{Hash, Hasher};
use super::def_path_hash::DefPathHashes;
use super::caching_codemap_view::CachingCodemapView;
@ -264,7 +264,7 @@ enum SawExprComponent<'a> {
SawExprPath,
SawExprAddrOf(hir::Mutability),
SawExprRet,
SawExprInlineAsm(&'a hir::InlineAsm),
SawExprInlineAsm(StableInlineAsm<'a>),
SawExprStruct,
SawExprRepeat,
}
@ -340,7 +340,7 @@ fn saw_expr<'a>(node: &'a Expr_,
ExprBreak(label, _) => (SawExprBreak(label.map(|l| l.name.as_str())), false),
ExprAgain(label) => (SawExprAgain(label.map(|l| l.name.as_str())), false),
ExprRet(..) => (SawExprRet, false),
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(a), false),
ExprInlineAsm(ref a,..) => (SawExprInlineAsm(StableInlineAsm(a)), false),
ExprStruct(..) => (SawExprStruct, false),
ExprRepeat(..) => (SawExprRepeat, false),
}
@ -491,6 +491,46 @@ enum SawSpanExpnKind {
SomeExpansion,
}
/// A wrapper that provides a stable Hash implementation.
struct StableInlineAsm<'a>(&'a InlineAsm);
impl<'a> Hash for StableInlineAsm<'a> {
fn hash<H: Hasher>(&self, state: &mut H) {
let InlineAsm {
asm,
asm_str_style,
ref outputs,
ref inputs,
ref clobbers,
volatile,
alignstack,
dialect,
expn_id: _, // This is used for error reporting
} = *self.0;
asm.as_str().hash(state);
asm_str_style.hash(state);
outputs.len().hash(state);
for output in outputs {
let InlineAsmOutput { constraint, is_rw, is_indirect } = *output;
constraint.as_str().hash(state);
is_rw.hash(state);
is_indirect.hash(state);
}
inputs.len().hash(state);
for input in inputs {
input.as_str().hash(state);
}
clobbers.len().hash(state);
for clobber in clobbers {
clobber.as_str().hash(state);
}
volatile.hash(state);
alignstack.hash(state);
dialect.hash(state);
}
}
macro_rules! hash_attrs {
($visitor:expr, $attrs:expr) => ({
let attrs = $attrs;

View File

@ -57,9 +57,9 @@
Please specify a valid "kind" value, from one of the following:
* static
* dylib
* framework
* static
* dylib
* framework
"##,

View File

@ -0,0 +1 @@
See [librustc/README.md](../librustc/README.md).

View File

@ -1 +0,0 @@
See the README.md in ../librustc.

View File

@ -1378,8 +1378,8 @@ fn main() {
You have two possibilities to solve this situation:
* Give an explicit definition of the expression
* Infer the expression
* Give an explicit definition of the expression
* Infer the expression
Examples:

View File

@ -207,7 +207,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if !f.alternate() {
clause.push_str("</span>");
let plain = format!("{:#}", self);
if plain.len() > 80 {
if plain.len() + pad > 80 {
//break it onto its own line regardless, but make sure method impls and trait
//blocks keep their fixed padding (2 and 9, respectively)
let padding = if pad > 10 {

View File

@ -46,6 +46,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
<title>{title}</title>
<link rel="stylesheet" type="text/css" href="{root_path}normalize.css">
<link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css">
<link rel="stylesheet" type="text/css" href="{root_path}main.css">
{css_extension}

View File

@ -1,5 +1,3 @@
@import "normalize.css";
/**
* Copyright 2013 The Rust Project Developers. See the COPYRIGHT
* file at the top-level directory of this distribution and at

View File

@ -1425,6 +1425,12 @@ fn split(self, byte: u8) -> Split<Self> where Self: Sized {
/// println!("{}", line.unwrap());
/// }
/// ```
///
/// # Errors
///
/// Each line of the iterator has the same error semantics as [`BufRead::read_line()`].
///
/// [`BufRead::read_line()`]: trait.BufRead.html#method.read_line
#[stable(feature = "rust1", since = "1.0.0")]
fn lines(self) -> Lines<Self> where Self: Sized {
Lines { buf: self }

View File

@ -23,7 +23,6 @@
pub type mx_status_t = i32;
pub type mx_size_t = usize;
pub type mx_ssize_t = isize;
pub const MX_HANDLE_INVALID: mx_handle_t = 0;

View File

@ -318,20 +318,38 @@ pub fn spawn<F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
// Free functions
////////////////////////////////////////////////////////////////////////////////
/// Spawns a new thread, returning a `JoinHandle` for it.
/// Spawns a new thread, returning a [`JoinHandle`] for it.
///
/// The join handle will implicitly *detach* the child thread upon being
/// dropped. In this case, the child thread may outlive the parent (unless
/// the parent thread is the main thread; the whole process is terminated when
/// the main thread finishes.) Additionally, the join handle provides a `join`
/// the main thread finishes). Additionally, the join handle provides a [`join`]
/// method that can be used to join the child thread. If the child thread
/// panics, `join` will return an `Err` containing the argument given to
/// `panic`.
/// panics, [`join`] will return an [`Err`] containing the argument given to
/// [`panic`].
///
/// # Panics
///
/// Panics if the OS fails to create a thread; use `Builder::spawn`
/// Panics if the OS fails to create a thread; use [`Builder::spawn`]
/// to recover from such errors.
///
/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
/// [`panic!`]: ../../std/macro.panic.html
/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let handler = thread::spawn(|| {
/// // thread code
/// });
///
/// handler.join().unwrap();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
@ -341,7 +359,7 @@ pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
/// Gets a handle to the thread that invokes it.
///
/// #Examples
/// # Examples
///
/// Getting a handle to the current thread with `thread::current()`:
///
@ -366,6 +384,14 @@ pub fn current() -> Thread {
}
/// Cooperatively gives up a timeslice to the OS scheduler.
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// thread::yield_now();
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn yield_now() {
imp::Thread::yield_now()
@ -375,7 +401,7 @@ pub fn yield_now() {
///
/// # Examples
///
/// ```rust,should_panic
/// ```should_panic
/// use std::thread;
///
/// struct SomeStruct;
@ -413,6 +439,15 @@ pub fn panicking() -> bool {
/// specifics or platform-dependent functionality. Note that on unix platforms
/// this function will not return early due to a signal being received or a
/// spurious wakeup.
///
/// # Examples
///
/// ```no_run
/// use std::thread;
///
/// // Let's sleep for 2 seconds:
/// thread::sleep_ms(2000);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::sleep`")]
pub fn sleep_ms(ms: u32) {
@ -433,7 +468,7 @@ pub fn sleep_ms(ms: u32) {
///
/// # Examples
///
/// ```rust,no_run
/// ```no_run
/// use std::{thread, time};
///
/// let ten_millis = time::Duration::from_millis(10);
@ -749,7 +784,7 @@ fn join(&mut self) -> Result<T> {
///
/// A `JoinHandle` *detaches* the child thread when it is dropped.
///
/// Due to platform restrictions, it is not possible to `Clone` this
/// Due to platform restrictions, it is not possible to [`Clone`] this
/// handle: the ability to join a child thread is a uniquely-owned
/// permission.
///
@ -760,7 +795,7 @@ fn join(&mut self) -> Result<T> {
///
/// Creation from [`thread::spawn`]:
///
/// ```rust
/// ```
/// use std::thread;
///
/// let join_handle: thread::JoinHandle<_> = thread::spawn(|| {
@ -770,7 +805,7 @@ fn join(&mut self) -> Result<T> {
///
/// Creation from [`thread::Builder::spawn`]:
///
/// ```rust
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new();
@ -780,13 +815,31 @@ fn join(&mut self) -> Result<T> {
/// }).unwrap();
/// ```
///
/// [`Clone`]: ../../std/clone/trait.Clone.html
/// [`thread::spawn`]: fn.spawn.html
/// [`thread::Builder::spawn`]: struct.Builder.html#method.spawn
#[stable(feature = "rust1", since = "1.0.0")]
pub struct JoinHandle<T>(JoinInner<T>);
impl<T> JoinHandle<T> {
/// Extracts a handle to the underlying thread
/// Extracts a handle to the underlying thread.
///
/// # Examples
///
/// ```
/// #![feature(thread_id)]
///
/// use std::thread;
///
/// let builder = thread::Builder::new();
///
/// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
/// // some work here
/// }).unwrap();
///
/// let thread = join_handle.thread();
/// println!("thread id: {:?}", thread.id());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn thread(&self) -> &Thread {
&self.0.thread
@ -794,8 +847,24 @@ pub fn thread(&self) -> &Thread {
/// Waits for the associated thread to finish.
///
/// If the child thread panics, `Err` is returned with the parameter given
/// to `panic`.
/// If the child thread panics, [`Err`] is returned with the parameter given
/// to [`panic`].
///
/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
/// [`panic!`]: ../../std/macro.panic.html
///
/// # Examples
///
/// ```
/// use std::thread;
///
/// let builder = thread::Builder::new();
///
/// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
/// // some work here
/// }).unwrap();
/// join_handle.join().expect("Couldn't join on the associated thread");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn join(mut self) -> Result<T> {
self.0.join()

View File

@ -107,7 +107,7 @@ impl Foo {
pub fn method_selfness(&self) { }
}
// Change Method Selfmutness -----------------------------------------------------------
// Change Method Selfmutness ---------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn method_selfmutness(&self) { }
@ -126,3 +126,411 @@ impl Foo {
pub fn method_selfmutness(&mut self) { }
}
// Add Method To Impl ----------------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_method_to_impl1(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_method_to_impl1(&self) { }
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_method_to_impl2(&self) { }
}
// Add Method Parameter --------------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_method_parameter(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_method_parameter(&self, _: i32) { }
}
// Change Method Parameter Name ------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn change_method_parameter_name(&self, a: i64) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_method_parameter_name(&self, b: i64) { }
}
// Change Method Return Type ---------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn change_method_return_type(&self) -> u16 { 0 }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_method_return_type(&self) -> u8 { 0 }
}
// Make Method #[inline] -------------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn make_method_inline(&self) -> u8 { 0 }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[inline]
pub fn make_method_inline(&self) -> u8 { 0 }
}
// Change order of parameters -------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn change_method_parameter_order(&self, a: i64, b: i64) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_method_parameter_order(&self, b: i64, a: i64) { }
}
// Make method unsafe ----------------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn make_method_unsafe(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub unsafe fn make_method_unsafe(&self) { }
}
// Make method extern ----------------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn make_method_extern(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub extern fn make_method_extern(&self) { }
}
// Change method calling convention --------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub extern "C" fn change_method_calling_convention(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub extern "system" fn change_method_calling_convention(&self) { }
}
// Add Lifetime Parameter to Method --------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_lifetime_parameter_to_method(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_lifetime_parameter_to_method<'a>(&self) { }
}
// Add Type Parameter To Method ------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_type_parameter_to_method(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_type_parameter_to_method<T>(&self) { }
}
// Add Lifetime Bound to Lifetime Parameter of Method --------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b>(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_lifetime_bound_to_lifetime_param_of_method<'a, 'b: 'a>(&self) { }
}
// Add Lifetime Bound to Type Parameter of Method ------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_lifetime_bound_to_type_param_of_method<'a, T>(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_lifetime_bound_to_type_param_of_method<'a, T: 'a>(&self) { }
}
// Add Trait Bound to Type Parameter of Method ------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_trait_bound_to_type_param_of_method<T>(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_trait_bound_to_type_param_of_method<T: Clone>(&self) { }
}
// Add #[no_mangle] to Method --------------------------------------------------
#[cfg(cfail1)]
impl Foo {
pub fn add_no_mangle_to_method(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Foo {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[no_mangle]
pub fn add_no_mangle_to_method(&self) { }
}
struct Bar<T>(T);
// Add Type Parameter To Impl --------------------------------------------------
#[cfg(cfail1)]
impl Bar<u32> {
pub fn add_type_parameter_to_impl(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl<T> Bar<T> {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_type_parameter_to_impl(&self) { }
}
// Change Self Type of Impl ----------------------------------------------------
#[cfg(cfail1)]
impl Bar<u32> {
pub fn change_impl_self_type(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl Bar<u64> {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn change_impl_self_type(&self) { }
}
// Add Lifetime Bound to Impl --------------------------------------------------
#[cfg(cfail1)]
impl<T> Bar<T> {
pub fn add_lifetime_bound_to_impl_parameter(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl<T: 'static> Bar<T> {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_lifetime_bound_to_impl_parameter(&self) { }
}
// Add Trait Bound to Impl Parameter -------------------------------------------
#[cfg(cfail1)]
impl<T> Bar<T> {
pub fn add_trait_bound_to_impl_parameter(&self) { }
}
#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl<T: Clone> Bar<T> {
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub fn add_trait_bound_to_impl_parameter(&self) { }
}

View File

@ -0,0 +1,265 @@
// Copyright 2016 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.
// This test case tests the incremental compilation hash (ICH) implementation
// for inline asm.
// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.
// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph
#![allow(warnings)]
#![feature(rustc_attrs)]
#![feature(asm)]
#![crate_type="rlib"]
// Change template -------------------------------------------------------------
#[cfg(cfail1)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_template(a: i32) -> i32 {
let c: i32;
unsafe {
asm!("add 1, $0"
: "=r"(c)
: "0"(a)
:
:
);
}
c
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_template(a: i32) -> i32 {
let c: i32;
unsafe {
asm!("add 2, $0"
: "=r"(c)
: "0"(a)
:
:
);
}
c
}
// Change output -------------------------------------------------------------
#[cfg(cfail1)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_output(a: i32) -> i32 {
let mut _out1: i32 = 0;
let mut _out2: i32 = 0;
unsafe {
asm!("add 1, $0"
: "=r"(_out1)
: "0"(a)
:
:
);
}
_out1
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_output(a: i32) -> i32 {
let mut _out1: i32 = 0;
let mut _out2: i32 = 0;
unsafe {
asm!("add 1, $0"
: "=r"(_out2)
: "0"(a)
:
:
);
}
_out1
}
// Change input -------------------------------------------------------------
#[cfg(cfail1)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_input(_a: i32, _b: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_a)
:
:
);
}
_out
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_input(_a: i32, _b: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_b)
:
:
);
}
_out
}
// Change input constraint -----------------------------------------------------
#[cfg(cfail1)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_input_constraint(_a: i32, _b: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_a), "r"(_b)
:
:
);
}
_out
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_input_constraint(_a: i32, _b: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "r"(_a), "0"(_b)
:
:
);
}
_out
}
// Change clobber --------------------------------------------------------------
#[cfg(cfail1)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_clobber(_a: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_a)
:
:
);
}
_out
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_clobber(_a: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_a)
: "eax"
:
);
}
_out
}
// Change options --------------------------------------------------------------
#[cfg(cfail1)]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_options(_a: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_a)
:
:
);
}
_out
}
#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_dirty(label="HirBody", cfg="cfail2")]
#[rustc_clean(label="HirBody", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn change_options(_a: i32) -> i32 {
let _out;
unsafe {
asm!("add 1, $0"
: "=r"(_out)
: "0"(_a)
:
: "volatile"
);
}
_out
}