Auto merge of #44936 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 15 pull requests - Successful merges: #44124, #44287, #44320, #44694, #44708, #44794, #44797, #44824, #44836, #44840, #44845, #44854, #44889, #44900, #44903 - Failed merges:
This commit is contained in:
commit
c4cca3a72d
@ -306,7 +306,7 @@ impl<'a> Builder<'a> {
|
||||
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
|
||||
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
|
||||
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
|
||||
Subcommand::Clean => panic!(),
|
||||
Subcommand::Clean { .. } => panic!(),
|
||||
};
|
||||
|
||||
let builder = Builder {
|
||||
|
@ -13,7 +13,7 @@
|
||||
//! Responsible for cleaning out a build directory of all old and stale
|
||||
//! artifacts to prepare for a fresh build. Currently doesn't remove the
|
||||
//! `build/cache` directory (download cache) or the `build/$target/llvm`
|
||||
//! directory as we want that cached between builds.
|
||||
//! directory unless the --all flag is present.
|
||||
|
||||
use std::fs;
|
||||
use std::io::{self, ErrorKind};
|
||||
@ -21,24 +21,29 @@ use std::path::Path;
|
||||
|
||||
use Build;
|
||||
|
||||
pub fn clean(build: &Build) {
|
||||
pub fn clean(build: &Build, all: bool) {
|
||||
rm_rf("tmp".as_ref());
|
||||
rm_rf(&build.out.join("tmp"));
|
||||
rm_rf(&build.out.join("dist"));
|
||||
|
||||
for host in &build.hosts {
|
||||
let entries = match build.out.join(host).read_dir() {
|
||||
Ok(iter) => iter,
|
||||
Err(_) => continue,
|
||||
};
|
||||
if all {
|
||||
rm_rf(&build.out);
|
||||
} else {
|
||||
rm_rf(&build.out.join("tmp"));
|
||||
rm_rf(&build.out.join("dist"));
|
||||
|
||||
for entry in entries {
|
||||
let entry = t!(entry);
|
||||
if entry.file_name().to_str() == Some("llvm") {
|
||||
continue
|
||||
for host in &build.hosts {
|
||||
let entries = match build.out.join(host).read_dir() {
|
||||
Ok(iter) => iter,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
for entry in entries {
|
||||
let entry = t!(entry);
|
||||
if entry.file_name().to_str() == Some("llvm") {
|
||||
continue
|
||||
}
|
||||
let path = t!(entry.path().canonicalize());
|
||||
rm_rf(&path);
|
||||
}
|
||||
let path = t!(entry.path().canonicalize());
|
||||
rm_rf(&path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,9 @@ pub enum Subcommand {
|
||||
paths: Vec<PathBuf>,
|
||||
test_args: Vec<String>,
|
||||
},
|
||||
Clean,
|
||||
Clean {
|
||||
all: bool,
|
||||
},
|
||||
Dist {
|
||||
paths: Vec<PathBuf>,
|
||||
},
|
||||
@ -147,6 +149,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
||||
opts.optmulti("", "test-args", "extra arguments", "ARGS");
|
||||
},
|
||||
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
||||
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
||||
_ => { },
|
||||
};
|
||||
|
||||
@ -250,7 +253,7 @@ Arguments:
|
||||
}
|
||||
});
|
||||
|
||||
// All subcommands can have an optional "Available paths" section
|
||||
// All subcommands except `clean` can have an optional "Available paths" section
|
||||
if matches.opt_present("verbose") {
|
||||
let config = Config::parse(&["build".to_string()]);
|
||||
let mut build = Build::new(config);
|
||||
@ -258,9 +261,10 @@ Arguments:
|
||||
|
||||
let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
|
||||
extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
|
||||
} else {
|
||||
extra_help.push_str(format!("Run `./x.py {} -h -v` to see a list of available paths.",
|
||||
subcommand).as_str());
|
||||
} else if subcommand.as_str() != "clean" {
|
||||
extra_help.push_str(format!(
|
||||
"Run `./x.py {} -h -v` to see a list of available paths.",
|
||||
subcommand).as_str());
|
||||
}
|
||||
|
||||
// User passed in -h/--help?
|
||||
@ -290,10 +294,13 @@ Arguments:
|
||||
}
|
||||
"clean" => {
|
||||
if paths.len() > 0 {
|
||||
println!("\nclean takes no arguments\n");
|
||||
println!("\nclean does not take a path argument\n");
|
||||
usage(1, &opts, &subcommand_help, &extra_help);
|
||||
}
|
||||
Subcommand::Clean
|
||||
|
||||
Subcommand::Clean {
|
||||
all: matches.opt_present("all"),
|
||||
}
|
||||
}
|
||||
"dist" => {
|
||||
Subcommand::Dist {
|
||||
|
@ -345,8 +345,8 @@ impl Build {
|
||||
job::setup(self);
|
||||
}
|
||||
|
||||
if let Subcommand::Clean = self.config.cmd {
|
||||
return clean::clean(self);
|
||||
if let Subcommand::Clean { all } = self.config.cmd {
|
||||
return clean::clean(self, all);
|
||||
}
|
||||
|
||||
self.verbose("finding compilers");
|
||||
|
@ -367,7 +367,7 @@ impl Step for Openssl {
|
||||
if !ok {
|
||||
panic!("failed to download openssl source")
|
||||
}
|
||||
let mut shasum = if target.contains("apple") {
|
||||
let mut shasum = if target.contains("apple") || build.build.contains("netbsd") {
|
||||
let mut cmd = Command::new("shasum");
|
||||
cmd.arg("-a").arg("256");
|
||||
cmd
|
||||
@ -387,7 +387,7 @@ impl Step for Openssl {
|
||||
let dst = build.openssl_install_dir(target).unwrap();
|
||||
drop(fs::remove_dir_all(&obj));
|
||||
drop(fs::remove_dir_all(&dst));
|
||||
build.run(Command::new("tar").arg("xf").arg(&tarball).current_dir(&out));
|
||||
build.run(Command::new("tar").arg("zxf").arg(&tarball).current_dir(&out));
|
||||
|
||||
let mut configure = Command::new("perl");
|
||||
configure.arg(obj.join("Configure"));
|
||||
|
@ -31,7 +31,7 @@ WORKDIR /build
|
||||
# The `config` config file was a previously generated config file for
|
||||
# the kernel. This file was generated by running `make defconfig`
|
||||
# followed by `make menuconfig` and then enabling the IPv6 protocol page.
|
||||
COPY disabled/aarch64-gnu/config /build/.config
|
||||
COPY aarch64-gnu/config /build/.config
|
||||
RUN curl https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.42.tar.xz | \
|
||||
tar xJf - && \
|
||||
cd /build/linux-4.4.42 && \
|
||||
|
@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
|
||||
# emscripten
|
||||
COPY scripts/emscripten-wasm.sh /scripts/
|
||||
COPY disabled/wasm32-exp/node.sh /usr/local/bin/node
|
||||
COPY wasm32-exp/node.sh /usr/local/bin/node
|
||||
RUN bash /scripts/emscripten-wasm.sh
|
||||
|
||||
# cache
|
||||
|
@ -36,12 +36,14 @@ elif [ -f "$docker_dir/disabled/$image/Dockerfile" ]; then
|
||||
echo Cannot run disabled images on travis!
|
||||
exit 1
|
||||
fi
|
||||
retry docker \
|
||||
# retry messes with the pipe from tar to docker. Not needed on non-travis
|
||||
# Transform changes the context of disabled Dockerfiles to match the enabled ones
|
||||
tar --transform 's#^./disabled/#./#' -C $docker_dir -c . | docker \
|
||||
build \
|
||||
--rm \
|
||||
-t rust-ci \
|
||||
-f "$docker_dir/disabled/$image/Dockerfile" \
|
||||
"$docker_dir"
|
||||
-f "$image/Dockerfile" \
|
||||
-
|
||||
else
|
||||
echo Invalid image: $image
|
||||
exit 1
|
||||
|
@ -1950,7 +1950,7 @@ impl<T> Vec<T> {
|
||||
/// assert_eq!(u, &[1, 2]);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "vec_splice", since = "1.22.0")]
|
||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||
pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<I::IntoIter>
|
||||
where R: RangeArgument<usize>, I: IntoIterator<Item=T>
|
||||
{
|
||||
@ -2553,13 +2553,13 @@ impl<'a, T> InPlace<T> for PlaceBack<'a, T> {
|
||||
/// [`splice()`]: struct.Vec.html#method.splice
|
||||
/// [`Vec`]: struct.Vec.html
|
||||
#[derive(Debug)]
|
||||
#[stable(feature = "vec_splice", since = "1.22.0")]
|
||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||
pub struct Splice<'a, I: Iterator + 'a> {
|
||||
drain: Drain<'a, I::Item>,
|
||||
replace_with: I,
|
||||
}
|
||||
|
||||
#[stable(feature = "vec_splice", since = "1.22.0")]
|
||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||
impl<'a, I: Iterator> Iterator for Splice<'a, I> {
|
||||
type Item = I::Item;
|
||||
|
||||
@ -2572,18 +2572,18 @@ impl<'a, I: Iterator> Iterator for Splice<'a, I> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "vec_splice", since = "1.22.0")]
|
||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||
impl<'a, I: Iterator> DoubleEndedIterator for Splice<'a, I> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.drain.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "vec_splice", since = "1.22.0")]
|
||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||
impl<'a, I: Iterator> ExactSizeIterator for Splice<'a, I> {}
|
||||
|
||||
|
||||
#[stable(feature = "vec_splice", since = "1.22.0")]
|
||||
#[stable(feature = "vec_splice", since = "1.21.0")]
|
||||
impl<'a, I: Iterator> Drop for Splice<'a, I> {
|
||||
fn drop(&mut self) {
|
||||
// exhaust drain first
|
||||
|
@ -456,7 +456,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
|
||||
/// assert_eq!(2, 1.max(2));
|
||||
/// assert_eq!(2, 2.max(2));
|
||||
/// ```
|
||||
#[stable(feature = "ord_max_min", since = "1.22.0")]
|
||||
#[stable(feature = "ord_max_min", since = "1.21.0")]
|
||||
fn max(self, other: Self) -> Self
|
||||
where Self: Sized {
|
||||
if other >= self { other } else { self }
|
||||
@ -472,7 +472,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
|
||||
/// assert_eq!(1, 1.min(2));
|
||||
/// assert_eq!(2, 2.min(2));
|
||||
/// ```
|
||||
#[stable(feature = "ord_max_min", since = "1.22.0")]
|
||||
#[stable(feature = "ord_max_min", since = "1.21.0")]
|
||||
fn min(self, other: Self) -> Self
|
||||
where Self: Sized {
|
||||
if self <= other { self } else { other }
|
||||
|
@ -488,13 +488,14 @@ impl<'a> Display for Arguments<'a> {
|
||||
/// The origin is: Point { x: 0, y: 0 }
|
||||
/// ```
|
||||
///
|
||||
/// There are a number of `debug_*` methods on `Formatter` to help you with manual
|
||||
/// There are a number of `debug_*` methods on [`Formatter`] to help you with manual
|
||||
/// implementations, such as [`debug_struct`][debug_struct].
|
||||
///
|
||||
/// `Debug` implementations using either `derive` or the debug builder API
|
||||
/// on `Formatter` support pretty printing using the alternate flag: `{:#?}`.
|
||||
/// on [`Formatter`] support pretty printing using the alternate flag: `{:#?}`.
|
||||
///
|
||||
/// [debug_struct]: ../../std/fmt/struct.Formatter.html#method.debug_struct
|
||||
/// [`Formatter`]: ../../std/fmt/struct.Formatter.html
|
||||
///
|
||||
/// Pretty printing with `#?`:
|
||||
///
|
||||
@ -1321,8 +1322,11 @@ impl<'a> Formatter<'a> {
|
||||
self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
|
||||
}
|
||||
|
||||
/// Creates a `DebugStruct` builder designed to assist with creation of
|
||||
/// `fmt::Debug` implementations for structs.
|
||||
/// Creates a [`DebugStruct`] builder designed to assist with creation of
|
||||
/// [`fmt::Debug`] implementations for structs.
|
||||
///
|
||||
/// [`DebugStruct`]: ../../std/fmt/struct.DebugStruct.html
|
||||
/// [`fmt::Debug`]: ../../std/fmt/trait.Debug.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -68,3 +68,22 @@ macro_rules! forward_ref_binop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// implements "T op= &U", based on "T op= U"
|
||||
// where U is expected to be `Copy`able
|
||||
macro_rules! forward_ref_op_assign {
|
||||
(impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
|
||||
forward_ref_op_assign!(impl $imp, $method for $t, $u,
|
||||
#[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
|
||||
};
|
||||
(impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
|
||||
#[$attr]
|
||||
impl<'a> $imp<&'a $u> for $t {
|
||||
#[inline]
|
||||
fn $method(&mut self, other: &'a $u) {
|
||||
$imp::$method(self, *other);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,7 +518,7 @@ pub trait Iterator {
|
||||
/// .for_each(|(i, x)| println!("{}:{}", i, x));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iterator_for_each", since = "1.22.0")]
|
||||
#[stable(feature = "iterator_for_each", since = "1.21.0")]
|
||||
fn for_each<F>(self, mut f: F) where
|
||||
Self: Sized, F: FnMut(Self::Item),
|
||||
{
|
||||
|
@ -558,7 +558,7 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
|
||||
#[unstable(feature = "fused", issue = "35602")]
|
||||
impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
|
||||
|
||||
/// An adapter for stepping iterators by a custom amount.
|
||||
/// An iterator for stepping iterators by a custom amount.
|
||||
///
|
||||
/// This `struct` is created by the [`step_by`] method on [`Iterator`]. See
|
||||
/// its documentation for more.
|
||||
|
@ -122,7 +122,7 @@ pub trait Sized {
|
||||
/// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
|
||||
/// [nomicon-coerce]: ../../nomicon/coercions.html
|
||||
#[unstable(feature = "unsize", issue = "27732")]
|
||||
#[lang="unsize"]
|
||||
#[lang = "unsize"]
|
||||
pub trait Unsize<T: ?Sized> {
|
||||
// Empty.
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "needs_drop", since = "1.22.0")]
|
||||
#[stable(feature = "needs_drop", since = "1.21.0")]
|
||||
pub fn needs_drop<T>() -> bool {
|
||||
unsafe { intrinsics::needs_drop::<T>() }
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ macro_rules! sh_impl_signed {
|
||||
*self = *self << other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shr<$f> for Wrapping<$t> {
|
||||
@ -58,6 +59,7 @@ macro_rules! sh_impl_signed {
|
||||
*self = *self >> other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
|
||||
)
|
||||
}
|
||||
|
||||
@ -80,6 +82,7 @@ macro_rules! sh_impl_unsigned {
|
||||
*self = *self << other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Shr<$f> for Wrapping<$t> {
|
||||
@ -98,6 +101,7 @@ macro_rules! sh_impl_unsigned {
|
||||
*self = *self >> other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
|
||||
)
|
||||
}
|
||||
|
||||
@ -142,6 +146,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self + other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Sub for Wrapping<$t> {
|
||||
@ -162,6 +167,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self - other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Mul for Wrapping<$t> {
|
||||
@ -182,6 +188,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self * other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_div", since = "1.3.0")]
|
||||
impl Div for Wrapping<$t> {
|
||||
@ -202,6 +209,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self / other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_impls", since = "1.7.0")]
|
||||
impl Rem for Wrapping<$t> {
|
||||
@ -222,6 +230,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self % other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Not for Wrapping<$t> {
|
||||
@ -254,6 +263,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self ^ other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl BitOr for Wrapping<$t> {
|
||||
@ -274,6 +284,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self | other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl BitAnd for Wrapping<$t> {
|
||||
@ -294,6 +305,7 @@ macro_rules! wrapping_impl {
|
||||
*self = *self & other;
|
||||
}
|
||||
}
|
||||
forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> }
|
||||
|
||||
#[stable(feature = "wrapping_neg", since = "1.10.0")]
|
||||
impl Neg for Wrapping<$t> {
|
||||
|
@ -662,6 +662,8 @@ macro_rules! add_assign_impl {
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn add_assign(&mut self, other: $t) { *self += other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -713,6 +715,8 @@ macro_rules! sub_assign_impl {
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn sub_assign(&mut self, other: $t) { *self -= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -755,6 +759,8 @@ macro_rules! mul_assign_impl {
|
||||
#[rustc_inherit_overflow_checks]
|
||||
fn mul_assign(&mut self, other: $t) { *self *= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -796,6 +802,8 @@ macro_rules! div_assign_impl {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, other: $t) { *self /= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -841,6 +849,8 @@ macro_rules! rem_assign_impl {
|
||||
#[inline]
|
||||
fn rem_assign(&mut self, other: $t) { *self %= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
|
@ -593,6 +593,8 @@ macro_rules! bitand_assign_impl {
|
||||
#[inline]
|
||||
fn bitand_assign(&mut self, other: $t) { *self &= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -638,6 +640,8 @@ macro_rules! bitor_assign_impl {
|
||||
#[inline]
|
||||
fn bitor_assign(&mut self, other: $t) { *self |= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -683,6 +687,8 @@ macro_rules! bitxor_assign_impl {
|
||||
#[inline]
|
||||
fn bitxor_assign(&mut self, other: $t) { *self ^= other }
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t }
|
||||
)+)
|
||||
}
|
||||
|
||||
@ -729,6 +735,8 @@ macro_rules! shl_assign_impl {
|
||||
*self <<= other
|
||||
}
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
|
||||
)
|
||||
}
|
||||
|
||||
@ -793,6 +801,8 @@ macro_rules! shr_assign_impl {
|
||||
*self >>= other
|
||||
}
|
||||
}
|
||||
|
||||
forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ use marker::Unsize;
|
||||
/// [unsize]: ../marker/trait.Unsize.html
|
||||
/// [nomicon-coerce]: ../../nomicon/coercions.html
|
||||
#[unstable(feature = "coerce_unsized", issue = "27732")]
|
||||
#[lang="coerce_unsized"]
|
||||
#[lang = "coerce_unsized"]
|
||||
pub trait CoerceUnsized<T> {
|
||||
// Empty.
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ pub use intrinsics::write_bytes;
|
||||
/// This has all the same safety problems as `ptr::read` with respect to
|
||||
/// invalid pointers, types, and double drops.
|
||||
#[stable(feature = "drop_in_place", since = "1.8.0")]
|
||||
#[lang="drop_in_place"]
|
||||
#[lang = "drop_in_place"]
|
||||
#[allow(unconditional_recursion)]
|
||||
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
// Code here does not matter - this is replaced by the
|
||||
|
@ -926,10 +926,24 @@ macro_rules! atomic_int {
|
||||
$stable_cxchg:meta,
|
||||
$stable_debug:meta,
|
||||
$stable_access:meta,
|
||||
$s_int_type:expr, $int_ref:expr,
|
||||
$int_type:ident $atomic_type:ident $atomic_init:ident) => {
|
||||
/// An integer type which can be safely shared between threads.
|
||||
///
|
||||
/// This type has the same in-memory representation as the underlying integer type.
|
||||
/// This type has the same in-memory representation as the underlying
|
||||
/// integer type, [`
|
||||
#[doc = $s_int_type]
|
||||
/// `](
|
||||
#[doc = $int_ref]
|
||||
/// ). For more about the differences between atomic types and
|
||||
/// non-atomic types, please see the [module-level documentation].
|
||||
///
|
||||
/// Please note that examples are shared between atomic variants of
|
||||
/// primitive integer types, so it's normal that they are all
|
||||
/// demonstrating [`AtomicIsize`].
|
||||
///
|
||||
/// [module-level documentation]: index.html
|
||||
/// [`AtomicIsize`]: struct.AtomicIsize.html
|
||||
#[$stable]
|
||||
pub struct $atomic_type {
|
||||
v: UnsafeCell<$int_type>,
|
||||
@ -1339,6 +1353,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"i8", "../../../std/primitive.i8.html",
|
||||
i8 AtomicI8 ATOMIC_I8_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "8")]
|
||||
@ -1348,6 +1363,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"u8", "../../../std/primitive.u8.html",
|
||||
u8 AtomicU8 ATOMIC_U8_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "16")]
|
||||
@ -1357,6 +1373,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"i16", "../../../std/primitive.i16.html",
|
||||
i16 AtomicI16 ATOMIC_I16_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "16")]
|
||||
@ -1366,6 +1383,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"u16", "../../../std/primitive.u16.html",
|
||||
u16 AtomicU16 ATOMIC_U16_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "32")]
|
||||
@ -1375,6 +1393,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"i32", "../../../std/primitive.i32.html",
|
||||
i32 AtomicI32 ATOMIC_I32_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "32")]
|
||||
@ -1384,6 +1403,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"u32", "../../../std/primitive.u32.html",
|
||||
u32 AtomicU32 ATOMIC_U32_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "64")]
|
||||
@ -1393,6 +1413,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"i64", "../../../std/primitive.i64.html",
|
||||
i64 AtomicI64 ATOMIC_I64_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "64")]
|
||||
@ -1402,6 +1423,7 @@ atomic_int! {
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
unstable(feature = "integer_atomics", issue = "32976"),
|
||||
"u64", "../../../std/primitive.u64.html",
|
||||
u64 AtomicU64 ATOMIC_U64_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
@ -1411,6 +1433,7 @@ atomic_int!{
|
||||
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||
stable(feature = "atomic_access", since = "1.15.0"),
|
||||
"isize", "../../../std/primitive.isize.html",
|
||||
isize AtomicIsize ATOMIC_ISIZE_INIT
|
||||
}
|
||||
#[cfg(target_has_atomic = "ptr")]
|
||||
@ -1420,6 +1443,7 @@ atomic_int!{
|
||||
stable(feature = "extended_compare_and_swap", since = "1.10.0"),
|
||||
stable(feature = "atomic_debug", since = "1.3.0"),
|
||||
stable(feature = "atomic_access", since = "1.15.0"),
|
||||
"usize", "../../../std/primitive.usize.html",
|
||||
usize AtomicUsize ATOMIC_USIZE_INIT
|
||||
}
|
||||
|
||||
@ -1752,7 +1776,7 @@ pub fn fence(order: Ordering) {
|
||||
/// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
|
||||
/// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
|
||||
#[inline]
|
||||
#[stable(feature = "compiler_fences", since = "1.22.0")]
|
||||
#[stable(feature = "compiler_fences", since = "1.21.0")]
|
||||
pub fn compiler_fence(order: Ordering) {
|
||||
unsafe {
|
||||
match order {
|
||||
|
@ -1351,74 +1351,6 @@ struct Foo<T: 'static> {
|
||||
```
|
||||
"##,
|
||||
|
||||
E0312: r##"
|
||||
A lifetime of reference outlives lifetime of borrowed content.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0312
|
||||
fn make_child<'tree, 'human>(
|
||||
x: &'human i32,
|
||||
y: &'tree i32
|
||||
) -> &'human i32 {
|
||||
if x > y
|
||||
{ x }
|
||||
else
|
||||
{ y }
|
||||
// error: lifetime of reference outlives lifetime of borrowed content
|
||||
}
|
||||
```
|
||||
|
||||
The function declares that it returns a reference with the `'human`
|
||||
lifetime, but it may return data with the `'tree` lifetime. As neither
|
||||
lifetime is declared longer than the other, this results in an
|
||||
error. Sometimes, this error is because the function *body* is
|
||||
incorrect -- that is, maybe you did not *mean* to return data from
|
||||
`y`. In that case, you should fix the function body.
|
||||
|
||||
Often, however, the body is correct. In that case, the function
|
||||
signature needs to be altered to match the body, so that the caller
|
||||
understands that data from either `x` or `y` may be returned. The
|
||||
simplest way to do this is to give both function parameters the *same*
|
||||
named lifetime:
|
||||
|
||||
```
|
||||
fn make_child<'human>(
|
||||
x: &'human i32,
|
||||
y: &'human i32
|
||||
) -> &'human i32 {
|
||||
if x > y
|
||||
{ x }
|
||||
else
|
||||
{ y } // ok!
|
||||
}
|
||||
```
|
||||
|
||||
However, in some cases, you may prefer to explicitly declare that one lifetime
|
||||
outlives another using a `where` clause:
|
||||
|
||||
```
|
||||
fn make_child<'tree, 'human>(
|
||||
x: &'human i32,
|
||||
y: &'tree i32
|
||||
) -> &'human i32
|
||||
where
|
||||
'tree: 'human
|
||||
{
|
||||
if x > y
|
||||
{ x }
|
||||
else
|
||||
{ y } // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Here, the where clause `'tree: 'human` can be read as "the lifetime
|
||||
'tree outlives the lifetime 'human" -- meaning, references with the
|
||||
`'tree` lifetime live *at least as long as* references with the
|
||||
`'human` lifetime. Therefore, it is safe to return data with lifetime
|
||||
`'tree` when data with the lifetime `'human` is needed.
|
||||
"##,
|
||||
|
||||
E0317: r##"
|
||||
This error occurs when an `if` expression without an `else` block is used in a
|
||||
context where a type other than `()` is expected, for example a `let`
|
||||
@ -2028,6 +1960,7 @@ register_diagnostics! {
|
||||
// E0304, // expected signed integer constant
|
||||
// E0305, // expected constant
|
||||
E0311, // thing may not live long enough
|
||||
E0312, // lifetime of reference outlives lifetime of borrowed content
|
||||
E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
|
||||
E0314, // closure outlives stack frame
|
||||
E0315, // cannot invoke closure outside of its lifetime
|
||||
|
@ -18,6 +18,7 @@ use infer::region_inference::RegionResolutionError;
|
||||
use hir::map as hir_map;
|
||||
use middle::resolve_lifetime as rl;
|
||||
use hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use infer::error_reporting::util::AnonymousArgInfo;
|
||||
|
||||
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// This method prints the error message for lifetime errors when both the concerned regions
|
||||
@ -57,6 +58,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let ty_sup = or_false!(self.find_anon_type(sup, &bregion_sup));
|
||||
|
||||
let ty_sub = or_false!(self.find_anon_type(sub, &bregion_sub));
|
||||
|
||||
debug!("try_report_anon_anon_conflict: found_arg1={:?} sup={:?} br1={:?}",
|
||||
ty_sub,
|
||||
sup,
|
||||
@ -66,56 +68,70 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
sub,
|
||||
bregion_sub);
|
||||
|
||||
let (main_label, label1, label2) = if let (Some(sup_arg), Some(sub_arg)) =
|
||||
(self.find_arg_with_region(sup, sup), self.find_arg_with_region(sub, sub)) {
|
||||
let (ty_sup, ty_fndecl_sup) = ty_sup;
|
||||
let (ty_sub, ty_fndecl_sub) = ty_sub;
|
||||
|
||||
let (anon_arg_sup, is_first_sup, anon_arg_sub, is_first_sub) =
|
||||
(sup_arg.arg, sup_arg.is_first, sub_arg.arg, sub_arg.is_first);
|
||||
if self.is_self_anon(is_first_sup, scope_def_id_sup) ||
|
||||
self.is_self_anon(is_first_sub, scope_def_id_sub) {
|
||||
return false;
|
||||
}
|
||||
let AnonymousArgInfo { arg: anon_arg_sup, .. } =
|
||||
or_false!(self.find_arg_with_region(sup, sup));
|
||||
let AnonymousArgInfo { arg: anon_arg_sub, .. } =
|
||||
or_false!(self.find_arg_with_region(sub, sub));
|
||||
|
||||
if self.is_return_type_anon(scope_def_id_sup, bregion_sup) ||
|
||||
self.is_return_type_anon(scope_def_id_sub, bregion_sub) {
|
||||
return false;
|
||||
}
|
||||
let sup_is_ret_type =
|
||||
self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup);
|
||||
let sub_is_ret_type =
|
||||
self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
|
||||
|
||||
if anon_arg_sup == anon_arg_sub {
|
||||
(format!("this type was declared with multiple lifetimes..."),
|
||||
format!(" with one lifetime"),
|
||||
format!(" into the other"))
|
||||
} else {
|
||||
let span_label_var1 = if let Some(simple_name) = anon_arg_sup.pat.simple_name() {
|
||||
format!(" from `{}`", simple_name)
|
||||
} else {
|
||||
format!("")
|
||||
};
|
||||
|
||||
let span_label_var2 = if let Some(simple_name) = anon_arg_sub.pat.simple_name() {
|
||||
format!(" into `{}`", simple_name)
|
||||
} else {
|
||||
format!("")
|
||||
};
|
||||
|
||||
let span_label =
|
||||
format!("these two types are declared with different lifetimes...",);
|
||||
|
||||
(span_label, span_label_var1, span_label_var2)
|
||||
}
|
||||
let span_label_var1 = if let Some(simple_name) = anon_arg_sup.pat.simple_name() {
|
||||
format!(" from `{}`", simple_name)
|
||||
} else {
|
||||
debug!("no arg with anon region found");
|
||||
debug!("try_report_anon_anon_conflict: is_suitable(sub) = {:?}",
|
||||
self.is_suitable_region(sub));
|
||||
debug!("try_report_anon_anon_conflict: is_suitable(sup) = {:?}",
|
||||
self.is_suitable_region(sup));
|
||||
return false;
|
||||
format!("")
|
||||
};
|
||||
|
||||
let span_label_var2 = if let Some(simple_name) = anon_arg_sub.pat.simple_name() {
|
||||
format!(" into `{}`", simple_name)
|
||||
} else {
|
||||
format!("")
|
||||
};
|
||||
|
||||
|
||||
let (span_1, span_2, main_label, span_label) = match (sup_is_ret_type, sub_is_ret_type) {
|
||||
(None, None) => {
|
||||
let (main_label_1, span_label_1) = if ty_sup == ty_sub {
|
||||
|
||||
(format!("this type is declared with multiple lifetimes..."),
|
||||
format!("...but data{} flows{} here",
|
||||
format!(" with one lifetime"),
|
||||
format!(" into the other")))
|
||||
} else {
|
||||
(format!("these two types are declared with different lifetimes..."),
|
||||
format!("...but data{} flows{} here",
|
||||
span_label_var1,
|
||||
span_label_var2))
|
||||
};
|
||||
(ty_sup.span, ty_sub.span, main_label_1, span_label_1)
|
||||
}
|
||||
|
||||
(Some(ret_span), _) => {
|
||||
(ty_sub.span,
|
||||
ret_span,
|
||||
format!("this parameter and the return type are declared \
|
||||
with different lifetimes...",),
|
||||
format!("...but data{} is returned here", span_label_var1))
|
||||
}
|
||||
(_, Some(ret_span)) => {
|
||||
(ty_sup.span,
|
||||
ret_span,
|
||||
format!("this parameter and the return type are declared \
|
||||
with different lifetimes...",),
|
||||
format!("...but data{} is returned here", span_label_var1))
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct_span_err!(self.tcx.sess, span, E0623, "lifetime mismatch")
|
||||
.span_label(ty_sup.span, main_label)
|
||||
.span_label(ty_sub.span, format!(""))
|
||||
.span_label(span, format!("...but data{} flows{} here", label1, label2))
|
||||
.span_label(span_1, main_label)
|
||||
.span_label(span_2, format!(""))
|
||||
.span_label(span, span_label)
|
||||
.emit();
|
||||
return true;
|
||||
}
|
||||
@ -135,28 +151,32 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
/// ```
|
||||
/// The function returns the nested type corresponding to the anonymous region
|
||||
/// for e.g. `&u8` and Vec<`&u8`.
|
||||
pub fn find_anon_type(&self, region: Region<'tcx>, br: &ty::BoundRegion) -> Option<&hir::Ty> {
|
||||
pub fn find_anon_type(&self,
|
||||
region: Region<'tcx>,
|
||||
br: &ty::BoundRegion)
|
||||
-> Option<(&hir::Ty, &hir::FnDecl)> {
|
||||
if let Some(anon_reg) = self.is_suitable_region(region) {
|
||||
let def_id = anon_reg.def_id;
|
||||
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
|
||||
let inputs: &[_] = match self.tcx.hir.get(node_id) {
|
||||
let fndecl = match self.tcx.hir.get(node_id) {
|
||||
hir_map::NodeItem(&hir::Item { node: hir::ItemFn(ref fndecl, ..), .. }) => {
|
||||
&fndecl.inputs
|
||||
&fndecl
|
||||
}
|
||||
hir_map::NodeTraitItem(&hir::TraitItem {
|
||||
node: hir::TraitItemKind::Method(ref fndecl, ..), ..
|
||||
}) => &fndecl.decl.inputs,
|
||||
node: hir::TraitItemKind::Method(ref m, ..), ..
|
||||
}) |
|
||||
hir_map::NodeImplItem(&hir::ImplItem {
|
||||
node: hir::ImplItemKind::Method(ref fndecl, ..), ..
|
||||
}) => &fndecl.decl.inputs,
|
||||
|
||||
_ => &[],
|
||||
node: hir::ImplItemKind::Method(ref m, ..), ..
|
||||
}) => &m.decl,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
return inputs
|
||||
return fndecl
|
||||
.inputs
|
||||
.iter()
|
||||
.filter_map(|arg| self.find_component_for_bound_region(&**arg, br))
|
||||
.next();
|
||||
.filter_map(|arg| self.find_component_for_bound_region(arg, br))
|
||||
.next()
|
||||
.map(|ty| (ty, &**fndecl));
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -35,15 +35,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// only introduced anonymous regions in parameters) as well as a
|
||||
// version new_ty of its type where the anonymous region is replaced
|
||||
// with the named one.//scope_def_id
|
||||
let (named, anon_arg_info, region_info) =
|
||||
let (named, anon, anon_arg_info, region_info) =
|
||||
if self.is_named_region(sub) && self.is_suitable_region(sup).is_some() &&
|
||||
self.find_arg_with_region(sup, sub).is_some() {
|
||||
(sub,
|
||||
sup,
|
||||
self.find_arg_with_region(sup, sub).unwrap(),
|
||||
self.is_suitable_region(sup).unwrap())
|
||||
} else if self.is_named_region(sup) && self.is_suitable_region(sub).is_some() &&
|
||||
self.find_arg_with_region(sub, sup).is_some() {
|
||||
(sup,
|
||||
sub,
|
||||
self.find_arg_with_region(sub, sup).unwrap(),
|
||||
self.is_suitable_region(sub).unwrap())
|
||||
} else {
|
||||
@ -76,33 +78,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.is_return_type_anon(scope_def_id, br) {
|
||||
debug!("try_report_named_anon_conflict: is_return_type_anon({:?}, {:?}) = true",
|
||||
scope_def_id,
|
||||
br);
|
||||
return false;
|
||||
} else if self.is_self_anon(is_first, scope_def_id) {
|
||||
debug!("try_report_named_anon_conflict: is_self_anon({:?}, {:?}) = true",
|
||||
is_first,
|
||||
scope_def_id);
|
||||
return false;
|
||||
} else {
|
||||
let (error_var, span_label_var) = if let Some(simple_name) = arg.pat.simple_name() {
|
||||
(format!("the type of `{}`", simple_name), format!("the type of `{}`", simple_name))
|
||||
} else {
|
||||
("parameter type".to_owned(), "type".to_owned())
|
||||
};
|
||||
|
||||
struct_span_err!(self.tcx.sess,
|
||||
span,
|
||||
E0621,
|
||||
"explicit lifetime required in {}",
|
||||
error_var)
|
||||
.span_label(arg.pat.span,
|
||||
format!("consider changing {} to `{}`", span_label_var, new_ty))
|
||||
.span_label(span, format!("lifetime `{}` required", named))
|
||||
.emit();
|
||||
return true;
|
||||
if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
|
||||
if self.is_return_type_anon(scope_def_id, br, fndecl).is_some() ||
|
||||
self.is_self_anon(is_first, scope_def_id) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let (error_var, span_label_var) = if let Some(simple_name) = arg.pat.simple_name() {
|
||||
(format!("the type of `{}`", simple_name), format!("the type of `{}`", simple_name))
|
||||
} else {
|
||||
("parameter type".to_owned(), "type".to_owned())
|
||||
};
|
||||
|
||||
struct_span_err!(self.tcx.sess,
|
||||
span,
|
||||
E0621,
|
||||
"explicit lifetime required in {}",
|
||||
error_var)
|
||||
.span_label(arg.pat.span,
|
||||
format!("consider changing {} to `{}`", span_label_var, new_ty))
|
||||
.span_label(span, format!("lifetime `{}` required", named))
|
||||
.emit();
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use infer::InferCtxt;
|
||||
use ty::{self, Region, Ty};
|
||||
use hir::def_id::DefId;
|
||||
use hir::map as hir_map;
|
||||
use syntax_pos::Span;
|
||||
|
||||
macro_rules! or_false {
|
||||
($v:expr) => {
|
||||
@ -163,7 +164,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// Here, we check for the case where the anonymous region
|
||||
// is in the return type.
|
||||
// FIXME(#42703) - Need to handle certain cases here.
|
||||
pub fn is_return_type_anon(&self, scope_def_id: DefId, br: ty::BoundRegion) -> bool {
|
||||
pub fn is_return_type_anon(&self,
|
||||
scope_def_id: DefId,
|
||||
br: ty::BoundRegion,
|
||||
decl: &hir::FnDecl)
|
||||
-> Option<Span> {
|
||||
let ret_ty = self.tcx.type_of(scope_def_id);
|
||||
match ret_ty.sty {
|
||||
ty::TyFnDef(_, _) => {
|
||||
@ -171,12 +176,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
let late_bound_regions = self.tcx
|
||||
.collect_referenced_late_bound_regions(&sig.output());
|
||||
if late_bound_regions.iter().any(|r| *r == br) {
|
||||
return true;
|
||||
return Some(decl.output.span());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
false
|
||||
None
|
||||
}
|
||||
// Here we check for the case where anonymous region
|
||||
// corresponds to self and if yes, we display E0312.
|
||||
|
@ -70,14 +70,6 @@ impl SerializedDepGraph {
|
||||
RustcEncodable, RustcDecodable)]
|
||||
pub struct DepNodeIndex(pub u32);
|
||||
|
||||
impl DepNodeIndex {
|
||||
#[inline]
|
||||
pub fn new(idx: usize) -> DepNodeIndex {
|
||||
assert!(idx <= ::std::u32::MAX as usize);
|
||||
DepNodeIndex(idx as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Idx for DepNodeIndex {
|
||||
#[inline]
|
||||
fn new(idx: usize) -> Self {
|
||||
|
@ -19,7 +19,7 @@ use rustc::util::common::time;
|
||||
use rustc::util::nodemap::DefIdMap;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::graph;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc_serialize::Encodable as RustcEncodable;
|
||||
use rustc_serialize::opaque::Encoder;
|
||||
use std::io::{self, Cursor, Write};
|
||||
|
@ -1332,6 +1332,12 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
|
||||
fn predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> ty::GenericPredicates<'tcx> {
|
||||
explicit_predicates_of(tcx, def_id)
|
||||
}
|
||||
|
||||
fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId)
|
||||
-> ty::GenericPredicates<'tcx> {
|
||||
use rustc::hir::map::*;
|
||||
use rustc::hir::*;
|
||||
|
||||
|
@ -691,6 +691,17 @@ impl<K, V, S> HashMap<K, V, S>
|
||||
/// Returns a reference to the map's [`BuildHasher`].
|
||||
///
|
||||
/// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashMap;
|
||||
/// use std::collections::hash_map::RandomState;
|
||||
///
|
||||
/// let hasher = RandomState::new();
|
||||
/// let map: HashMap<isize, isize> = HashMap::with_hasher(hasher);
|
||||
/// let hasher: &RandomState = map.hasher();
|
||||
/// ```
|
||||
#[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
|
||||
pub fn hasher(&self) -> &S {
|
||||
&self.hash_builder
|
||||
|
@ -167,7 +167,7 @@ impl TcpStream {
|
||||
/// connection request.
|
||||
///
|
||||
/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
|
||||
#[stable(feature = "tcpstream_connect_timeout", since = "1.22.0")]
|
||||
#[stable(feature = "tcpstream_connect_timeout", since = "1.21.0")]
|
||||
pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
|
||||
net_imp::TcpStream::connect_timeout(addr, timeout).map(TcpStream)
|
||||
}
|
||||
|
@ -65,6 +65,31 @@ pub struct Guard {
|
||||
/// each lock, but once a lock is poisoned then all future acquisitions will
|
||||
/// return this error.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::{Arc, Mutex};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mutex = Arc::new(Mutex::new(1));
|
||||
///
|
||||
/// // poison the mutex
|
||||
/// let c_mutex = mutex.clone();
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// let mut data = c_mutex.lock().unwrap();
|
||||
/// *data = 2;
|
||||
/// panic!();
|
||||
/// }).join();
|
||||
///
|
||||
/// match mutex.lock() {
|
||||
/// Ok(_) => unreachable!(),
|
||||
/// Err(p_err) => {
|
||||
/// let data = p_err.get_ref();
|
||||
/// println!("recovered: {}", data);
|
||||
/// }
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// [`Mutex`]: ../../std/sync/struct.Mutex.html
|
||||
/// [`RwLock`]: ../../std/sync/struct.RwLock.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -72,10 +97,16 @@ pub struct PoisonError<T> {
|
||||
guard: T,
|
||||
}
|
||||
|
||||
/// An enumeration of possible errors which can occur while calling the
|
||||
/// [`try_lock`] method.
|
||||
/// An enumeration of possible errors associated with a [`TryLockResult`] which
|
||||
/// can occur while trying to aquire a lock, from the [`try_lock`] method on a
|
||||
/// [`Mutex`] or the [`try_read`] and [`try_write`] methods on an [`RwLock`].
|
||||
///
|
||||
/// [`Mutex`]: struct.Mutex.html
|
||||
/// [`RwLock`]: struct.RwLock.html
|
||||
/// [`TryLockResult`]: type.TryLockResult.html
|
||||
/// [`try_lock`]: struct.Mutex.html#method.try_lock
|
||||
/// [`try_read`]: struct.RwLock.html#method.try_read
|
||||
/// [`try_write`]: struct.RwLock.html#method.try_write
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub enum TryLockError<T> {
|
||||
/// The lock could not be acquired because another thread failed while holding
|
||||
@ -148,6 +179,28 @@ impl<T> PoisonError<T> {
|
||||
|
||||
/// Consumes this error indicating that a lock is poisoned, returning the
|
||||
/// underlying guard to allow access regardless.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashSet;
|
||||
/// use std::sync::{Arc, Mutex};
|
||||
/// use std::thread;
|
||||
///
|
||||
/// let mutex = Arc::new(Mutex::new(HashSet::new()));
|
||||
///
|
||||
/// // poison the mutex
|
||||
/// let c_mutex = mutex.clone();
|
||||
/// let _ = thread::spawn(move || {
|
||||
/// let mut data = c_mutex.lock().unwrap();
|
||||
/// data.insert(10);
|
||||
/// panic!();
|
||||
/// }).join();
|
||||
///
|
||||
/// let p_err = mutex.lock().unwrap_err();
|
||||
/// let data = p_err.into_inner();
|
||||
/// println!("recovered {} items", data.len());
|
||||
/// ```
|
||||
#[stable(feature = "sync_poison", since = "1.2.0")]
|
||||
pub fn into_inner(self) -> T { self.guard }
|
||||
|
||||
|
@ -38,7 +38,7 @@ trait Copy {}
|
||||
trait Freeze {}
|
||||
impl Freeze for .. {}
|
||||
|
||||
#[lang="drop_in_place"]
|
||||
#[lang = "drop_in_place"]
|
||||
#[inline]
|
||||
#[allow(unconditional_recursion)]
|
||||
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
|
@ -25,7 +25,7 @@ trait Copy {}
|
||||
trait Freeze {}
|
||||
impl Freeze for .. {}
|
||||
|
||||
#[lang="drop_in_place"]
|
||||
#[lang = "drop_in_place"]
|
||||
#[inline]
|
||||
#[allow(unconditional_recursion)]
|
||||
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
|
@ -34,7 +34,7 @@ fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
|
||||
b: &'b MyBox<SomeTrait>)
|
||||
-> &'b MyBox<SomeTrait>
|
||||
{
|
||||
a //~ ERROR E0312
|
||||
a //~ ERROR lifetime mismatch
|
||||
}
|
||||
|
||||
fn load2<'a>(ss: &MyBox<SomeTrait+'a>) -> MyBox<SomeTrait+'a> {
|
||||
|
@ -9,12 +9,12 @@
|
||||
// except according to those terms.
|
||||
|
||||
// Test that the type of `sum` falls back to `i32` here,
|
||||
// and that the for loop desugaring doesn't inferfere with
|
||||
// and that the for loop desugaring doesn't interfere with
|
||||
// that.
|
||||
|
||||
fn main() {
|
||||
let mut sum = 0;
|
||||
for i in Vec::new() {
|
||||
sum += i;
|
||||
sum += &i;
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +173,15 @@ fn test_op_assigns() {
|
||||
tmp.$op(Wrapping($rhs));
|
||||
assert_eq!(black_box(tmp), Wrapping($ans));
|
||||
}
|
||||
|
||||
// also test that a &Wrapping<T> right-hand side is possible
|
||||
{
|
||||
let mut tmp = Wrapping($initial);
|
||||
tmp = black_box(tmp);
|
||||
tmp.$op(&Wrapping($rhs));
|
||||
assert_eq!(black_box(tmp), Wrapping($ans));
|
||||
}
|
||||
|
||||
// FIXME(30524): Uncomment this test
|
||||
/*
|
||||
{
|
||||
|
84
src/test/run-pass/op-assign-builtins-by-ref.rs
Normal file
84
src/test/run-pass/op-assign-builtins-by-ref.rs
Normal file
@ -0,0 +1,84 @@
|
||||
// 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.
|
||||
|
||||
fn main() {
|
||||
// test compound assignment operators with ref as right-hand side,
|
||||
// for each operator, with various types as operands.
|
||||
|
||||
// test AddAssign
|
||||
{
|
||||
let mut x = 3i8;
|
||||
x += &2i8;
|
||||
assert_eq!(x, 5i8);
|
||||
}
|
||||
|
||||
// test SubAssign
|
||||
{
|
||||
let mut x = 7i16;
|
||||
x -= &4;
|
||||
assert_eq!(x, 3i16);
|
||||
}
|
||||
|
||||
// test MulAssign
|
||||
{
|
||||
let mut x = 3f32;
|
||||
x *= &3f32;
|
||||
assert_eq!(x, 9f32);
|
||||
}
|
||||
|
||||
// test DivAssign
|
||||
{
|
||||
let mut x = 6f64;
|
||||
x /= &2f64;
|
||||
assert_eq!(x, 3f64);
|
||||
}
|
||||
|
||||
// test RemAssign
|
||||
{
|
||||
let mut x = 7i64;
|
||||
x %= &4i64;
|
||||
assert_eq!(x, 3i64);
|
||||
}
|
||||
|
||||
// test BitOrAssign
|
||||
{
|
||||
let mut x = 0b1010u8;
|
||||
x |= &0b1100u8;
|
||||
assert_eq!(x, 0b1110u8);
|
||||
}
|
||||
|
||||
// test BitAndAssign
|
||||
{
|
||||
let mut x = 0b1010u16;
|
||||
x &= &0b1100u16;
|
||||
assert_eq!(x, 0b1000u16);
|
||||
}
|
||||
|
||||
// test BitXorAssign
|
||||
{
|
||||
let mut x = 0b1010u32;
|
||||
x ^= &0b1100u32;
|
||||
assert_eq!(x, 0b0110u32);
|
||||
}
|
||||
|
||||
// test ShlAssign
|
||||
{
|
||||
let mut x = 0b1010u64;
|
||||
x <<= &2u32;
|
||||
assert_eq!(x, 0b101000u64);
|
||||
}
|
||||
|
||||
// test ShrAssign
|
||||
{
|
||||
let mut x = 0b1010u64;
|
||||
x >>= &2i16;
|
||||
assert_eq!(x, 0b10u64);
|
||||
}
|
||||
}
|
@ -1,27 +1,13 @@
|
||||
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:21:20
|
||||
|
|
||||
19 | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
|
||||
| ---- -------
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
20 |
|
||||
21 | if x > y { x } else { y }
|
||||
| ^
|
||||
|
|
||||
note: ...the reference is valid for the lifetime 'a as defined on the method body at 19:5...
|
||||
--> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:19:5
|
||||
|
|
||||
19 | / fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
|
||||
20 | |
|
||||
21 | | if x > y { x } else { y }
|
||||
22 | |
|
||||
23 | | }
|
||||
| |_____^
|
||||
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 19:5
|
||||
--> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:19:5
|
||||
|
|
||||
19 | / fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
|
||||
20 | |
|
||||
21 | | if x > y { x } else { y }
|
||||
22 | |
|
||||
23 | | }
|
||||
| |_____^
|
||||
| ^ ...but data from `x` is returned here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,27 +1,13 @@
|
||||
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:18:5
|
||||
|
|
||||
16 | fn foo<'a>(&self, x: &'a i32) -> &i32 {
|
||||
| ------- ----
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
17 |
|
||||
18 | x
|
||||
| ^
|
||||
|
|
||||
note: ...the reference is valid for the anonymous lifetime #1 defined on the method body at 16:3...
|
||||
--> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:16:3
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &'a i32) -> &i32 {
|
||||
17 | |
|
||||
18 | | x
|
||||
19 | |
|
||||
20 | | }
|
||||
| |___^
|
||||
note: ...but the borrowed content is only valid for the lifetime 'a as defined on the method body at 16:3
|
||||
--> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:16:3
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &'a i32) -> &i32 {
|
||||
17 | |
|
||||
18 | | x
|
||||
19 | |
|
||||
20 | | }
|
||||
| |___^
|
||||
| ^ ...but data from `x` is returned here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,27 +1,13 @@
|
||||
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex1-return-one-existing-name-self-is-anon.rs:18:30
|
||||
|
|
||||
16 | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
|
||||
| ----- -------
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
17 |
|
||||
18 | if true { x } else { self }
|
||||
| ^^^^
|
||||
|
|
||||
note: ...the reference is valid for the lifetime 'a as defined on the method body at 16:5...
|
||||
--> $DIR/ex1-return-one-existing-name-self-is-anon.rs:16:5
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
|
||||
17 | |
|
||||
18 | | if true { x } else { self }
|
||||
19 | |
|
||||
20 | | }
|
||||
| |_____^
|
||||
note: ...but the borrowed content is only valid for the anonymous lifetime #1 defined on the method body at 16:5
|
||||
--> $DIR/ex1-return-one-existing-name-self-is-anon.rs:16:5
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
|
||||
17 | |
|
||||
18 | | if true { x } else { self }
|
||||
19 | |
|
||||
20 | | }
|
||||
| |_____^
|
||||
| ^^^^ ...but data from `self` is returned here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0623]: lifetime mismatch
|
||||
15 | fn foo(mut x: Ref) {
|
||||
| ---
|
||||
| |
|
||||
| this type was declared with multiple lifetimes...
|
||||
| this type is declared with multiple lifetimes...
|
||||
16 | x.a = x.b;
|
||||
| ^^^ ...but data with one lifetime flows into the other here
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0623]: lifetime mismatch
|
||||
15 | fn foo(mut x: Ref) {
|
||||
| ---
|
||||
| |
|
||||
| this type was declared with multiple lifetimes...
|
||||
| this type is declared with multiple lifetimes...
|
||||
16 | x.a = x.b;
|
||||
| ^^^ ...but data with one lifetime flows into the other here
|
||||
|
||||
|
@ -1,23 +1,12 @@
|
||||
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:17:5
|
||||
|
|
||||
16 | fn foo<'a>(&self, x: &i32) -> &i32 {
|
||||
| ---- ----
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
17 | x
|
||||
| ^
|
||||
|
|
||||
note: ...the reference is valid for the anonymous lifetime #1 defined on the method body at 16:3...
|
||||
--> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:16:3
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &i32) -> &i32 {
|
||||
17 | | x
|
||||
18 | | }
|
||||
| |___^
|
||||
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 16:3
|
||||
--> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:16:3
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &i32) -> &i32 {
|
||||
17 | | x
|
||||
18 | | }
|
||||
| |___^
|
||||
| ^ ...but data from `x` is returned here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,23 +1,12 @@
|
||||
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ex3-both-anon-regions-self-is-anon.rs:17:19
|
||||
|
|
||||
16 | fn foo<'a>(&self, x: &Foo) -> &Foo {
|
||||
| ---- ----
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
17 | if true { x } else { self }
|
||||
| ^
|
||||
|
|
||||
note: ...the reference is valid for the anonymous lifetime #1 defined on the method body at 16:5...
|
||||
--> $DIR/ex3-both-anon-regions-self-is-anon.rs:16:5
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &Foo) -> &Foo {
|
||||
17 | | if true { x } else { self }
|
||||
18 | | }
|
||||
| |_____^
|
||||
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 16:5
|
||||
--> $DIR/ex3-both-anon-regions-self-is-anon.rs:16:5
|
||||
|
|
||||
16 | / fn foo<'a>(&self, x: &Foo) -> &Foo {
|
||||
17 | | if true { x } else { self }
|
||||
18 | | }
|
||||
| |_____^
|
||||
| ^ ...but data from `x` is returned here
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -49,7 +49,7 @@ const TEST_REPOS: &'static [Test] = &[
|
||||
Test {
|
||||
name: "xsv",
|
||||
repo: "https://github.com/BurntSushi/xsv",
|
||||
sha: "a9a7163f2a2953cea426fee1216bec914fe2f56a",
|
||||
sha: "4b308adbe48ac81657fd124b90b44f7c3263f771",
|
||||
lock: None,
|
||||
},
|
||||
];
|
||||
|
Loading…
x
Reference in New Issue
Block a user