From f65bb2a051a6362b3e2dcdf3e081b8c76f5ef1a7 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Sat, 2 Sep 2017 22:50:01 -0400 Subject: [PATCH 01/29] Manuall rebase of @Migi pull/41336 --- src/libcore/internal_macros.rs | 19 +++++ src/libcore/num/wrapping.rs | 12 +++ src/libcore/ops/arith.rs | 10 +++ src/libcore/ops/bit.rs | 10 +++ src/test/run-pass/num-wrapping.rs | 9 ++ .../run-pass/op-assign-builtins-by-ref.rs | 84 +++++++++++++++++++ 6 files changed, 144 insertions(+) create mode 100644 src/test/run-pass/op-assign-builtins-by-ref.rs diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs index 9a7914064fdd5..bd30a92b07907 100644 --- a/src/libcore/internal_macros.rs +++ b/src/libcore/internal_macros.rs @@ -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.18.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); + } + } + } +} + diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index acdf685e850ab..ae1b0b3ce11b2 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -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> { diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index 62007caedd3fc..8b3d662a6db77 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -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 } )+) } diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs index 0bc5e554cb347..7ac5fc4debf14 100644 --- a/src/libcore/ops/bit.rs +++ b/src/libcore/ops/bit.rs @@ -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 } ) } diff --git a/src/test/run-pass/num-wrapping.rs b/src/test/run-pass/num-wrapping.rs index 143759e271561..20c7f27336e25 100644 --- a/src/test/run-pass/num-wrapping.rs +++ b/src/test/run-pass/num-wrapping.rs @@ -173,6 +173,15 @@ fn test_op_assigns() { tmp.$op(Wrapping($rhs)); assert_eq!(black_box(tmp), Wrapping($ans)); } + + // also test that a &Wrapping 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 /* { diff --git a/src/test/run-pass/op-assign-builtins-by-ref.rs b/src/test/run-pass/op-assign-builtins-by-ref.rs new file mode 100644 index 0000000000000..77023a566794f --- /dev/null +++ b/src/test/run-pass/op-assign-builtins-by-ref.rs @@ -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 or the MIT license +// , 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); + } +} \ No newline at end of file From 9a547fc7c49f484b0be223d53cd0c6a08bbadef5 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Sun, 3 Sep 2017 13:07:47 -0400 Subject: [PATCH 02/29] get ci green --- .../for-loop-unconstrained-element-type-i32-fallback.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs b/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs index b36afcf87b3ee..264efa9f40227 100644 --- a/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs +++ b/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs @@ -9,9 +9,11 @@ // 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. +// ignore-test + fn main() { let mut sum = 0; for i in Vec::new() { From 732dd2fd5f5fb28193408b64ade0e940434d239f Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Tue, 12 Sep 2017 16:56:40 -0400 Subject: [PATCH 03/29] Missing trailing newline --- src/test/run-pass/op-assign-builtins-by-ref.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-pass/op-assign-builtins-by-ref.rs b/src/test/run-pass/op-assign-builtins-by-ref.rs index 77023a566794f..230d44ba647a5 100644 --- a/src/test/run-pass/op-assign-builtins-by-ref.rs +++ b/src/test/run-pass/op-assign-builtins-by-ref.rs @@ -81,4 +81,4 @@ fn main() { x >>= &2i16; assert_eq!(x, 0b10u64); } -} \ No newline at end of file +} From b91bac29835fb7d70ee5d29cac970efa18eeba89 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Thu, 14 Sep 2017 10:46:14 -0400 Subject: [PATCH 04/29] readd test --- .../for-loop-unconstrained-element-type-i32-fallback.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs b/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs index 264efa9f40227..0bfc4d2264c62 100644 --- a/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs +++ b/src/test/run-pass/for-loop-unconstrained-element-type-i32-fallback.rs @@ -12,11 +12,9 @@ // and that the for loop desugaring doesn't interfere with // that. -// ignore-test - fn main() { let mut sum = 0; for i in Vec::new() { - sum += i; + sum += &i; } } From 2c78bb49fde79e93b110a979f1f11b3f1221e1ef Mon Sep 17 00:00:00 2001 From: Tommy Ip Date: Wed, 20 Sep 2017 18:14:19 +0100 Subject: [PATCH 05/29] Add --all flag to ./x.py clean This flag removes all build artifacts, including the LLVM build directory. --- src/bootstrap/builder.rs | 2 +- src/bootstrap/clean.rs | 35 ++++++++++++++++++++--------------- src/bootstrap/flags.rs | 10 ++++++++-- src/bootstrap/lib.rs | 4 ++-- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7d116f23ef581..935b690497b52 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -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 { diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 119340a0190c4..87f194fb7d2f8 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -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); } } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 7546d7fd4f07a..34b0ca627aad1 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -60,7 +60,9 @@ pub enum Subcommand { paths: Vec, test_args: Vec, }, - Clean, + Clean { + all: bool, + }, Dist { paths: Vec, }, @@ -147,6 +149,7 @@ To learn more about a subcommand, run `./x.py -h`"); opts.optmulti("", "test-args", "extra arguments", "ARGS"); }, "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); }, + "clean" => { opts.optflag("", "all", "clean all build artifacts"); }, _ => { }, }; @@ -293,7 +296,10 @@ Arguments: println!("\nclean takes no arguments\n"); usage(1, &opts, &subcommand_help, &extra_help); } - Subcommand::Clean + + Subcommand::Clean { + all: matches.opt_present("all"), + } } "dist" => { Subcommand::Dist { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 06c7c4c2faffc..0876786f9a544 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -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"); From 09d90e52682641e5d6d0a70e42011fd24ced1434 Mon Sep 17 00:00:00 2001 From: Tommy Ip Date: Wed, 20 Sep 2017 19:31:59 +0100 Subject: [PATCH 06/29] Do not show "available paths" help in ./x.py clean --- src/bootstrap/flags.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 34b0ca627aad1..df378188b4ad0 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -253,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); @@ -261,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? @@ -293,7 +294,7 @@ 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); } From cfc711e062e607dc5defad439b9ee34b5ba6fcef Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Thu, 21 Sep 2017 15:46:17 -0400 Subject: [PATCH 07/29] fix version number --- src/libcore/internal_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs index bd30a92b07907..cb215a38e5356 100644 --- a/src/libcore/internal_macros.rs +++ b/src/libcore/internal_macros.rs @@ -74,7 +74,7 @@ macro_rules! forward_ref_binop { 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.18.0")]); + #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]); }; (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => { #[$attr] From 2adeba62077fc7630d57705cce4f2f0e9029351e Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Thu, 21 Sep 2017 15:53:33 -0400 Subject: [PATCH 08/29] update xsv to head --- src/tools/cargotest/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 012ee835494e8..0a9da26d9968d 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -49,7 +49,7 @@ const TEST_REPOS: &'static [Test] = &[ Test { name: "xsv", repo: "https://github.com/BurntSushi/xsv", - sha: "a9a7163f2a2953cea426fee1216bec914fe2f56a", + sha: "4b308adbe48ac81657fd124b90b44f7c3263f771", lock: None, }, ]; From 15fa85c195c38f9b0c2a9003d68d05727603ef68 Mon Sep 17 00:00:00 2001 From: toidiu Date: Sat, 23 Sep 2017 14:55:40 -0400 Subject: [PATCH 09/29] extract explicit_predicates_of --- src/librustc_typeck/collect.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 79cb9147c185b..8f7cf946a49dc 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1325,6 +1325,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::*; From 99c0c520aff7f9858340406631d9de763a743d41 Mon Sep 17 00:00:00 2001 From: Lucas Morales Date: Sat, 23 Sep 2017 18:28:08 -0400 Subject: [PATCH 10/29] docs improvement std::sync::{PoisonError, TryLockError} --- src/libstd/sys_common/poison.rs | 57 +++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys_common/poison.rs b/src/libstd/sys_common/poison.rs index 3c61593acc55b..934ac3edbf1f1 100644 --- a/src/libstd/sys_common/poison.rs +++ b/src/libstd/sys_common/poison.rs @@ -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 { 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 { /// The lock could not be acquired because another thread failed while holding @@ -148,6 +179,28 @@ impl PoisonError { /// 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 } From bc43e1739234727ebddaf475c2851eab00353324 Mon Sep 17 00:00:00 2001 From: Ethan Dagner Date: Sat, 23 Sep 2017 11:47:21 -0600 Subject: [PATCH 11/29] Add doc example to HashMap::hasher --- src/libstd/collections/hash/map.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 96af227257824..f28577d257e74 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -691,6 +691,17 @@ impl HashMap /// 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 = 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 From 874124b2c73dc764aa83f7ba9711a4170c0aeffc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 24 Sep 2017 22:23:26 -0700 Subject: [PATCH 12/29] Backport libs stabilizations to 1.21 beta This includes the following stabilizations: - tcpstream_connect_timeout https://github.com/rust-lang/rust/pull/44563 - iterator_for_each https://github.com/rust-lang/rust/pull/44567 - ord_max_min https://github.com/rust-lang/rust/pull/44593 - compiler_fences https://github.com/rust-lang/rust/pull/44595 - needs_drop https://github.com/rust-lang/rust/pull/44639 - vec_splice https://github.com/rust-lang/rust/pull/44640 --- src/liballoc/vec.rs | 12 ++++++------ src/libcore/cmp.rs | 4 ++-- src/libcore/iter/iterator.rs | 2 +- src/libcore/mem.rs | 2 +- src/libcore/sync/atomic.rs | 2 +- src/libstd/net/tcp.rs | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 7dd8895c1ae4c..725d3e15f4a61 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -1950,7 +1950,7 @@ impl Vec { /// 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(&mut self, range: R, replace_with: I) -> Splice where R: RangeArgument, I: IntoIterator { @@ -2553,13 +2553,13 @@ impl<'a, T> InPlace 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.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 diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 6f86f8caad073..e012cbd76ff91 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -456,7 +456,7 @@ pub trait Ord: Eq + PartialOrd { /// 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 { /// 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 } diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 36bf9633b4a35..e9e31065cf876 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -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(self, mut f: F) where Self: Sized, F: FnMut(Self::Item), { diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 669b93120cf45..c869054cee81a 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -402,7 +402,7 @@ pub fn align_of_val(val: &T) -> usize { /// } /// ``` #[inline] -#[stable(feature = "needs_drop", since = "1.22.0")] +#[stable(feature = "needs_drop", since = "1.21.0")] pub fn needs_drop() -> bool { unsafe { intrinsics::needs_drop::() } } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 3dd08e6971066..2bb40cb672e26 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1752,7 +1752,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 { diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index aff9af66444c4..8d1e7882e5db4 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -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 { net_imp::TcpStream::connect_timeout(addr, timeout).map(TcpStream) } From d5d41f2a3c83f2df11b14c81bfe6a76ccdb099e3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 25 Sep 2017 15:41:16 +0200 Subject: [PATCH 13/29] Add missing links in fmt module --- src/libcore/fmt/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index b84a1deb61144..6c251b9eb0924 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -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 /// From 3db0094359095aaf2ef3769b9fe2e3b3ff65cf98 Mon Sep 17 00:00:00 2001 From: steveklabnik Date: Mon, 25 Sep 2017 11:41:39 -0400 Subject: [PATCH 14/29] Improve wording for StepBy No other iterator makes the distinction between an iterator and an iterator adapter in its summary line, so change it to be consistent with all other adapters. --- src/libcore/iter/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 7907f2fd66126..14b87f42f6a79 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -546,7 +546,7 @@ impl Iterator for Cycle where I: Clone + Iterator { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for Cycle 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. From 20d4c0fab418edf036b7e0f1910053d3437da269 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 25 Sep 2017 20:06:03 +0200 Subject: [PATCH 15/29] Move src/librustc_mir/transform/nll.rs to a subdirectory --- src/librustc_mir/transform/{nll.rs => nll/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/librustc_mir/transform/{nll.rs => nll/mod.rs} (100%) diff --git a/src/librustc_mir/transform/nll.rs b/src/librustc_mir/transform/nll/mod.rs similarity index 100% rename from src/librustc_mir/transform/nll.rs rename to src/librustc_mir/transform/nll/mod.rs From f7fd04ae65d30c3b0af36623bbeb299bbc52d710 Mon Sep 17 00:00:00 2001 From: Lucas Morales Date: Mon, 25 Sep 2017 19:39:52 -0400 Subject: [PATCH 16/29] docs improvement sync::atomic::Atomic* --- src/libcore/sync/atomic.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 3dd08e6971066..bf11e18e4f337 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -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 } From e58f528bb0664c33355ff6b0aa125b8a751fee2a Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Mon, 11 Sep 2017 19:59:57 +0530 Subject: [PATCH 17/29] merge fixes, addressing CR comments --- .../error_reporting/different_lifetimes.rs | 132 +++++++++++------- .../error_reporting/named_anon_conflict.rs | 53 ++++--- src/librustc/infer/error_reporting/util.rs | 11 +- ...e-existing-name-return-type-is-anon.stderr | 26 +--- ...turn-one-existing-name-self-is-anon.stderr | 26 +--- ...th-anon-regions-return-type-is-anon.stderr | 24 +--- .../ex3-both-anon-regions-self-is-anon.stderr | 24 +--- 7 files changed, 138 insertions(+), 158 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index 6c57130a9955f..687b518ef6aff 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -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,78 @@ 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_var1 = if let Some(simple_name) = anon_arg_sup.pat.simple_name() { + format!(" flows 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_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...",); + 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 { - (span_label, span_label_var1, span_label_var2) + (format!("this type was declared with multiple lifetimes..."), + format!("...but data{} flows{} here", + format!(" with one lifetime"), + format!(" into the other"))) + } else { + (format!("these two types was declared with multiple 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_span1), Some(ret_span2)) => { + (ret_span1, + ret_span2, + format!("the return type is declared with different lifetimes..."), + format!("...but data{} flows{} here", + format!(" with one lifetime"), + format!(" into the other"))) + } + + (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)) } - } 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; }; + 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 +159,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 diff --git a/src/librustc/infer/error_reporting/named_anon_conflict.rs b/src/librustc/infer/error_reporting/named_anon_conflict.rs index a3bbdab497a9b..7027c868e6efe 100644 --- a/src/librustc/infer/error_reporting/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/named_anon_conflict.rs @@ -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,30 @@ 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; + if let Some(anon_ty) = self.find_anon_type(anon, &br) { + let (_, fndecl) = anon_ty; + 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 { - 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()) - }; + ("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; - 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; - } } } diff --git a/src/librustc/infer/error_reporting/util.rs b/src/librustc/infer/error_reporting/util.rs index 94faec464b244..47db3f1b7926a 100644 --- a/src/librustc/infer/error_reporting/util.rs +++ b/src/librustc/infer/error_reporting/util.rs @@ -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 { 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. diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index e3fd0192053b9..4a1673a531d34 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -1,27 +1,11 @@ -error[E0312]: lifetime of reference outlives lifetime of borrowed content... +error[E0621]: explicit lifetime required in the type of `self` --> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:18:5 | +16 | fn foo<'a>(&self, x: &'a i32) -> &i32 { + | ----- consider changing the type of `self` to `&'a Foo` +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 | | } - | |___^ + | ^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 8551f015db527..973c5ed72f875 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -1,27 +1,11 @@ -error[E0312]: lifetime of reference outlives lifetime of borrowed content... +error[E0621]: explicit lifetime required in the type of `self` --> $DIR/ex1-return-one-existing-name-self-is-anon.rs:18:30 | +16 | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { + | ----- consider changing the type of `self` to `&'a Foo` +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 | | } - | |_____^ + | ^^^^ lifetime `'a` required error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index 890f9b311e7d2..c6b1280ca95aa 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -1,23 +1,13 @@ -error[E0312]: lifetime of reference outlives lifetime of borrowed content... +error[E0621]: explicit lifetime required in the type of `self` --> $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 diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index 43f00c32c6285..9b15de1b1738f 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -1,23 +1,13 @@ -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 From aa6f0c80507230d864f7af5fe3c4085e28cabfe9 Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Mon, 11 Sep 2017 20:27:26 +0530 Subject: [PATCH 18/29] modify message for return time having multiple lifetimes --- .../error_reporting/different_lifetimes.rs | 12 ++------ ...ne-existing-name-if-else-using-impl.stderr | 29 +++++-------------- ...e-existing-name-return-type-is-anon.stderr | 9 ++++-- ...turn-one-existing-name-self-is-anon.stderr | 9 ++++-- ...th-anon-regions-return-type-is-anon.stderr | 6 ++-- .../ex3-both-anon-regions-self-is-anon.stderr | 4 +-- 6 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index 687b518ef6aff..e9866545f976a 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -82,7 +82,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub); let span_label_var1 = if let Some(simple_name) = anon_arg_sup.pat.simple_name() { - format!(" flows from `{}`", simple_name) + format!(" from `{}`", simple_name) } else { format!("") }; @@ -103,21 +103,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { format!(" with one lifetime"), format!(" into the other"))) } else { - (format!("these two types was declared with multiple lifetimes..."), + (format!("these two types was 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_span1), Some(ret_span2)) => { - (ret_span1, - ret_span2, - format!("the return type is declared with different lifetimes..."), - format!("...but data{} flows{} here", - format!(" with one lifetime"), - format!(" into the other"))) - } (Some(ret_span), _) => { (ty_sub.span, diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr index 9e4f6c421790f..f383a4dcf673e 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr @@ -1,27 +1,14 @@ -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 flows `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index 4a1673a531d34..27a674e5bb7e8 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -1,11 +1,14 @@ -error[E0621]: explicit lifetime required in the type of `self` +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 { - | ----- consider changing the type of `self` to `&'a Foo` + | ------- ---- + | | + | this parameter and the return type are declared + with different lifetimes... 17 | 18 | x - | ^ lifetime `'a` required + | ^ ...but data flows from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 973c5ed72f875..8f957d1b009d0 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -1,11 +1,14 @@ -error[E0621]: explicit lifetime required in the type of `self` +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 { - | ----- consider changing the type of `self` to `&'a Foo` + | ----- ------- + | | + | this parameter and the return type are declared + with different lifetimes... 17 | 18 | if true { x } else { self } - | ^^^^ lifetime `'a` required + | ^^^^ ...but data flows from `self` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index c6b1280ca95aa..1ea2a4ff8ad4d 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -1,11 +1,11 @@ -error[E0621]: explicit lifetime required in the type of `self` +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... + | this parameter and the return type are declared + with different lifetimes... 17 | x | ^ ...but data from `x` is returned here diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index 9b15de1b1738f..316b76c64607b 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -4,8 +4,8 @@ error[E0623]: lifetime mismatch 16 | fn foo<'a>(&self, x: &Foo) -> &Foo { | ---- ---- | | - | this parameter and the return type are - declared with different lifetimes... + | this parameter and the return type are declared + with different lifetimes... 17 | if true { x } else { self } | ^ ...but data from `x` is returned here From bbf82be0766ead2a5e989a9c5bbb507841ebaef4 Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Tue, 12 Sep 2017 00:16:54 +0530 Subject: [PATCH 19/29] tidy fix --- src/librustc/infer/error_reporting/different_lifetimes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index e9866545f976a..aca6db1f9a002 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -110,7 +110,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }; (ty_sup.span, ty_sub.span, main_label_1, span_label_1) } - + (Some(ret_span), _) => { (ty_sub.span, ret_span, From d7bb575b063d10d3dcc4de5facb7453c419d3086 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 12 Sep 2017 10:53:00 -0400 Subject: [PATCH 20/29] use present tense consistently and update references --- src/librustc/infer/error_reporting/different_lifetimes.rs | 4 ++-- .../ex1-return-one-existing-name-if-else-using-impl.stderr | 2 +- .../ex1-return-one-existing-name-return-type-is-anon.stderr | 2 +- .../ex1-return-one-existing-name-self-is-anon.stderr | 2 +- .../ex3-both-anon-regions-both-are-structs-3.stderr | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index aca6db1f9a002..5ae5568ff7114 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -98,12 +98,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { (None, None) => { let (main_label_1, span_label_1) = if ty_sup == ty_sub { - (format!("this type was declared with multiple lifetimes..."), + (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 was declared with different lifetimes..."), + (format!("these two types are declared with different lifetimes..."), format!("...but data{} flows{} here", span_label_var1, span_label_var2)) diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr index f383a4dcf673e..311433b828c3e 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr @@ -8,7 +8,7 @@ error[E0623]: lifetime mismatch with different lifetimes... 20 | 21 | if x > y { x } else { y } - | ^ ...but data flows `x` is returned here + | ^ ...but data from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index 27a674e5bb7e8..a187ed3160b2e 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -8,7 +8,7 @@ error[E0623]: lifetime mismatch with different lifetimes... 17 | 18 | x - | ^ ...but data flows from `x` is returned here + | ^ ...but data from `x` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 8f957d1b009d0..67574f422a322 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -8,7 +8,7 @@ error[E0623]: lifetime mismatch with different lifetimes... 17 | 18 | if true { x } else { self } - | ^^^^ ...but data flows from `self` is returned here + | ^^^^ ...but data from `self` is returned here error: aborting due to previous error diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr index 1b5ac7c7b57ee..73460277de44c 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr @@ -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 From 9e4649ebf80679090786074c020d3d2e2c0e8a84 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 12 Sep 2017 17:21:53 -0400 Subject: [PATCH 21/29] remove random newlines from error messages, fix compile-fail test That kind of formatting seems like the job of other code. --- src/librustc/infer/error_reporting/different_lifetimes.rs | 8 ++++---- src/test/compile-fail/object-lifetime-default-mybox.rs | 2 +- ...ex1-return-one-existing-name-if-else-using-impl.stderr | 3 +-- ...x1-return-one-existing-name-return-type-is-anon.stderr | 3 +-- .../ex1-return-one-existing-name-self-is-anon.stderr | 3 +-- .../ex3-both-anon-regions-return-type-is-anon.stderr | 3 +-- .../ex3-both-anon-regions-self-is-anon.stderr | 3 +-- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/librustc/infer/error_reporting/different_lifetimes.rs b/src/librustc/infer/error_reporting/different_lifetimes.rs index 5ae5568ff7114..ee30db2625519 100644 --- a/src/librustc/infer/error_reporting/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/different_lifetimes.rs @@ -114,15 +114,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { (Some(ret_span), _) => { (ty_sub.span, ret_span, - format!("this parameter and the return type are declared - with different lifetimes...",), + 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!("this parameter and the return type are declared \ + with different lifetimes...",), format!("...but data{} is returned here", span_label_var1)) } }; diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs index 014b0c1e80e71..54657e76e9702 100644 --- a/src/test/compile-fail/object-lifetime-default-mybox.rs +++ b/src/test/compile-fail/object-lifetime-default-mybox.rs @@ -34,7 +34,7 @@ fn load1<'a,'b>(a: &'a MyBox, b: &'b MyBox) -> &'b MyBox { - a //~ ERROR E0312 + a //~ ERROR lifetime mismatch } fn load2<'a>(ss: &MyBox) -> MyBox { diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr index 311433b828c3e..cb9a1edf1ddf9 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr @@ -4,8 +4,7 @@ error[E0623]: lifetime mismatch 19 | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 { | ---- ------- | | - | this parameter and the return type are declared - with different lifetimes... + | this parameter and the return type are declared with different lifetimes... 20 | 21 | if x > y { x } else { y } | ^ ...but data from `x` is returned here diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index a187ed3160b2e..8af6acc62c436 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -4,8 +4,7 @@ error[E0623]: lifetime mismatch 16 | fn foo<'a>(&self, x: &'a i32) -> &i32 { | ------- ---- | | - | this parameter and the return type are declared - with different lifetimes... + | this parameter and the return type are declared with different lifetimes... 17 | 18 | x | ^ ...but data from `x` is returned here diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 67574f422a322..c09de0c33af7a 100644 --- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -4,8 +4,7 @@ error[E0623]: lifetime mismatch 16 | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | ----- ------- | | - | this parameter and the return type are declared - with different lifetimes... + | this parameter and the return type are declared with different lifetimes... 17 | 18 | if true { x } else { self } | ^^^^ ...but data from `self` is returned here diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index 1ea2a4ff8ad4d..1409b2161330b 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -4,8 +4,7 @@ error[E0623]: lifetime mismatch 16 | fn foo<'a>(&self, x: &i32) -> &i32 { | ---- ---- | | - | this parameter and the return type are declared - with different lifetimes... + | this parameter and the return type are declared with different lifetimes... 17 | x | ^ ...but data from `x` is returned here diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index 316b76c64607b..cae45023e26b2 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -4,8 +4,7 @@ error[E0623]: lifetime mismatch 16 | fn foo<'a>(&self, x: &Foo) -> &Foo { | ---- ---- | | - | this parameter and the return type are declared - with different lifetimes... + | this parameter and the return type are declared with different lifetimes... 17 | if true { x } else { self } | ^ ...but data from `x` is returned here From 4bbb58d429a56652acfd186295d05de7d84ee74e Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Sun, 24 Sep 2017 03:24:49 +0530 Subject: [PATCH 22/29] remove error code description --- src/librustc/diagnostics.rs | 69 +------------------------------------ 1 file changed, 1 insertion(+), 68 deletions(-) diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 76fba1583f3bc..26f56ffacae7f 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -1351,74 +1351,6 @@ struct Foo { ``` "##, -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 From 5c59bbadb3bebdbeb85556e4974f6b2e640d22de Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Sun, 24 Sep 2017 19:46:29 +0530 Subject: [PATCH 23/29] minor fixes --- src/librustc/infer/error_reporting/named_anon_conflict.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc/infer/error_reporting/named_anon_conflict.rs b/src/librustc/infer/error_reporting/named_anon_conflict.rs index 7027c868e6efe..80fb4ce8e0392 100644 --- a/src/librustc/infer/error_reporting/named_anon_conflict.rs +++ b/src/librustc/infer/error_reporting/named_anon_conflict.rs @@ -78,8 +78,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { return false; } - if let Some(anon_ty) = self.find_anon_type(anon, &br) { - let (_, fndecl) = anon_ty; + 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; From 73543d53cd01899df38ce71b883ed820c5822fba Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 26 Sep 2017 11:56:44 -0400 Subject: [PATCH 24/29] fix test reference --- .../ex3-both-anon-regions-both-are-structs-4.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr index 689a1ac292b33..fb524ae62c57a 100644 --- a/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr +++ b/src/test/ui/lifetime-errors/ex3-both-anon-regions-both-are-structs-4.stderr @@ -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 From b53b853129e4a05994e7029e2c45d74141a13961 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 31 Aug 2017 09:17:50 -0500 Subject: [PATCH 25/29] bootstrap: use shasum(1) on NetBSD build hosts NetBSD doesn't ship with sha256sum. The openssl build will probably try to use perl anyway, so using perl's shasum is reasonable. --- src/bootstrap/native.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 99077d03dbe03..6e479fe1cb614 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -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 From 90aa66bfc2e90de39e10ad3ed6d08b534f1efd02 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Thu, 31 Aug 2017 09:22:39 -0500 Subject: [PATCH 26/29] bootstrap: use tar -z on extract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some tar(1) programs—such as NetBSD's—do not automatically decompress. --- src/bootstrap/native.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 6e479fe1cb614..9b8857b5749de 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -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")); From cde47cef0f102933abf0a9143ae916864feb7b6b Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Wed, 27 Sep 2017 15:11:22 -0300 Subject: [PATCH 27/29] Remove DepNodeIndex::new is already impl for Idx --- src/librustc_incremental/persist/data.rs | 8 -------- src/librustc_incremental/persist/save.rs | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/librustc_incremental/persist/data.rs b/src/librustc_incremental/persist/data.rs index 06acfb5d77807..9050702e3ca71 100644 --- a/src/librustc_incremental/persist/data.rs +++ b/src/librustc_incremental/persist/data.rs @@ -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 { diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 83a618211dad3..fd699229f1b73 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -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}; From 20fc2153239ef0dd2eeb23a8ee30d0c9843000b3 Mon Sep 17 00:00:00 2001 From: Havvy Date: Thu, 28 Sep 2017 01:30:25 -0700 Subject: [PATCH 28/29] Normalize spaces in lang attributes. --- src/libcore/marker.rs | 2 +- src/libcore/ops/unsize.rs | 2 +- src/libcore/ptr.rs | 2 +- src/rtstartup/rsbegin.rs | 2 +- src/rtstartup/rsend.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index e8fd729b638be..f56a9a4033298 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -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 { // Empty. } diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs index 58da290cfb694..cd896859b16bc 100644 --- a/src/libcore/ops/unsize.rs +++ b/src/libcore/ops/unsize.rs @@ -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 { // Empty. } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 4041a3760e5ca..34d310446536d 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -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(to_drop: *mut T) { // Code here does not matter - this is replaced by the diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs index 335817fddbbe2..8733c7436d5bd 100644 --- a/src/rtstartup/rsbegin.rs +++ b/src/rtstartup/rsbegin.rs @@ -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(to_drop: *mut T) { diff --git a/src/rtstartup/rsend.rs b/src/rtstartup/rsend.rs index 9229b4e31289f..a6aed3540ddbb 100644 --- a/src/rtstartup/rsend.rs +++ b/src/rtstartup/rsend.rs @@ -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(to_drop: *mut T) { From 3457a22d9151806d2af401a94076cb55d88ac8c8 Mon Sep 17 00:00:00 2001 From: Alexander von Gluck IV Date: Tue, 5 Sep 2017 13:08:02 -0500 Subject: [PATCH 29/29] ci: Fix building disabled containers * Change the context into the disabled directory. Now you can test containers which are disabled. --- src/ci/docker/disabled/aarch64-gnu/Dockerfile | 2 +- src/ci/docker/disabled/wasm32-exp/Dockerfile | 2 +- src/ci/docker/run.sh | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/ci/docker/disabled/aarch64-gnu/Dockerfile b/src/ci/docker/disabled/aarch64-gnu/Dockerfile index 9a0e45312235e..fedb4094c8aaa 100644 --- a/src/ci/docker/disabled/aarch64-gnu/Dockerfile +++ b/src/ci/docker/disabled/aarch64-gnu/Dockerfile @@ -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 && \ diff --git a/src/ci/docker/disabled/wasm32-exp/Dockerfile b/src/ci/docker/disabled/wasm32-exp/Dockerfile index 6323369421bb4..8653b0e8b465e 100644 --- a/src/ci/docker/disabled/wasm32-exp/Dockerfile +++ b/src/ci/docker/disabled/wasm32-exp/Dockerfile @@ -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 diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 5eba81ff60a22..e4f63149278b1 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -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