diff --git a/Cargo.lock b/Cargo.lock index 69d929e913a9a..2191267893c9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1587,7 +1587,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "polonius-engine" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1966,7 +1966,7 @@ dependencies = [ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_apfloat 0.0.0", @@ -2352,7 +2352,6 @@ dependencies = [ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_data_structures 0.0.0", - "rustc_mir 0.0.0", "rustc_target 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", @@ -2406,7 +2405,7 @@ dependencies = [ "graphviz 0.0.0", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "polonius-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", "rustc_apfloat 0.0.0", "rustc_data_structures 0.0.0", @@ -3427,7 +3426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201" +"checksum polonius-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "494cc28002fae8ce2604c31c5cc1e73009318a0f6d2bb539a018dc22420a2dd0" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6" "checksum pretty_env_logger 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8d1e63042e889b85228620629b51c011d380eed2c7e0015f8a644def280c28" diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b6bb11d07ef04..2e792b6053ea3 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -18,7 +18,7 @@ use std::borrow::Cow; use std::env; -use std::fs::{self, File}; +use std::fs; use std::io::BufReader; use std::io::prelude::*; use std::path::{Path, PathBuf}; @@ -707,7 +707,7 @@ impl Step for CodegenBackend { } let stamp = codegen_backend_stamp(builder, compiler, target, backend); let codegen_backend = codegen_backend.to_str().unwrap(); - t!(t!(File::create(&stamp)).write_all(codegen_backend.as_bytes())); + t!(fs::write(&stamp, &codegen_backend)); } } @@ -796,8 +796,7 @@ fn copy_codegen_backends_to_sysroot(builder: &Builder, for backend in builder.config.rust_codegen_backends.iter() { let stamp = codegen_backend_stamp(builder, compiler, target, *backend); - let mut dylib = String::new(); - t!(t!(File::open(&stamp)).read_to_string(&mut dylib)); + let dylib = t!(fs::read_to_string(&stamp)); let file = Path::new(&dylib); let filename = file.file_name().unwrap().to_str().unwrap(); // change `librustc_codegen_llvm-xxxxxx.so` to `librustc_codegen_llvm-llvm.so` @@ -1137,10 +1136,7 @@ pub fn run_cargo(builder: &Builder, // contents (the list of files to copy) is different or if any dep's mtime // is newer then we rewrite the stamp file. deps.sort(); - let mut stamp_contents = Vec::new(); - if let Ok(mut f) = File::open(stamp) { - t!(f.read_to_end(&mut stamp_contents)); - } + let stamp_contents = fs::read(stamp); let stamp_mtime = mtime(&stamp); let mut new_contents = Vec::new(); let mut max = None; @@ -1156,7 +1152,10 @@ pub fn run_cargo(builder: &Builder, } let max = max.unwrap(); let max_path = max_path.unwrap(); - if stamp_contents == new_contents && max <= stamp_mtime { + let contents_equal = stamp_contents + .map(|contents| contents == new_contents) + .unwrap_or_default(); + if contents_equal && max <= stamp_mtime { builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}", stamp, max, stamp_mtime)); return deps @@ -1166,7 +1165,7 @@ pub fn run_cargo(builder: &Builder, } else { builder.verbose(&format!("updating {:?} as deps changed", stamp)); } - t!(t!(File::create(stamp)).write_all(&new_contents)); + t!(fs::write(&stamp, &new_contents)); deps } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 8fc2d5787cb4b..1dafbe148afda 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -15,8 +15,7 @@ use std::collections::{HashMap, HashSet}; use std::env; -use std::fs::{self, File}; -use std::io::prelude::*; +use std::fs; use std::path::{Path, PathBuf}; use std::process; use std::cmp; @@ -416,9 +415,7 @@ impl Config { config.run_host_only = !(flags.host.is_empty() && !flags.target.is_empty()); let toml = file.map(|file| { - let mut f = t!(File::open(&file)); - let mut contents = String::new(); - t!(f.read_to_string(&mut contents)); + let contents = t!(fs::read_to_string(&file)); match toml::from_str(&contents) { Ok(table) => table, Err(err) => { diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index cd8d5642b2570..68aed59074638 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -19,8 +19,8 @@ //! pieces of `rustup.rs`! use std::env; -use std::fs::{self, File}; -use std::io::{Read, Write}; +use std::fs; +use std::io::Write; use std::path::{PathBuf, Path}; use std::process::{Command, Stdio}; @@ -1510,8 +1510,7 @@ impl Step for Extended { } let xform = |p: &Path| { - let mut contents = String::new(); - t!(t!(File::open(p)).read_to_string(&mut contents)); + let mut contents = t!(fs::read_to_string(p)); if rls_installer.is_none() { contents = filter(&contents, "rls"); } @@ -1522,8 +1521,8 @@ impl Step for Extended { contents = filter(&contents, "rustfmt"); } let ret = tmp.join(p.file_name().unwrap()); - t!(t!(File::create(&ret)).write_all(contents.as_bytes())); - return ret + t!(fs::write(&ret, &contents)); + ret }; if target.contains("apple-darwin") { @@ -1868,8 +1867,7 @@ impl Step for HashSign { let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| { panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n") }); - let mut pass = String::new(); - t!(t!(File::open(&file)).read_to_string(&mut pass)); + let pass = t!(fs::read_to_string(&file)); let today = output(Command::new("date").arg("+%Y-%m-%d")); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 201129b92df05..020bd7093e361 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -18,8 +18,7 @@ //! `rustdoc`. use std::collections::HashSet; -use std::fs::{self, File}; -use std::io::prelude::*; +use std::fs; use std::io; use std::path::{PathBuf, Path}; @@ -379,12 +378,11 @@ impl Step for Standalone { let version_info = out.join("version_info.html"); if !builder.config.dry_run && !up_to_date(&version_input, &version_info) { - let mut info = String::new(); - t!(t!(File::open(&version_input)).read_to_string(&mut info)); - let info = info.replace("VERSION", &builder.rust_release()) - .replace("SHORT_HASH", builder.rust_info.sha_short().unwrap_or("")) - .replace("STAMP", builder.rust_info.sha().unwrap_or("")); - t!(t!(File::create(&version_info)).write_all(info.as_bytes())); + let info = t!(fs::read_to_string(&version_input)) + .replace("VERSION", &builder.rust_release()) + .replace("SHORT_HASH", builder.rust_info.sha_short().unwrap_or("")) + .replace("STAMP", builder.rust_info.sha().unwrap_or("")); + t!(fs::write(&version_info, &info)); } for file in t!(fs::read_dir(builder.src.join("src/doc"))) { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 2832f5bebddd6..a62830da4bb61 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1067,9 +1067,8 @@ impl Build { /// Returns the `a.b.c` version that the given package is at. fn release_num(&self, package: &str) -> String { - let mut toml = String::new(); let toml_file_name = self.src.join(&format!("src/tools/{}/Cargo.toml", package)); - t!(t!(File::open(toml_file_name)).read_to_string(&mut toml)); + let toml = t!(fs::read_to_string(&toml_file_name)); for line in toml.lines() { let prefix = "version = \""; let suffix = "\""; @@ -1151,8 +1150,7 @@ impl Build { } let mut paths = Vec::new(); - let mut contents = Vec::new(); - t!(t!(File::open(stamp)).read_to_end(&mut contents)); + let contents = t!(fs::read(stamp)); // This is the method we use for extracting paths from the stamp file passed to us. See // run_cargo for more information (in compile.rs). for part in contents.split(|b| *b == 0) { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 448967ef0c2e1..150b6bea18064 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -21,7 +21,6 @@ use std::env; use std::ffi::OsString; use std::fs::{self, File}; -use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::process::Command; @@ -75,8 +74,7 @@ impl Step for Llvm { } let rebuild_trigger = builder.src.join("src/rustllvm/llvm-rebuild-trigger"); - let mut rebuild_trigger_contents = String::new(); - t!(t!(File::open(&rebuild_trigger)).read_to_string(&mut rebuild_trigger_contents)); + let rebuild_trigger_contents = t!(fs::read_to_string(&rebuild_trigger)); let (out_dir, llvm_config_ret_dir) = if emscripten { let dir = builder.emscripten_llvm_out(target); @@ -93,8 +91,7 @@ impl Step for Llvm { let build_llvm_config = llvm_config_ret_dir .join(exe("llvm-config", &*builder.config.build)); if done_stamp.exists() { - let mut done_contents = String::new(); - t!(t!(File::open(&done_stamp)).read_to_string(&mut done_contents)); + let done_contents = t!(fs::read_to_string(&done_stamp)); // If LLVM was already built previously and contents of the rebuild-trigger file // didn't change from the previous build, then no action is required. @@ -261,7 +258,7 @@ impl Step for Llvm { cfg.build(); - t!(t!(File::create(&done_stamp)).write_all(rebuild_trigger_contents.as_bytes())); + t!(fs::write(&done_stamp, &rebuild_trigger_contents)); build_llvm_config } diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 15d3bccba09cc..7a9e6d4fd387b 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -21,8 +21,7 @@ use std::collections::HashMap; use std::env; use std::ffi::{OsString, OsStr}; -use std::fs::{self, File}; -use std::io::Read; +use std::fs; use std::path::PathBuf; use std::process::Command; @@ -235,9 +234,7 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake } if build.config.channel == "stable" { - let mut stage0 = String::new(); - t!(t!(File::open(build.src.join("src/stage0.txt"))) - .read_to_string(&mut stage0)); + let stage0 = t!(fs::read_to_string(build.src.join("src/stage0.txt"))); if stage0.contains("\ndev:") { panic!("bootstrapping from a dev compiler in a stable release, but \ should only be bootstrapping from a released compiler!"); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index da827356800e9..4ece3435e929a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -16,8 +16,7 @@ use std::env; use std::ffi::OsString; use std::fmt; -use std::fs::{self, File}; -use std::io::Read; +use std::fs; use std::iter; use std::path::{Path, PathBuf}; use std::process::Command; @@ -1427,10 +1426,8 @@ impl Step for ErrorIndex { } fn markdown_test(builder: &Builder, compiler: Compiler, markdown: &Path) -> bool { - match File::open(markdown) { - Ok(mut file) => { - let mut contents = String::new(); - t!(file.read_to_string(&mut contents)); + match fs::read_to_string(markdown) { + Ok(contents) => { if !contents.contains("```") { return true; } diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y index a7da69f65faf2..8ea1cb26dc0c7 100644 --- a/src/grammar/parser-lalr.y +++ b/src/grammar/parser-lalr.y @@ -741,14 +741,14 @@ fn_anon_params ; fn_params_with_self -: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfValue", 3, $2, $4, $5); } +: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfLower", 3, $2, $4, $5); } | '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); } | '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); } | '(' maybe_params ')' { $$ = mk_node("SelfStatic", 1, $2); } ; fn_anon_params_with_self -: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfValue", 3, $2, $4, $5); } +: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfLower", 3, $2, $4, $5); } | '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); } | '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); } | '(' maybe_anon_params ')' { $$ = mk_node("SelfStatic", 1, $2); } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 3ca6de191de2d..c0a947e701108 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -1187,8 +1187,9 @@ impl, U: ?Sized> DispatchFromDyn> for Weak {} impl Weak { /// Constructs a new `Weak`, without allocating any memory. - /// Calling [`upgrade`][Weak::upgrade] on the return value always gives [`None`]. + /// Calling [`upgrade`] on the return value always gives [`None`]. /// + /// [`upgrade`]: #method.upgrade /// [`None`]: ../../std/option/enum.Option.html /// /// # Examples @@ -1260,6 +1261,52 @@ impl Weak { Some(unsafe { self.ptr.as_ref() }) } } + + /// Returns true if the two `Weak`s point to the same value (not just values + /// that compare as equal). + /// + /// # Notes + /// + /// Since this compares pointers it means that `Weak::new()` will equal each + /// other, even though they don't point to any value. + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::rc::{Rc, Weak}; + /// + /// let first_rc = Rc::new(5); + /// let first = Rc::downgrade(&first_rc); + /// let second = Rc::downgrade(&first_rc); + /// + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Rc::new(5); + /// let third = Rc::downgrade(&third_rc); + /// + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + /// + /// Comparing `Weak::new`. + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::rc::{Rc, Weak}; + /// + /// let first = Weak::new(); + /// let second = Weak::new(); + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Rc::new(()); + /// let third = Rc::downgrade(&third_rc); + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + #[inline] + #[unstable(feature = "weak_ptr_eq", issue = "55981")] + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + this.ptr.as_ptr() == other.ptr.as_ptr() + } } #[stable(feature = "rc_weak", since = "1.4.0")] diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs index 662f8ae614fcb..acc1f9b306e7d 100644 --- a/src/liballoc/string.rs +++ b/src/liballoc/string.rs @@ -577,7 +577,7 @@ impl String { return Cow::Borrowed(""); }; - const REPLACEMENT: &'static str = "\u{FFFD}"; + const REPLACEMENT: &str = "\u{FFFD}"; let mut res = String::with_capacity(v.len()); res.push_str(first_valid); diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 4f4031e3c4e32..0a397f79103db 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -1130,6 +1130,53 @@ impl Weak { Some(unsafe { self.ptr.as_ref() }) } } + + /// Returns true if the two `Weak`s point to the same value (not just values + /// that compare as equal). + /// + /// # Notes + /// + /// Since this compares pointers it means that `Weak::new()` will equal each + /// other, even though they don't point to any value. + /// + /// + /// # Examples + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::sync::{Arc, Weak}; + /// + /// let first_rc = Arc::new(5); + /// let first = Arc::downgrade(&first_rc); + /// let second = Arc::downgrade(&first_rc); + /// + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Arc::new(5); + /// let third = Arc::downgrade(&third_rc); + /// + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + /// + /// Comparing `Weak::new`. + /// + /// ``` + /// #![feature(weak_ptr_eq)] + /// use std::sync::{Arc, Weak}; + /// + /// let first = Weak::new(); + /// let second = Weak::new(); + /// assert!(Weak::ptr_eq(&first, &second)); + /// + /// let third_rc = Arc::new(()); + /// let third = Arc::downgrade(&third_rc); + /// assert!(!Weak::ptr_eq(&first, &third)); + /// ``` + #[inline] + #[unstable(feature = "weak_ptr_eq", issue = "55981")] + pub fn ptr_eq(this: &Self, other: &Self) -> bool { + this.ptr.as_ptr() == other.ptr.as_ptr() + } } #[stable(feature = "arc_weak", since = "1.4.0")] diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs index dbc28ef7cf6a9..2d4813718f41a 100644 --- a/src/libcore/convert.rs +++ b/src/libcore/convert.rs @@ -327,7 +327,8 @@ pub trait Into: Sized { /// An example usage for error handling: /// /// ``` -/// use std::io::{self, Read}; +/// use std::fs; +/// use std::io; /// use std::num; /// /// enum CliError { @@ -348,9 +349,7 @@ pub trait Into: Sized { /// } /// /// fn open_and_parse_file(file_name: &str) -> Result { -/// let mut file = std::fs::File::open("test")?; -/// let mut contents = String::new(); -/// file.read_to_string(&mut contents)?; +/// let mut contents = fs::read_to_string(&file_name)?; /// let num: i32 = contents.trim().parse()?; /// Ok(num) /// } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 75ec0d7d50be6..0c5256b981e5c 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1381,7 +1381,7 @@ impl<'a> Formatter<'a> { for part in formatted.parts { match *part { flt2dec::Part::Zero(mut nzeroes) => { - const ZEROES: &'static str = // 64 zeroes + const ZEROES: &str = // 64 zeroes "0000000000000000000000000000000000000000000000000000000000000000"; while nzeroes > ZEROES.len() { self.buf.write_str(ZEROES)?; diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 62e1f9fcb640c..de7ab8843daed 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -602,7 +602,9 @@ unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned } #[inline] - fn may_have_side_effect() -> bool { false } + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } } #[unstable(feature = "trusted_len", issue = "37572")] diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 8b1855800c2fd..5ba0e949483ae 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -238,6 +238,10 @@ macro_rules! debug_assert_ne { /// with converting downstream errors. /// /// The `?` operator was added to replace `try!` and should be used instead. +/// Furthermore, `try` is a reserved word in Rust 2018, so if you must use +/// it, you will need to use the [raw-identifier syntax][ris]: `r#try`. +/// +/// [ris]: https://doc.rust-lang.org/nightly/rust-by-example/compatibility/raw_identifiers.html /// /// `try!` matches the given [`Result`]. In case of the `Ok` variant, the /// expression has the value of the wrapped value. diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index d3a74ed2a6856..c56e91bbe4d2d 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2516,6 +2516,36 @@ pub fn eq(a: *const T, b: *const T) -> bool { a == b } +/// Hash the raw pointer address behind a reference, rather than the value +/// it points to. +/// +/// # Examples +/// +/// ``` +/// #![feature(ptr_hash)] +/// use std::collections::hash_map::DefaultHasher; +/// use std::hash::{Hash, Hasher}; +/// use std::ptr; +/// +/// let five = 5; +/// let five_ref = &five; +/// +/// let mut hasher = DefaultHasher::new(); +/// ptr::hash(five_ref, &mut hasher); +/// let actual = hasher.finish(); +/// +/// let mut hasher = DefaultHasher::new(); +/// (five_ref as *const i32).hash(&mut hasher); +/// let expected = hasher.finish(); +/// +/// assert_eq!(actual, expected); +/// ``` +#[unstable(feature = "ptr_hash", reason = "newly added", issue = "56286")] +pub fn hash(hashee: *const T, into: &mut S) { + use hash::Hash; + hashee.hash(into); +} + // Impls for function pointers macro_rules! fnptr_impls_safety_abi { ($FnTy: ty, $($Arg: ident),*) => { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 89efa120a6fab..6c953d1b9a0ac 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -536,10 +536,9 @@ fn next_code_point_reverse<'a, I>(bytes: &mut I) -> Option where I: DoubleEndedIterator, { // Decode UTF-8 - let w = match bytes.next_back() { - None => return None, - Some(&next_byte) if next_byte < 128 => return Some(next_byte as u32), - Some(&back_byte) => back_byte, + let w = match *bytes.next_back()? { + next_byte if next_byte < 128 => return Some(next_byte as u32), + back_byte => back_byte, }; // Multibyte case follows diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index 495483db5551c..19be1a07c5baa 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1249,6 +1249,23 @@ fn test_cloned() { assert_eq!(it.next_back(), None); } +#[test] +fn test_cloned_side_effects() { + let mut count = 0; + { + let iter = [1, 2, 3] + .iter() + .map(|x| { + count += 1; + x + }) + .cloned() + .zip(&[1]); + for _ in iter {} + } + assert_eq!(count, 2); +} + #[test] fn test_double_ended_map() { let xs = [1, 2, 3, 4, 5, 6]; diff --git a/src/libcore/unicode/printable.rs b/src/libcore/unicode/printable.rs index 519dd17bb9b3f..32e4b6b0fa512 100644 --- a/src/libcore/unicode/printable.rs +++ b/src/libcore/unicode/printable.rs @@ -80,7 +80,7 @@ pub(crate) fn is_printable(x: char) -> bool { } } -const SINGLETONS0U: &'static [(u8, u8)] = &[ +const SINGLETONS0U: &[(u8, u8)] = &[ (0x00, 1), (0x03, 5), (0x05, 6), @@ -122,7 +122,7 @@ const SINGLETONS0U: &'static [(u8, u8)] = &[ (0xfe, 3), (0xff, 9), ]; -const SINGLETONS0L: &'static [u8] = &[ +const SINGLETONS0L: &[u8] = &[ 0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90, 0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, @@ -162,7 +162,7 @@ const SINGLETONS0L: &'static [u8] = &[ 0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff, ]; -const SINGLETONS1U: &'static [(u8, u8)] = &[ +const SINGLETONS1U: &[(u8, u8)] = &[ (0x00, 6), (0x01, 1), (0x03, 1), @@ -197,7 +197,7 @@ const SINGLETONS1U: &'static [(u8, u8)] = &[ (0xf0, 4), (0xf9, 4), ]; -const SINGLETONS1L: &'static [u8] = &[ +const SINGLETONS1L: &[u8] = &[ 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36, @@ -219,7 +219,7 @@ const SINGLETONS1L: &'static [u8] = &[ 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x3f, 0x71, 0x72, 0x7b, ]; -const NORMAL0: &'static [u8] = &[ +const NORMAL0: &[u8] = &[ 0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, @@ -363,7 +363,7 @@ const NORMAL0: &'static [u8] = &[ 0x1b, 0x03, 0x0f, 0x0d, ]; -const NORMAL1: &'static [u8] = &[ +const NORMAL1: &[u8] = &[ 0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 3316735de663e..64cf7f4d30dfd 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -17,7 +17,7 @@ jobserver = "0.1" lazy_static = "1.0.0" scoped-tls = { version = "0.1.1", features = ["nightly"] } log = { version = "0.4", features = ["release_max_level_info", "std"] } -polonius-engine = "0.5.0" +polonius-engine = "0.6.0" rustc-rayon = "0.1.1" rustc-rayon-core = "0.1.1" rustc_apfloat = { path = "../librustc_apfloat" } diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 388bbc52c3b1a..a20d04972fd75 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -381,7 +381,7 @@ macro_rules! define_dep_nodes { #[allow(dead_code, non_upper_case_globals)] pub mod label_strs { $( - pub const $variant: &'static str = stringify!($variant); + pub const $variant: &str = stringify!($variant); )* } ); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index dc8baa112bb59..a485af0a5eef9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1201,7 +1201,7 @@ impl<'a> LoweringContext<'a> { None, P(hir::Path { def: self.expect_full_def(t.id), - segments: hir_vec![hir::PathSegment::from_ident(keywords::SelfType.ident())], + segments: hir_vec![hir::PathSegment::from_ident(keywords::SelfUpper.ident())], span: t.span, }), )), @@ -2425,7 +2425,7 @@ impl<'a> LoweringContext<'a> { // Don't expose `Self` (recovered "keyword used as ident" parse error). // `rustc::ty` expects `Self` to be only used for a trait's `Self`. // Instead, use gensym("Self") to create a distinct name that looks the same. - let ident = if param.ident.name == keywords::SelfType.name() { + let ident = if param.ident.name == keywords::SelfUpper.name() { param.ident.gensym() } else { param.ident @@ -2981,7 +2981,7 @@ impl<'a> LoweringContext<'a> { // Correctly resolve `self` imports if path.segments.len() > 1 - && path.segments.last().unwrap().ident.name == keywords::SelfValue.name() + && path.segments.last().unwrap().ident.name == keywords::SelfLower.name() { let _ = path.segments.pop(); if rename.is_none() { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index ef777abfbc41a..4ac07d78a2613 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -475,7 +475,7 @@ impl<'hir> Map<'hir> { pub fn ty_param_name(&self, id: NodeId) -> Name { match self.get(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfType.name(), + Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(), Node::GenericParam(param) => param.name.ident().name, _ => bug!("ty_param_name: {} not a type parameter", self.node_to_string(id)), } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 1674320165e65..85bf257df237f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -311,7 +311,7 @@ pub struct Path { impl Path { pub fn is_global(&self) -> bool { - !self.segments.is_empty() && self.segments[0].ident.name == keywords::CrateRoot.name() + !self.segments.is_empty() && self.segments[0].ident.name == keywords::PathRoot.name() } } diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 9a0ceddcf1b4a..484722f8c131b 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -65,7 +65,7 @@ pub trait PpAnn { pub struct NoAnn; impl PpAnn for NoAnn {} -pub const NO_ANN: &'static dyn PpAnn = &NoAnn; +pub const NO_ANN: &dyn PpAnn = &NoAnn; impl PpAnn for hir::Crate { fn try_fetch_item(&self, item: ast::NodeId) -> Option<&hir::Item> { @@ -1622,7 +1622,7 @@ impl<'a> State<'a> { if i > 0 { self.s.word("::")? } - if segment.ident.name != keywords::CrateRoot.name() && + if segment.ident.name != keywords::PathRoot.name() && segment.ident.name != keywords::DollarCrate.name() { self.print_ident(segment.ident)?; segment.with_generic_args(|generic_args| { @@ -1636,7 +1636,7 @@ impl<'a> State<'a> { } pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> { - if segment.ident.name != keywords::CrateRoot.name() && + if segment.ident.name != keywords::PathRoot.name() && segment.ident.name != keywords::DollarCrate.name() { self.print_ident(segment.ident)?; segment.with_generic_args(|generic_args| { @@ -1664,7 +1664,7 @@ impl<'a> State<'a> { if i > 0 { self.s.word("::")? } - if segment.ident.name != keywords::CrateRoot.name() && + if segment.ident.name != keywords::PathRoot.name() && segment.ident.name != keywords::DollarCrate.name() { self.print_ident(segment.ident)?; segment.with_generic_args(|generic_args| { diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index d98bb82aabad1..d5bf4f4cd3bd9 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -503,6 +503,7 @@ impl_stable_hash_for!(struct mir::ClosureOutlivesRequirement<'tcx> { impl_stable_hash_for!(enum mir::ConstraintCategory { Return, + Yield, UseAsConst, UseAsStatic, TypeAnnotation, diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index b629fb820b34d..b9ed0fcd4f38f 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -134,14 +134,10 @@ impl_stable_hash_for!(struct ::syntax::attr::Stability { const_stability }); -impl<'a> HashStable> -for ::syntax::edition::Edition { - fn hash_stable(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher) { - mem::discriminant(self).hash_stable(hcx, hasher); - } -} +impl_stable_hash_for!(enum ::syntax::edition::Edition { + Edition2015, + Edition2018, +}); impl<'a> HashStable> for ::syntax::attr::StabilityLevel { diff --git a/src/librustc/ich/mod.rs b/src/librustc/ich/mod.rs index 9751c560acd1e..fc2f1ee6ff892 100644 --- a/src/librustc/ich/mod.rs +++ b/src/librustc/ich/mod.rs @@ -24,15 +24,15 @@ mod impls_misc; mod impls_ty; mod impls_syntax; -pub const ATTR_DIRTY: &'static str = "rustc_dirty"; -pub const ATTR_CLEAN: &'static str = "rustc_clean"; -pub const ATTR_IF_THIS_CHANGED: &'static str = "rustc_if_this_changed"; -pub const ATTR_THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need"; -pub const ATTR_PARTITION_REUSED: &'static str = "rustc_partition_reused"; -pub const ATTR_PARTITION_CODEGENED: &'static str = "rustc_partition_codegened"; -pub const ATTR_EXPECTED_CGU_REUSE: &'static str = "rustc_expected_cgu_reuse"; +pub const ATTR_DIRTY: &str = "rustc_dirty"; +pub const ATTR_CLEAN: &str = "rustc_clean"; +pub const ATTR_IF_THIS_CHANGED: &str = "rustc_if_this_changed"; +pub const ATTR_THEN_THIS_WOULD_NEED: &str = "rustc_then_this_would_need"; +pub const ATTR_PARTITION_REUSED: &str = "rustc_partition_reused"; +pub const ATTR_PARTITION_CODEGENED: &str = "rustc_partition_codegened"; +pub const ATTR_EXPECTED_CGU_REUSE: &str = "rustc_expected_cgu_reuse"; -pub const IGNORED_ATTRIBUTES: &'static [&'static str] = &[ +pub const IGNORED_ATTRIBUTES: &[&str] = &[ "cfg", ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED, diff --git a/src/librustc/infer/lexical_region_resolve/graphviz.rs b/src/librustc/infer/lexical_region_resolve/graphviz.rs index a210d63f129e3..512e57d810aa4 100644 --- a/src/librustc/infer/lexical_region_resolve/graphviz.rs +++ b/src/librustc/infer/lexical_region_resolve/graphviz.rs @@ -31,9 +31,8 @@ use std::borrow::Cow; use std::collections::hash_map::Entry::Vacant; use std::collections::btree_map::BTreeMap; use std::env; -use std::fs::File; +use std::fs; use std::io; -use std::io::prelude::*; use std::sync::atomic::{AtomicBool, Ordering}; fn print_help_message() { @@ -268,5 +267,5 @@ fn dump_region_data_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, ' debug!("dump_region_data calling render"); let mut v = Vec::new(); dot::render(&g, &mut v).unwrap(); - File::create(path).and_then(|mut f| f.write_all(&v)) + fs::write(path, &v) } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 282b5d13e2c61..bb7a6a6ee7b72 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -166,6 +166,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) | hir::ItemKind::Static(..) + | hir::ItemKind::Existential(..) | hir::ItemKind::Const(..) => { intravisit::walk_item(self, &item); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 54a0192d2e8a5..b846a1c4930fb 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1575,7 +1575,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let sp = ident.span; let var = self.variable(hir_id, sp); // Ignore unused self. - if ident.name != keywords::SelfValue.name() { + if ident.name != keywords::SelfLower.name() { if !self.warn_about_unused(sp, hir_id, entry_ln, var) { if self.live_on_entry(entry_ln, var).is_none() { self.report_dead_assign(hir_id, sp, var, true); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 35d1a4dd2cb7c..3c2551f5cd436 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -592,10 +592,7 @@ impl<'tcx> ScopeTree { return Some(scope.item_local_id()); } - match self.opt_encl_scope(scope) { - None => return None, - Some(parent) => scope = parent, - } + scope = self.opt_encl_scope(scope)?; } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 368f83eb61127..0319b33a899b3 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2894,6 +2894,7 @@ pub struct ClosureOutlivesRequirement<'tcx> { #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub enum ConstraintCategory { Return, + Yield, UseAsConst, UseAsStatic, TypeAnnotation, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 480d4a8e48f0e..e8b280fb3d802 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -780,43 +780,42 @@ macro_rules! options { } pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool; - pub const $stat: &'static [(&'static str, $setter_name, - Option<&'static str>, &'static str)] = + pub const $stat: &[(&str, $setter_name, Option<&str>, &str)] = &[ $( (stringify!($opt), $mod_set::$opt, $mod_desc::$parse, $desc) ),* ]; #[allow(non_upper_case_globals, dead_code)] mod $mod_desc { - pub const parse_bool: Option<&'static str> = None; - pub const parse_opt_bool: Option<&'static str> = + pub const parse_bool: Option<&str> = None; + pub const parse_opt_bool: Option<&str> = Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`"); - pub const parse_string: Option<&'static str> = Some("a string"); - pub const parse_string_push: Option<&'static str> = Some("a string"); - pub const parse_pathbuf_push: Option<&'static str> = Some("a path"); - pub const parse_opt_string: Option<&'static str> = Some("a string"); - pub const parse_opt_pathbuf: Option<&'static str> = Some("a path"); - pub const parse_list: Option<&'static str> = Some("a space-separated list of strings"); - pub const parse_opt_list: Option<&'static str> = Some("a space-separated list of strings"); - pub const parse_uint: Option<&'static str> = Some("a number"); - pub const parse_passes: Option<&'static str> = + pub const parse_string: Option<&str> = Some("a string"); + pub const parse_string_push: Option<&str> = Some("a string"); + pub const parse_pathbuf_push: Option<&str> = Some("a path"); + pub const parse_opt_string: Option<&str> = Some("a string"); + pub const parse_opt_pathbuf: Option<&str> = Some("a path"); + pub const parse_list: Option<&str> = Some("a space-separated list of strings"); + pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings"); + pub const parse_uint: Option<&str> = Some("a number"); + pub const parse_passes: Option<&str> = Some("a space-separated list of passes, or `all`"); - pub const parse_opt_uint: Option<&'static str> = + pub const parse_opt_uint: Option<&str> = Some("a number"); - pub const parse_panic_strategy: Option<&'static str> = + pub const parse_panic_strategy: Option<&str> = Some("either `unwind` or `abort`"); - pub const parse_relro_level: Option<&'static str> = + pub const parse_relro_level: Option<&str> = Some("one of: `full`, `partial`, or `off`"); - pub const parse_sanitizer: Option<&'static str> = + pub const parse_sanitizer: Option<&str> = Some("one of: `address`, `leak`, `memory` or `thread`"); - pub const parse_linker_flavor: Option<&'static str> = + pub const parse_linker_flavor: Option<&str> = Some(::rustc_target::spec::LinkerFlavor::one_of()); - pub const parse_optimization_fuel: Option<&'static str> = + pub const parse_optimization_fuel: Option<&str> = Some("crate=integer"); - pub const parse_unpretty: Option<&'static str> = + pub const parse_unpretty: Option<&str> = Some("`string` or `string=string`"); - pub const parse_lto: Option<&'static str> = + pub const parse_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \ `fat`, or omitted"); - pub const parse_cross_lang_lto: Option<&'static str> = + pub const parse_cross_lang_lto: Option<&str> = Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \ or the path to the linker plugin"); } diff --git a/src/librustc/session/filesearch.rs b/src/librustc/session/filesearch.rs index f410c270bcef9..e686a1d1275b6 100644 --- a/src/librustc/session/filesearch.rs +++ b/src/librustc/session/filesearch.rs @@ -179,12 +179,12 @@ fn find_libdir(sysroot: &Path) -> Cow<'static, str> { // "lib" (i.e. non-default), this value is used (see issue #16552). #[cfg(target_pointer_width = "64")] - const PRIMARY_LIB_DIR: &'static str = "lib64"; + const PRIMARY_LIB_DIR: &str = "lib64"; #[cfg(target_pointer_width = "32")] - const PRIMARY_LIB_DIR: &'static str = "lib32"; + const PRIMARY_LIB_DIR: &str = "lib32"; - const SECONDARY_LIB_DIR: &'static str = "lib"; + const SECONDARY_LIB_DIR: &str = "lib"; match option_env!("CFG_LIBDIR_RELATIVE") { Some(libdir) if libdir != "lib" => libdir.into(), @@ -198,4 +198,4 @@ fn find_libdir(sysroot: &Path) -> Cow<'static, str> { // The name of rustc's own place to organize libraries. // Used to be "rustc", now the default is "rustlib" -const RUST_LIB_DIR: &'static str = "rustlib"; +const RUST_LIB_DIR: &str = "rustlib"; diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs index 768d4f1e5fb65..6b0a8a0af2b9d 100644 --- a/src/librustc/session/search_paths.rs +++ b/src/librustc/session/search_paths.rs @@ -67,14 +67,13 @@ impl<'a> Iterator for Iter<'a> { fn next(&mut self) -> Option<(&'a Path, PathKind)> { loop { - match self.iter.next() { - Some(&(kind, ref p)) if self.kind == PathKind::All || - kind == PathKind::All || - kind == self.kind => { + match *self.iter.next()? { + (kind, ref p) if self.kind == PathKind::All || + kind == PathKind::All || + kind == self.kind => { return Some((p, kind)) } - Some(..) => {} - None => return None, + _ => {} } } } diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 19ef3171b13fc..cb17246b15f11 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -85,6 +85,8 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, source_substs: &'tcx Substs<'tcx>, target_node: specialization_graph::Node) -> &'tcx Substs<'tcx> { + debug!("translate_substs({:?}, {:?}, {:?}, {:?})", + param_env, source_impl, source_substs, target_node); let source_trait_ref = infcx.tcx .impl_trait_ref(source_impl) .unwrap() @@ -119,10 +121,13 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, /// whichever applies. pub fn find_associated_item<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, item: &ty::AssociatedItem, substs: &'tcx Substs<'tcx>, impl_data: &super::VtableImplData<'tcx, ()>, ) -> (DefId, &'tcx Substs<'tcx>) { + debug!("find_associated_item({:?}, {:?}, {:?}, {:?})", + param_env, item, substs, impl_data); assert!(!substs.needs_infer()); let trait_def_id = tcx.trait_id_of_impl(impl_data.impl_def_id).unwrap(); @@ -132,7 +137,7 @@ pub fn find_associated_item<'a, 'tcx>( match ancestors.defs(tcx, item.ident, item.kind, trait_def_id).next() { Some(node_item) => { let substs = tcx.infer_ctxt().enter(|infcx| { - let param_env = ty::ParamEnv::reveal_all(); + let param_env = param_env.with_reveal_all(); let substs = substs.rebase_onto(tcx, trait_def_id, impl_data.substs); let substs = translate_substs(&infcx, param_env, impl_data.impl_def_id, substs, node_item.node); @@ -219,12 +224,17 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, source_trait_ref: ty::TraitRef<'tcx>, target_impl: DefId) -> Result<&'tcx Substs<'tcx>, ()> { + debug!("fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)", + param_env, source_trait_ref, target_impl); + let selcx = &mut SelectionContext::new(&infcx); let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl); let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx, param_env, target_impl, target_substs); + debug!("fulfill_implication: target_trait_ref={:?}, obligations={:?}", + target_trait_ref, obligations); // do the impls unify? If not, no specialization. match infcx.at(&ObligationCause::dummy(), param_env) diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 36538ac0889de..36e93cc774089 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -33,8 +33,8 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> { if ty::tls::with(|tcx| tcx.sess.verbose()) { write!( f, - "Obligation(predicate={:?},cause={:?},depth={})", - self.predicate, self.cause, self.recursion_depth + "Obligation(predicate={:?},cause={:?},param_env={:?},depth={})", + self.predicate, self.cause, self.param_env, self.recursion_depth ) } else { write!( diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 42a4de1682c39..f041192413107 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1493,12 +1493,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { BorrowckMode::Ast => match self.sess.edition() { Edition::Edition2015 => BorrowckMode::Ast, Edition::Edition2018 => BorrowckMode::Migrate, - - // For now, future editions mean Migrate. (But it - // would make a lot of sense for it to be changed to - // `BorrowckMode::Mir`, depending on how we plan to - // time the forcing of full migration to NLL.) - _ => BorrowckMode::Migrate, }, } } @@ -2710,7 +2704,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { #[inline] pub fn mk_self_type(self) -> Ty<'tcx> { - self.mk_ty_param(0, keywords::SelfType.name().as_interned_str()) + self.mk_ty_param(0, keywords::SelfUpper.name().as_interned_str()) } pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> Kind<'tcx> { diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 411a6e7e6238e..a24920da158e2 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -347,9 +347,10 @@ fn resolve_associated_item<'a, 'tcx>( ) -> Option> { let def_id = trait_item.def_id; debug!("resolve_associated_item(trait_item={:?}, \ + param_env={:?}, \ trait_id={:?}, \ rcvr_substs={:?})", - def_id, trait_id, rcvr_substs); + def_id, param_env, trait_id, rcvr_substs); let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs); let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref))); @@ -359,7 +360,7 @@ fn resolve_associated_item<'a, 'tcx>( match vtbl { traits::VtableImpl(impl_data) => { let (def_id, substs) = traits::find_associated_item( - tcx, trait_item, rcvr_substs, &impl_data); + tcx, param_env, trait_item, rcvr_substs, &impl_data); let substs = tcx.erase_regions(&substs); Some(ty::Instance::new(def_id, substs)) } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 1416cb17feaed..1a52717ef0588 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1020,7 +1020,7 @@ impl<'a, 'gcx, 'tcx> ParamTy { } pub fn for_self() -> ParamTy { - ParamTy::new(0, keywords::SelfType.name().as_interned_str()) + ParamTy::new(0, keywords::SelfUpper.name().as_interned_str()) } pub fn for_def(def: &ty::GenericParamDef) -> ParamTy { @@ -1035,7 +1035,7 @@ impl<'a, 'gcx, 'tcx> ParamTy { // FIXME(#50125): Ignoring `Self` with `idx != 0` might lead to weird behavior elsewhere, // but this should only be possible when using `-Z continue-parse-after-error` like // `compile-fail/issue-36638.rs`. - self.name == keywords::SelfType.name().as_str() && self.idx == 0 + self.name == keywords::SelfUpper.name().as_str() && self.idx == 0 } } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 7a246af82e5fe..c6ba20de0d3b9 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -28,7 +28,7 @@ use lazy_static; use session::Session; // The name of the associated type for `Fn` return types -pub const FN_OUTPUT_NAME: &'static str = "Output"; +pub const FN_OUTPUT_NAME: &str = "Output"; // Useful type to use with `Result<>` indicate that an error has already // been reported to the user, so no need to continue checking. diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index a802729e3fbdb..e47e95afb1643 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -615,7 +615,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { let new_loan_str = &new_loan.kind.to_user_str(); self.bccx.cannot_reborrow_already_uniquely_borrowed( new_loan.span, "closure", &nl, &new_loan_msg, new_loan_str, - old_loan.span, &old_loan_msg, previous_end_span, Origin::Ast) + old_loan.span, &old_loan_msg, previous_end_span, "", Origin::Ast) } (..) => self.bccx.cannot_reborrow_already_borrowed( diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs index d25917e51bfd6..ecae6197dc7ca 100644 --- a/src/librustc_codegen_ssa/back/symbol_export.rs +++ b/src/librustc_codegen_ssa/back/symbol_export.rs @@ -225,7 +225,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // These are weak symbols that point to the profile version and the // profile name, which need to be treated as exported so LTO doesn't nix // them. - const PROFILER_WEAK_SYMBOLS: [&'static str; 2] = [ + const PROFILER_WEAK_SYMBOLS: [&str; 2] = [ "__llvm_profile_raw_version", "__llvm_profile_filename", ]; diff --git a/src/librustc_codegen_utils/codegen_backend.rs b/src/librustc_codegen_utils/codegen_backend.rs index 046f0cccfee05..f1f798e770089 100644 --- a/src/librustc_codegen_utils/codegen_backend.rs +++ b/src/librustc_codegen_utils/codegen_backend.rs @@ -22,8 +22,8 @@ #![feature(box_syntax)] use std::any::Any; -use std::io::{self, Write}; -use std::fs::File; +use std::io::Write; +use std::fs; use std::path::Path; use std::sync::{mpsc, Arc}; @@ -81,12 +81,8 @@ pub struct NoLlvmMetadataLoader; impl MetadataLoader for NoLlvmMetadataLoader { fn get_rlib_metadata(&self, _: &Target, filename: &Path) -> Result { - let mut file = File::open(filename) - .map_err(|e| format!("metadata file open err: {:?}", e))?; - - let mut buf = Vec::new(); - io::copy(&mut file, &mut buf).unwrap(); - let buf: OwningRef, [u8]> = OwningRef::new(buf).into(); + let buf = fs::read(filename).map_err(|e| format!("metadata file open err: {:?}", e))?; + let buf: OwningRef, [u8]> = OwningRef::new(buf); return Ok(rustc_erase_owner!(buf.map_owner_box())); } @@ -212,8 +208,7 @@ impl CodegenBackend for MetadataOnlyCodegenBackend { } else { &ongoing_codegen.metadata.raw_data }; - let mut file = File::create(&output_name).unwrap(); - file.write_all(metadata).unwrap(); + fs::write(&output_name, metadata).unwrap(); } sess.abort_if_errors(); diff --git a/src/librustc_codegen_utils/symbol_names.rs b/src/librustc_codegen_utils/symbol_names.rs index 344a252578472..611d7b137c6f2 100644 --- a/src/librustc_codegen_utils/symbol_names.rs +++ b/src/librustc_codegen_utils/symbol_names.rs @@ -389,7 +389,7 @@ impl SymbolPathBuffer { impl ItemPathBuffer for SymbolPathBuffer { fn root_mode(&self) -> &RootMode { - const ABSOLUTE: &'static RootMode = &RootMode::Absolute; + const ABSOLUTE: &RootMode = &RootMode::Absolute; ABSOLUTE } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 96cb235a93362..8e0ecb70c6896 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -81,7 +81,6 @@ pub mod sync; pub mod tiny_list; pub mod thin_vec; pub mod transitive_relation; -pub mod tuple_slice; pub use ena::unify; pub mod vec_linked_list; pub mod work_queue; diff --git a/src/librustc_data_structures/tuple_slice.rs b/src/librustc_data_structures/tuple_slice.rs deleted file mode 100644 index b7c71dd366469..0000000000000 --- a/src/librustc_data_structures/tuple_slice.rs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2014 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. - -use std::slice; - -/// Allows to view uniform tuples as slices -pub trait TupleSlice { - fn as_slice(&self) -> &[T]; - fn as_mut_slice(&mut self) -> &mut [T]; -} - -macro_rules! impl_tuple_slice { - ($tuple_type:ty, $size:expr) => { - impl TupleSlice for $tuple_type { - fn as_slice(&self) -> &[T] { - unsafe { - let ptr = &self.0 as *const T; - slice::from_raw_parts(ptr, $size) - } - } - - fn as_mut_slice(&mut self) -> &mut [T] { - unsafe { - let ptr = &mut self.0 as *mut T; - slice::from_raw_parts_mut(ptr, $size) - } - } - } - } -} - -impl_tuple_slice!((T, T), 2); -impl_tuple_slice!((T, T, T), 3); -impl_tuple_slice!((T, T, T, T), 4); -impl_tuple_slice!((T, T, T, T, T), 5); -impl_tuple_slice!((T, T, T, T, T, T), 6); -impl_tuple_slice!((T, T, T, T, T, T, T), 7); -impl_tuple_slice!((T, T, T, T, T, T, T, T), 8); - -#[test] -fn test_sliced_tuples() { - let t2 = (100, 101); - assert_eq!(t2.as_slice(), &[100, 101]); - - let t3 = (102, 103, 104); - assert_eq!(t3.as_slice(), &[102, 103, 104]); - - let t4 = (105, 106, 107, 108); - assert_eq!(t4.as_slice(), &[105, 106, 107, 108]); - - let t5 = (109, 110, 111, 112, 113); - assert_eq!(t5.as_slice(), &[109, 110, 111, 112, 113]); - - let t6 = (114, 115, 116, 117, 118, 119); - assert_eq!(t6.as_slice(), &[114, 115, 116, 117, 118, 119]); - - let t7 = (120, 121, 122, 123, 124, 125, 126); - assert_eq!(t7.as_slice(), &[120, 121, 122, 123, 124, 125, 126]); - - let t8 = (127, 128, 129, 130, 131, 132, 133, 134); - assert_eq!(t8.as_slice(), &[127, 128, 129, 130, 131, 132, 133, 134]); - -} diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs index 4ff2529b26d93..17ac9a6b53973 100644 --- a/src/librustc_incremental/assert_module_sources.rs +++ b/src/librustc_incremental/assert_module_sources.rs @@ -40,9 +40,9 @@ use syntax::ast; use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED, ATTR_EXPECTED_CGU_REUSE}; -const MODULE: &'static str = "module"; -const CFG: &'static str = "cfg"; -const KIND: &'static str = "kind"; +const MODULE: &str = "module"; +const CFG: &str = "cfg"; +const KIND: &str = "kind"; pub fn assert_module_sources<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { tcx.dep_graph.with_ignore(|| { diff --git a/src/librustc_incremental/persist/file_format.rs b/src/librustc_incremental/persist/file_format.rs index 98f7873fda0e4..e5faba6178233 100644 --- a/src/librustc_incremental/persist/file_format.rs +++ b/src/librustc_incremental/persist/file_format.rs @@ -28,7 +28,7 @@ use rustc::session::config::nightly_options; use rustc_serialize::opaque::Encoder; /// The first few bytes of files generated by incremental compilation -const FILE_MAGIC: &'static [u8] = b"RSIC"; +const FILE_MAGIC: &[u8] = b"RSIC"; /// Change this if the header format changes const HEADER_FORMAT_VERSION: u16 = 0; @@ -36,7 +36,7 @@ const HEADER_FORMAT_VERSION: u16 = 0; /// A version string that hopefully is always different for compiler versions /// with different encodings of incremental compilation artifacts. Contains /// the git commit hash. -const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION"); +const RUSTC_VERSION: Option<&str> = option_env!("CFG_VERSION"); pub fn write_file_header(stream: &mut Encoder) { stream.emit_raw_bytes(FILE_MAGIC); diff --git a/src/librustc_incremental/persist/fs.rs b/src/librustc_incremental/persist/fs.rs index 75cdefaf49f00..bc98798f77253 100644 --- a/src/librustc_incremental/persist/fs.rs +++ b/src/librustc_incremental/persist/fs.rs @@ -128,10 +128,10 @@ use std::time::{UNIX_EPOCH, SystemTime, Duration}; use rand::{RngCore, thread_rng}; -const LOCK_FILE_EXT: &'static str = ".lock"; -const DEP_GRAPH_FILENAME: &'static str = "dep-graph.bin"; -const WORK_PRODUCTS_FILENAME: &'static str = "work-products.bin"; -const QUERY_CACHE_FILENAME: &'static str = "query-cache.bin"; +const LOCK_FILE_EXT: &str = ".lock"; +const DEP_GRAPH_FILENAME: &str = "dep-graph.bin"; +const WORK_PRODUCTS_FILENAME: &str = "work-products.bin"; +const QUERY_CACHE_FILENAME: &str = "query-cache.bin"; // We encode integers using the following base, so they are shorter than decimal // or hexadecimal numbers (we want short file and directory names). Since these diff --git a/src/librustc_incremental/persist/work_product.rs b/src/librustc_incremental/persist/work_product.rs index cfe59b1f67262..ddd28eb5393ec 100644 --- a/src/librustc_incremental/persist/work_product.rs +++ b/src/librustc_incremental/persist/work_product.rs @@ -29,7 +29,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( return None } - let saved_files: Option> = + let saved_files = files.iter() .map(|&(kind, ref path)| { let extension = match kind { @@ -51,11 +51,7 @@ pub fn copy_cgu_workproducts_to_incr_comp_cache_dir( } } }) - .collect(); - let saved_files = match saved_files { - None => return None, - Some(v) => v, - }; + .collect::>>()?; let work_product = WorkProduct { cgu_name: cgu_name.to_string(), diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index fe197e3e2e28c..7fb7a06ea1ad5 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -12,7 +12,6 @@ test = false [dependencies] log = "0.4" rustc = { path = "../librustc" } -rustc_mir = { path = "../librustc_mir"} rustc_target = { path = "../librustc_target" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 71efc5654eff3..4d709d574c4f1 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -36,7 +36,6 @@ extern crate syntax; extern crate rustc; #[macro_use] extern crate log; -extern crate rustc_mir; extern crate rustc_target; extern crate syntax_pos; extern crate rustc_data_structures; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index fab618d9c8ec8..c7eb06cbe0053 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -473,7 +473,7 @@ impl UnusedImportBraces { match items[0].0.kind { ast::UseTreeKind::Simple(rename, ..) => { let orig_ident = items[0].0.prefix.segments.last().unwrap().ident; - if orig_ident.name == keywords::SelfValue.name() { + if orig_ident.name == keywords::SelfLower.name() { return; } node_ident = rename.unwrap_or(orig_ident); diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index e91d15b78c075..fc3af6cf2e732 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -52,7 +52,7 @@ pub const METADATA_VERSION: u8 = 4; /// This header is followed by the position of the `CrateRoot`, /// which is encoded as a 32-bit big-endian unsigned integer, /// and further followed by the rustc version string. -pub const METADATA_HEADER: &'static [u8; 12] = +pub const METADATA_HEADER: &[u8; 12] = &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; /// A value of type T referred to by its absolute position diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index 2da0ede9d15ce..b81d93f3930bc 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -15,7 +15,7 @@ either = "1.5.0" graphviz = { path = "../libgraphviz" } log = "0.4" log_settings = "0.1.1" -polonius-engine = "0.5.0" +polonius-engine = "0.6.0" rustc = { path = "../librustc" } rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index fd7dc7fc4bd3a..947c32df0f6a3 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -16,7 +16,7 @@ use rustc::mir::traversal; use rustc::mir::visit::{ PlaceContext, Visitor, NonUseContext, MutatingUseContext, NonMutatingUseContext }; -use rustc::mir::{self, Location, Mir, Place, Local}; +use rustc::mir::{self, Location, Mir, Local}; use rustc::ty::{RegionVid, TyCtxt}; use rustc::util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::indexed_vec::IndexVec; @@ -41,10 +41,6 @@ crate struct BorrowSet<'tcx> { /// only need to store one borrow index crate activation_map: FxHashMap>, - /// Every borrow has a region; this maps each such regions back to - /// its borrow-indexes. - crate region_map: FxHashMap>, - /// Map from local to all the borrows on that local crate local_map: FxHashMap>, @@ -149,7 +145,6 @@ impl<'tcx> BorrowSet<'tcx> { idx_vec: IndexVec::new(), location_map: Default::default(), activation_map: Default::default(), - region_map: Default::default(), local_map: Default::default(), pending_activations: Default::default(), locals_state_at_exit: @@ -164,7 +159,6 @@ impl<'tcx> BorrowSet<'tcx> { borrows: visitor.idx_vec, location_map: visitor.location_map, activation_map: visitor.activation_map, - region_map: visitor.region_map, local_map: visitor.local_map, locals_state_at_exit: visitor.locals_state_at_exit, } @@ -184,7 +178,6 @@ struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> { idx_vec: IndexVec>, location_map: FxHashMap, activation_map: FxHashMap>, - region_map: FxHashMap>, local_map: FxHashMap>, /// When we encounter a 2-phase borrow statement, it will always @@ -229,7 +222,6 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { self.insert_as_pending_if_two_phase(location, &assigned_place, kind, idx); - self.region_map.entry(region).or_default().insert(idx); if let Some(local) = borrowed_place.root_local() { self.local_map.entry(local).or_default().insert(idx); } @@ -238,68 +230,68 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> { self.super_assign(block, assigned_place, rvalue, location) } - fn visit_place( + fn visit_local( &mut self, - place: &mir::Place<'tcx>, + temp: &Local, context: PlaceContext<'tcx>, location: Location, ) { - self.super_place(place, context, location); - - // We found a use of some temporary TEMP... - if let Place::Local(temp) = place { - // ... check whether we (earlier) saw a 2-phase borrow like - // - // TMP = &mut place - if let Some(&borrow_index) = self.pending_activations.get(temp) { - let borrow_data = &mut self.idx_vec[borrow_index]; - - // Watch out: the use of TMP in the borrow itself - // doesn't count as an activation. =) - if borrow_data.reserve_location == location && - context == PlaceContext::MutatingUse(MutatingUseContext::Store) - { - return; - } + if !context.is_use() { + return; + } - if let TwoPhaseActivation::ActivatedAt(other_location) = - borrow_data.activation_location { - span_bug!( - self.mir.source_info(location).span, - "found two uses for 2-phase borrow temporary {:?}: \ - {:?} and {:?}", - temp, - location, - other_location, - ); - } + // We found a use of some temporary TMP + // check whether we (earlier) saw a 2-phase borrow like + // + // TMP = &mut place + if let Some(&borrow_index) = self.pending_activations.get(temp) { + let borrow_data = &mut self.idx_vec[borrow_index]; - // Otherwise, this is the unique later use - // that we expect. - borrow_data.activation_location = match context { - // The use of TMP in a shared borrow does not - // count as an actual activation. - PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) | - PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) => - TwoPhaseActivation::NotActivated, - _ => { - // Double check: This borrow is indeed a two-phase borrow (that is, - // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and - // we've not found any other activations (checked above). - assert_eq!( - borrow_data.activation_location, - TwoPhaseActivation::NotActivated, - "never found an activation for this borrow!", - ); - - self.activation_map - .entry(location) - .or_default() - .push(borrow_index); - TwoPhaseActivation::ActivatedAt(location) - } - }; + // Watch out: the use of TMP in the borrow itself + // doesn't count as an activation. =) + if borrow_data.reserve_location == location && + context == PlaceContext::MutatingUse(MutatingUseContext::Store) + { + return; + } + + if let TwoPhaseActivation::ActivatedAt(other_location) = + borrow_data.activation_location { + span_bug!( + self.mir.source_info(location).span, + "found two uses for 2-phase borrow temporary {:?}: \ + {:?} and {:?}", + temp, + location, + other_location, + ); } + + // Otherwise, this is the unique later use + // that we expect. + borrow_data.activation_location = match context { + // The use of TMP in a shared borrow does not + // count as an actual activation. + PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow(..)) | + PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow(..)) => + TwoPhaseActivation::NotActivated, + _ => { + // Double check: This borrow is indeed a two-phase borrow (that is, + // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and + // we've not found any other activations (checked above). + assert_eq!( + borrow_data.activation_location, + TwoPhaseActivation::NotActivated, + "never found an activation for this borrow!", + ); + + self.activation_map + .entry(location) + .or_default() + .push(borrow_index); + TwoPhaseActivation::ActivatedAt(location) + } + }; } } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 4ccd26bee8b88..ba26ed36c20f4 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -344,6 +344,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let first_borrow_desc; + let explanation = self.explain_why_borrow_contains_point(context, issued_borrow, None); + let second_borrow_desc = if explanation.is_explained() { + "second " + } else { + "" + }; + // FIXME: supply non-"" `opt_via` when appropriate let mut err = match ( gen_borrow_kind, @@ -454,6 +461,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { issued_span, "", None, + second_borrow_desc, Origin::Mir, ) } @@ -469,6 +477,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { issued_span, "", None, + second_borrow_desc, Origin::Mir, ) } @@ -513,7 +522,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); } - self.explain_why_borrow_contains_point(context, issued_borrow, None) + explanation .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc); err.buffer(&mut self.errors_buffer); diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 7afe2c67adc9b..4bcabfef4fd7f 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -263,7 +263,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { // Deliberately fall into this case for all implicit self types, // so that we don't fall in to the next case with them. *kind == mir::ImplicitSelfKind::MutRef - } else if Some(keywords::SelfValue.name()) == local_decl.name { + } else if Some(keywords::SelfLower.name()) == local_decl.name { // Otherwise, check if the name is the self kewyord - in which case // we have an explicit self. Do the same thing in this case and check // for a `self: &mut Self` to suggest removing the `&mut`. diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index bb9a29b055b7f..7fb3f02e0e3f3 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -52,6 +52,12 @@ pub(in borrow_check) enum LaterUseKind { } impl BorrowExplanation { + pub(in borrow_check) fn is_explained(&self) -> bool { + match self { + BorrowExplanation::Unexplained => false, + _ => true, + } + } pub(in borrow_check) fn add_explanation_to_diagnostic<'cx, 'gcx, 'tcx>( &self, tcx: TyCtxt<'cx, 'gcx, 'tcx>, @@ -271,13 +277,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { borrow_region_vid, region, ); - let opt_place_desc = self.describe_place(&borrow.borrowed_place); - BorrowExplanation::MustBeValidFor { - category, - from_closure, - span, - region_name, - opt_place_desc, + if let Some(region_name) = region_name { + let opt_place_desc = self.describe_place(&borrow.borrowed_place); + BorrowExplanation::MustBeValidFor { + category, + from_closure, + span, + region_name, + opt_place_desc, + } + } else { + BorrowExplanation::Unexplained } } else { BorrowExplanation::Unexplained diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 8af23a8813a9e..42d20e675bad9 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -66,10 +66,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> { /// Visits the whole MIR and generates invalidates() facts /// Most of the code implementing this was stolen from borrow_check/mod.rs impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> { - fn visit_statement(&mut self, - block: BasicBlock, - statement: &Statement<'tcx>, - location: Location) { + fn visit_statement( + &mut self, + block: BasicBlock, + statement: &Statement<'tcx>, + location: Location, + ) { + self.check_activations(location); + match statement.kind { StatementKind::Assign(ref lhs, ref rhs) => { self.consume_rvalue( @@ -159,6 +163,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> { terminator: &Terminator<'tcx>, location: Location ) { + self.check_activations(location); + match terminator.kind { TerminatorKind::SwitchInt { ref discr, @@ -482,5 +488,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> { let lidx = self.location_table.start_index(l); self.all_facts.invalidates.push((lidx, b)); } + + fn check_activations( + &mut self, + location: Location, + ) { + if !self.tcx.two_phase_borrows() { + return; + } + + // Two-phase borrow support: For each activation that is newly + // generated at this statement, check if it interferes with + // another borrow. + for &borrow_index in self.borrow_set.activations_at_location(location) { + let borrow = &self.borrow_set[borrow_index]; + + // only mutable borrows should be 2-phase + assert!(match borrow.kind { + BorrowKind::Shared | BorrowKind::Shallow => false, + BorrowKind::Unique | BorrowKind::Mut { .. } => true, + }); + + self.access_place( + ContextKind::Activation.new(location), + &borrow.borrowed_place, + ( + Deep, + Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index), + ), + LocalMutationIsAllowed::No, + ); + + // We do not need to call `check_if_path_or_subpath_is_moved` + // again, as we already called it when we made the + // initial reservation. + } + } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index 3358e5851f939..32aaa0590d2f9 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -38,6 +38,7 @@ impl ConstraintDescription for ConstraintCategory { match self { ConstraintCategory::Assignment => "assignment ", ConstraintCategory::Return => "returning this value ", + ConstraintCategory::Yield => "yielding this value ", ConstraintCategory::UseAsConst => "using this value as a constant ", ConstraintCategory::UseAsStatic => "using this value as a static ", ConstraintCategory::Cast => "cast ", @@ -133,11 +134,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); match categorized_path[i].0 { - ConstraintCategory::OpaqueType - | ConstraintCategory::Boring - | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => false, - ConstraintCategory::TypeAnnotation | ConstraintCategory::Return => true, + ConstraintCategory::OpaqueType | ConstraintCategory::Boring | + ConstraintCategory::BoringNoLocation | ConstraintCategory::Internal => false, + ConstraintCategory::TypeAnnotation | ConstraintCategory::Return | + ConstraintCategory::Yield => true, _ => constraint_sup_scc != target_scc, } }); @@ -376,9 +376,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.span_label(span, message); - match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1) - .source - { + match self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, &mut 1).unwrap().source { RegionNameSource::NamedEarlyBoundRegion(fr_span) | RegionNameSource::NamedFreeRegion(fr_span) | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _) @@ -521,10 +519,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); let counter = &mut 1; - let fr_name = self.give_region_a_name(infcx, mir, mir_def_id, fr, counter); + let fr_name = self.give_region_a_name(infcx, mir, mir_def_id, fr, counter).unwrap(); fr_name.highlight_region_name(&mut diag); let outlived_fr_name = - self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, counter); + self.give_region_a_name(infcx, mir, mir_def_id, outlived_fr, counter).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); let mir_def_name = if infcx.tcx.is_closure(mir_def_id) { @@ -661,7 +659,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx: &InferCtxt<'_, '_, 'tcx>, borrow_region: RegionVid, outlived_region: RegionVid, - ) -> (ConstraintCategory, bool, Span, RegionName) { + ) -> (ConstraintCategory, bool, Span, Option) { let (category, from_closure, span) = self.best_blame_constraint(mir, borrow_region, |r| r == outlived_region); let outlived_fr_name = diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index a32fb0503a814..b01e257ae2eff 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -157,7 +157,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { mir_def_id: DefId, fr: RegionVid, counter: &mut usize, - ) -> RegionName { + ) -> Option { debug!("give_region_a_name(fr={:?}, counter={})", fr, counter); assert!(self.universal_regions.is_universal_region(fr)); @@ -177,8 +177,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.give_name_if_anonymous_region_appears_in_output( infcx, mir, mir_def_id, fr, counter, ) - }) - .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr)); + }); debug!("give_region_a_name: gave name {:?}", value); value diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 5f64dfd931c89..33346a584e5a4 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1467,7 +1467,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { value_ty, ty, term_location.to_locations(), - ConstraintCategory::Return, + ConstraintCategory::Yield, ) { span_mirbug!( self, diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index f73e08eb13521..7d583b4f54191 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -87,10 +87,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> { type Item = &'cx Place<'tcx>; fn next(&mut self) -> Option { - let mut cursor = match self.next { - None => return None, - Some(place) => place, - }; + let mut cursor = self.next?; // Post-processing `place`: Enqueue any remaining // work. Also, `place` may not be a prefix itself, but diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index 6896c91352fdd..f6a9d46b5e2cb 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -137,8 +137,8 @@ where MWF: MirWithFlowState<'tcx>, block: BasicBlock, mir: &Mir) -> io::Result<()> { // Header rows - const HDRS: [&'static str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"]; - const HDR_FMT: &'static str = "bgcolor=\"grey\""; + const HDRS: [&str; 4] = ["ENTRY", "MIR", "BLOCK GENS", "BLOCK KILLS"]; + const HDR_FMT: &str = "bgcolor=\"grey\""; write!(w, "")?; diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 27bc28ac81d84..3a9e4fc9e4ab9 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { // re-consider the current implementations of the // propagate_call_return method. - if let mir::Rvalue::Ref(region, _, ref place) = **rhs { + if let mir::Rvalue::Ref(_, _, ref place) = **rhs { if place.ignore_borrow( self.tcx, self.mir, @@ -258,13 +258,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { panic!("could not find BorrowIndex for location {:?}", location); }); - assert!(self.borrow_set.region_map - .get(®ion.to_region_vid()) - .unwrap_or_else(|| { - panic!("could not find BorrowIndexs for RegionVid {:?}", region); - }) - .contains(&index) - ); sets.gen(*index); // Issue #46746: Two-phase borrows handles diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 56a9daf84f768..ec5617d705248 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -606,7 +606,7 @@ static X: i32 = 1; const C: i32 = 2; // these three are not allowed: -const CR: &'static mut i32 = &mut C; +const CR: &mut i32 = &mut C; static STATIC_REF: &'static mut i32 = &mut X; static CONST_REF: &'static mut i32 = &mut C; ``` @@ -1163,7 +1163,7 @@ You can also have this error while using a cell type: use std::cell::Cell; const A: Cell = Cell::new(1); -const B: &'static Cell = &A; +const B: &Cell = &A; // error: cannot borrow a constant which may contain interior mutability, // create a static instead @@ -1171,10 +1171,10 @@ const B: &'static Cell = &A; struct C { a: Cell } const D: C = C { a: Cell::new(1) }; -const E: &'static Cell = &D.a; // error +const E: &Cell = &D.a; // error // or: -const F: &'static C = &D; // error +const F: &C = &D; // error ``` This is because cell types do operations that are not thread-safe. Due to this, diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 3a6ee6da42215..528942df29fee 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -585,7 +585,7 @@ fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, // smallest into each other) we're sure to start off with a deterministic // order (sorted by name). This'll mean that if two cgus have the same size // the stable sort below will keep everything nice and deterministic. - codegen_units.sort_by_key(|cgu| cgu.name().clone()); + codegen_units.sort_by_key(|cgu| *cgu.name()); // Merge the two smallest codegen units until the target size is reached. while codegen_units.len() > target_cgu_count { @@ -985,7 +985,7 @@ fn collect_and_partition_mono_items<'a, 'tcx>( output.push_str(" @@"); let mut empty = Vec::new(); let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); - cgus.as_mut_slice().sort_by_cached_key(|&(ref name, _)| name.clone()); + cgus.sort_by_key(|(name, _)| *name); cgus.dedup(); for &(ref cgu_name, (linkage, _)) in cgus.iter() { output.push_str(" "); diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index c0edd3926d32d..6d7fc404edbb1 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -10,17 +10,25 @@ //! This module provides two passes: //! -//! - [CleanAscribeUserType], that replaces all -//! [StatementKind::AscribeUserType] statements with [StatementKind::Nop]. -//! - [CleanFakeReadsAndBorrows], that replaces all [FakeRead] statements and -//! borrows that are read by [FakeReadCause::ForMatchGuard] fake reads with -//! [StatementKind::Nop]. +//! - [`CleanAscribeUserType`], that replaces all [`AscribeUserType`] +//! statements with [`Nop`]. +//! - [`CleanFakeReadsAndBorrows`], that replaces all [`FakeRead`] statements +//! and borrows that are read by [`ForMatchGuard`] fake reads with [`Nop`]. //! -//! The [CleanFakeReadsAndBorrows] "pass" is actually implemented as two +//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two //! traversals (aka visits) of the input MIR. The first traversal, -//! [DeleteAndRecordFakeReads], deletes the fake reads and finds the temporaries -//! read by [ForMatchGuard] reads, and [DeleteFakeBorrows] deletes the -//! initialization of those temporaries. +//! [`DeleteAndRecordFakeReads`], deletes the fake reads and finds the +//! temporaries read by [`ForMatchGuard`] reads, and [`DeleteFakeBorrows`] +//! deletes the initialization of those temporaries. +//! +//! [`CleanAscribeUserType`]: cleanup_post_borrowck::CleanAscribeUserType +//! [`CleanFakeReadsAndBorrows`]: cleanup_post_borrowck::CleanFakeReadsAndBorrows +//! [`DeleteAndRecordFakeReads`]: cleanup_post_borrowck::DeleteAndRecordFakeReads +//! [`DeleteFakeBorrows`]: cleanup_post_borrowck::DeleteFakeBorrows +//! [`AscribeUserType`]: rustc::mir::StatementKind::AscribeUserType +//! [`Nop`]: rustc::mir::StatementKind::Nop +//! [`FakeRead`]: rustc::mir::StatementKind::FakeRead +//! [`ForMatchGuard`]: rustc::mir::FakeReadCause::ForMatchGuard use rustc_data_structures::fx::FxHashSet; diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index ae0483e3c140c..8566f845f23e3 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -261,6 +261,7 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { old_loan_span: Span, old_opt_via: &str, previous_end_span: Option, + second_borrow_desc: &str, o: Origin, ) -> DiagnosticBuilder<'cx> { let mut err = struct_span_err!( @@ -274,7 +275,10 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { kind_new, OGN = o ); - err.span_label(new_loan_span, format!("borrow occurs here{}", opt_via)); + err.span_label( + new_loan_span, + format!("{}borrow occurs here{}", second_borrow_desc, opt_via), + ); err.span_label( old_loan_span, format!("{} construction occurs here{}", container_name, old_opt_via), diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c74492fe64936..2d7e7d01274f6 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -24,7 +24,7 @@ use std::path::{Path, PathBuf}; use super::graphviz::write_mir_fn_graphviz; use transform::MirSource; -const INDENT: &'static str = " "; +const INDENT: &str = " "; /// Alignment for lining up comments following MIR statements pub(crate) const ALIGN: usize = 40; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0fa41cb484fc9..4e773124c8dab 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -145,7 +145,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } _ => None, }.map(|ctxt| Segment::from_ident(Ident::new( - keywords::CrateRoot.name(), use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt) + keywords::PathRoot.name(), use_tree.prefix.span.shrink_to_lo().with_ctxt(ctxt) ))); let prefix = crate_root.into_iter().chain(prefix_iter).collect::>(); @@ -153,7 +153,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let empty_for_self = |prefix: &[Segment]| { prefix.is_empty() || - prefix.len() == 1 && prefix[0].ident.name == keywords::CrateRoot.name() + prefix.len() == 1 && prefix[0].ident.name == keywords::PathRoot.name() }; match use_tree.kind { ast::UseTreeKind::Simple(rename, ..) => { @@ -164,7 +164,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if nested { // Correctly handle `self` - if source.ident.name == keywords::SelfValue.name() { + if source.ident.name == keywords::SelfLower.name() { type_ns_only = true; if empty_for_self(&module_path) { @@ -185,7 +185,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } } else { // Disallow `self` - if source.ident.name == keywords::SelfValue.name() { + if source.ident.name == keywords::SelfLower.name() { resolve_error(self, use_tree.span, ResolutionError::SelfImportsOnlyAllowedWithin); @@ -205,7 +205,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // `crate_name` should not be interpreted as relative. module_path.push(Segment { ident: Ident { - name: keywords::CrateRoot.name(), + name: keywords::PathRoot.name(), span: source.ident.span, }, id: Some(self.session.next_node_id()), @@ -270,7 +270,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Ensure there is at most one `self` in the list let self_spans = items.iter().filter_map(|&(ref use_tree, _)| { if let ast::UseTreeKind::Simple(..) = use_tree.kind { - if use_tree.ident().name == keywords::SelfValue.name() { + if use_tree.ident().name == keywords::SelfLower.name() { return Some(use_tree.span); } } @@ -305,7 +305,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let new_span = prefix[prefix.len() - 1].ident.span; let tree = ast::UseTree { prefix: ast::Path::from_ident( - Ident::new(keywords::SelfValue.name(), new_span) + Ident::new(keywords::SelfLower.name(), new_span) ), kind: ast::UseTreeKind::Simple( Some(Ident::new(keywords::Underscore.name().gensymed(), new_span)), @@ -318,7 +318,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // This particular use tree &tree, id, &prefix, true, // The whole `use` item - parent_scope.clone(), item, ty::Visibility::Invisible, root_span, + parent_scope, item, ty::Visibility::Invisible, root_span, ); } } @@ -344,13 +344,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } ItemKind::ExternCrate(orig_name) => { - let module = if orig_name.is_none() && ident.name == keywords::SelfValue.name() { + let module = if orig_name.is_none() && ident.name == keywords::SelfLower.name() { self.session .struct_span_err(item.span, "`extern crate self;` requires renaming") .span_suggestion(item.span, "try", "extern crate self as name;".into()) .emit(); return; - } else if orig_name == Some(keywords::SelfValue.name()) { + } else if orig_name == Some(keywords::SelfLower.name()) { if !self.session.features_untracked().extern_crate_self { emit_feature_err(&self.session.parse_sess, "extern_crate_self", item.span, GateIssue::Language, "`extern crate self` is unstable"); @@ -783,7 +783,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { "an `extern crate` loading macros must be at the crate root"); } if let ItemKind::ExternCrate(Some(orig_name)) = item.node { - if orig_name == keywords::SelfValue.name() { + if orig_name == keywords::SelfLower.name() { self.session.span_err(attr.span, "`macro_use` is not supported on `extern crate self`"); } diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index e2a6303f57944..23edaf1243812 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -30,7 +30,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { match (path.get(0), path.get(1)) { // `{{root}}::ident::...` on both editions. // On 2015 `{{root}}` is usually added implicitly. - (Some(fst), Some(snd)) if fst.ident.name == keywords::CrateRoot.name() && + (Some(fst), Some(snd)) if fst.ident.name == keywords::PathRoot.name() && !snd.ident.is_path_segment_keyword() => {} // `ident::...` on 2018 (Some(fst), _) if fst.ident.span.rust_2018() && @@ -61,7 +61,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { parent_scope: &ParentScope<'b>, ) -> Option<(Vec, Option)> { // Replace first ident with `self` and check if that is valid. - path[0].ident.name = keywords::SelfValue.name(); + path[0].ident.name = keywords::SelfLower.name(); let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index fdac1e3b81652..9ea39aea86867 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -769,7 +769,7 @@ impl<'a, 'tcx, 'cl> Visitor<'tcx> for Resolver<'a, 'cl> { self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); } TyKind::ImplicitSelf => { - let self_ty = keywords::SelfType.ident(); + let self_ty = keywords::SelfUpper.ident(); let def = self.resolve_ident_in_lexical_scope(self_ty, TypeNS, Some(ty.id), ty.span) .map_or(Def::Err, |d| d.def()); self.record_def(ty.id, PathResolution::new(def)); @@ -1679,7 +1679,7 @@ impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { components: &[&str], is_value: bool ) -> hir::Path { - let segments = iter::once(keywords::CrateRoot.ident()) + let segments = iter::once(keywords::PathRoot.ident()) .chain( crate_root.into_iter() .chain(components.iter().cloned()) @@ -1721,7 +1721,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let path = if path_str.starts_with("::") { ast::Path { span, - segments: iter::once(keywords::CrateRoot.ident()) + segments: iter::once(keywords::PathRoot.ident()) .chain({ path_str.split("::").skip(1).map(Ident::from_str) }) @@ -2036,7 +2036,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let record_used = record_used_id.is_some(); assert!(ns == TypeNS || ns == ValueNS); if ns == TypeNS { - ident.span = if ident.name == keywords::SelfType.name() { + ident.span = if ident.name == keywords::SelfUpper.name() { // FIXME(jseyfried) improve `Self` hygiene ident.span.with_ctxt(SyntaxContext::empty()) } else { @@ -2649,7 +2649,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let mut self_type_rib = Rib::new(NormalRibKind); // plain insert (no renaming, types are not currently hygienic....) - self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def); + self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def); self.ribs[TypeNS].push(self_type_rib); f(self); self.ribs[TypeNS].pop(); @@ -2660,7 +2660,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { { let self_def = Def::SelfCtor(impl_id); let mut self_type_rib = Rib::new(NormalRibKind); - self_type_rib.bindings.insert(keywords::SelfType.ident(), self_def); + self_type_rib.bindings.insert(keywords::SelfUpper.ident(), self_def); self.ribs[ValueNS].push(self_type_rib); f(self); self.ribs[ValueNS].pop(); @@ -3146,7 +3146,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let item_span = path.last().unwrap().ident.span; let (mod_prefix, mod_str) = if path.len() == 1 { (String::new(), "this scope".to_string()) - } else if path.len() == 2 && path[0].ident.name == keywords::CrateRoot.name() { + } else if path.len() == 2 && path[0].ident.name == keywords::PathRoot.name() { (String::new(), "the crate root".to_string()) } else { let mod_path = &path[..path.len() - 1]; @@ -3515,13 +3515,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn self_type_is_available(&mut self, span: Span) -> bool { - let binding = self.resolve_ident_in_lexical_scope(keywords::SelfType.ident(), + let binding = self.resolve_ident_in_lexical_scope(keywords::SelfUpper.ident(), TypeNS, None, span); if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false } } fn self_value_is_available(&mut self, self_span: Span, path_span: Span) -> bool { - let ident = Ident::new(keywords::SelfValue.name(), self_span); + let ident = Ident::new(keywords::SelfLower.name(), self_span); let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, path_span); if let Some(LexicalScopeBinding::Def(def)) = binding { def != Def::Err } else { false } } @@ -3673,7 +3673,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { }; if path.len() > 1 && !global_by_default && result.base_def() != Def::Err && - path[0].ident.name != keywords::CrateRoot.name() && + path[0].ident.name != keywords::PathRoot.name() && path[0].ident.name != keywords::DollarCrate.name() { let unqualified_result = { match self.resolve_path_without_parent_scope( @@ -3755,7 +3755,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let name = ident.name; allow_super &= ns == TypeNS && - (name == keywords::SelfValue.name() || + (name == keywords::SelfLower.name() || name == keywords::Super.name()); if ns == TypeNS { @@ -3779,24 +3779,24 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { return PathResult::Failed(ident.span, msg, false); } if i == 0 { - if name == keywords::SelfValue.name() { + if name == keywords::SelfLower.name() { let mut ctxt = ident.span.ctxt().modern(); module = Some(ModuleOrUniformRoot::Module( self.resolve_self(&mut ctxt, self.current_module))); continue; } if name == keywords::Extern.name() || - name == keywords::CrateRoot.name() && ident.span.rust_2018() { + name == keywords::PathRoot.name() && ident.span.rust_2018() { module = Some(ModuleOrUniformRoot::ExternPrelude); continue; } - if name == keywords::CrateRoot.name() && + if name == keywords::PathRoot.name() && ident.span.rust_2015() && self.session.rust_2018() { // `::a::b` from 2015 macro on 2018 global edition module = Some(ModuleOrUniformRoot::CrateRootAndExternPrelude); continue; } - if name == keywords::CrateRoot.name() || + if name == keywords::PathRoot.name() || name == keywords::Crate.name() || name == keywords::DollarCrate.name() { // `::a::b`, `crate::a::b` or `$crate::a::b` @@ -3809,12 +3809,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // Report special messages for path segment keywords in wrong positions. if ident.is_path_segment_keyword() && i != 0 { - let name_str = if name == keywords::CrateRoot.name() { + let name_str = if name == keywords::PathRoot.name() { "crate root".to_string() } else { format!("`{}`", name) }; - let msg = if i == 1 && path[0].ident.name == keywords::CrateRoot.name() { + let msg = if i == 1 && path[0].ident.name == keywords::PathRoot.name() { format!("global paths cannot start with {}", name_str) } else { format!("{} in paths can only be used in start position", name_str) @@ -3944,7 +3944,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // We're only interested in `use` paths which should start with // `{{root}}` or `extern` currently. - if first_name != keywords::Extern.name() && first_name != keywords::CrateRoot.name() { + if first_name != keywords::Extern.name() && first_name != keywords::PathRoot.name() { return } @@ -3953,7 +3953,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { Some(Segment { ident, .. }) if ident.name == keywords::Crate.name() => return, // Otherwise go below to see if it's an extern crate Some(_) => {} - // If the path has length one (and it's `CrateRoot` most likely) + // If the path has length one (and it's `PathRoot` most likely) // then we don't know whether we're gonna be importing a crate or an // item in our crate. Defer this lint to elsewhere None => return, @@ -4740,7 +4740,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } else { let ctxt = ident.span.ctxt(); Some(Segment::from_ident(Ident::new( - keywords::CrateRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt) + keywords::PathRoot.name(), path.span.shrink_to_lo().with_ctxt(ctxt) ))) }; @@ -5090,17 +5090,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn is_self_type(path: &[Segment], namespace: Namespace) -> bool { - namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfType.name() + namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfUpper.name() } fn is_self_value(path: &[Segment], namespace: Namespace) -> bool { - namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfValue.name() + namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfLower.name() } fn names_to_string(idents: &[Ident]) -> String { let mut result = String::new(); for (i, ident) in idents.iter() - .filter(|ident| ident.name != keywords::CrateRoot.name()) + .filter(|ident| ident.name != keywords::PathRoot.name()) .enumerate() { if i > 0 { result.push_str("::"); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 5db3efee9f6a1..65a9652cd237c 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -167,7 +167,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { if path.segments[0].ident.name == keywords::DollarCrate.name() { let module = self.0.resolve_crate_root(path.segments[0].ident); - path.segments[0].ident.name = keywords::CrateRoot.name(); + path.segments[0].ident.name = keywords::PathRoot.name(); if !module.is_local() { let span = path.segments[0].ident.span; path.segments.insert(1, match module.kind { @@ -674,7 +674,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { _ => Err(Determinacy::Determined), } WhereToResolve::CrateRoot => { - let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span); + let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span); let root_module = self.resolve_crate_root(root_ident); let binding = self.resolve_ident_in_module_ext( ModuleOrUniformRoot::Module(root_module), @@ -960,7 +960,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { break 'ok; } if rust_2015 { - let root_ident = Ident::new(keywords::CrateRoot.name(), orig_ident.span); + let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span); let root_module = self.resolve_crate_root(root_ident); if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module), orig_ident, ns, None, false, path_span) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index e7cd32f4e810f..865aace8aabb5 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -198,7 +198,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { .to_name_binding(self.arenas); return Ok(binding); } else if ident.name == keywords::Super.name() || - ident.name == keywords::SelfValue.name() { + ident.name == keywords::SelfLower.name() { // FIXME: Implement these with renaming requirements so that e.g. // `use super;` doesn't work, but `use super as name;` does. // Fall through here to get an error from `early_resolve_...`. @@ -1263,8 +1263,8 @@ fn import_path_to_string(names: &[Ident], subclass: &ImportDirectiveSubclass, span: Span) -> String { let pos = names.iter() - .position(|p| span == p.span && p.name != keywords::CrateRoot.name()); - let global = !names.is_empty() && names[0].name == keywords::CrateRoot.name(); + .position(|p| span == p.span && p.name != keywords::PathRoot.name()); + let global = !names.is_empty() && names[0].name == keywords::PathRoot.name(); if let Some(pos) = pos { let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] }; names_to_string(names) diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 5b8070cbf3d8e..5830fa00be8cb 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -234,7 +234,7 @@ macro_rules! supported_targets { $(mod $module;)* /// List of supported targets - const TARGETS: &'static [&'static str] = &[$($triple),*]; + const TARGETS: &[&str] = &[$($triple),*]; fn load_specific(target: &str) -> TargetResult { match target { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a1bb0b53f1fce..5682a73bed573 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -938,7 +938,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty opt_self = Some(ty::GenericParamDef { index: 0, - name: keywords::SelfType.name().as_interned_str(), + name: keywords::SelfUpper.name().as_interned_str(), def_id: tcx.hir.local_def_id(param_id), pure_wrt_drop: false, kind: ty::GenericParamDefKind::Type { @@ -1007,7 +1007,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty synthetic, .. } => { - if param.name.ident().name == keywords::SelfType.name() { + if param.name.ident().name == keywords::SelfUpper.name() { span_bug!( param.span, "`Self` should not be the name of a regular parameter" diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index fd8f70b19e7ec..09862a7ad106a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1575,7 +1575,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind { ty::GenericParamDefKind::Lifetime => None, ty::GenericParamDefKind::Type { .. } => { - if param.name == keywords::SelfType.name().as_str() { + if param.name == keywords::SelfUpper.name().as_str() { assert_eq!(param.index, 0); return None; } @@ -3174,7 +3174,7 @@ fn qpath_to_string(p: &hir::QPath) -> String { if i > 0 { s.push_str("::"); } - if seg.ident.name != keywords::CrateRoot.name() { + if seg.ident.name != keywords::PathRoot.name() { s.push_str(&*seg.ident.as_str()); } } @@ -3726,7 +3726,7 @@ fn resolve_type(cx: &DocContext, hir::Float(float_ty) => return Primitive(float_ty.into()), }, Def::SelfTy(..) if path.segments.len() == 1 => { - return Generic(keywords::SelfType.name().to_string()); + return Generic(keywords::SelfUpper.name().to_string()); } Def::TyParam(..) if path.segments.len() == 1 => { return Generic(format!("{:#}", path)); @@ -3948,10 +3948,7 @@ pub fn path_to_def_local(tcx: &TyCtxt, path: &[&str]) -> Option { let mut path_it = path.iter().peekable(); loop { - let segment = match path_it.next() { - Some(segment) => segment, - None => return None, - }; + let segment = path_it.next()?; for item_id in mem::replace(&mut items, HirVec::new()).iter() { let item = tcx.hir.expect_item(item_id.id); @@ -3986,10 +3983,7 @@ pub fn path_to_def(tcx: &TyCtxt, path: &[&str]) -> Option { let mut path_it = path.iter().skip(1).peekable(); loop { - let segment = match path_it.next() { - Some(segment) => segment, - None => return None, - }; + let segment = path_it.next()?; for item in mem::replace(&mut items, Lrc::new(vec![])).iter() { if item.ident.name == *segment { diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs index 5263cfe7b0e4f..fa5d015e5b72d 100644 --- a/src/librustdoc/html/layout.rs +++ b/src/librustdoc/html/layout.rs @@ -57,6 +57,9 @@ pub fn render( {css_extension}\ {favicon}\ {in_header}\ + \ \ \ $DIR/borrowck-insert-during-each.rs:27:9 diff --git a/src/test/ui/existential_types/private_unused.rs b/src/test/ui/existential_types/private_unused.rs new file mode 100644 index 0000000000000..736d812bc0aff --- /dev/null +++ b/src/test/ui/existential_types/private_unused.rs @@ -0,0 +1,13 @@ +// compile-pass + +#[deny(warnings)] + +enum Empty { } +trait Bar {} +impl Bar for () {} + +fn boo() -> impl Bar {} + +fn main() { + boo(); +} diff --git a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr index 8dabb3c2505b6..60163d78e78f9 100644 --- a/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr +++ b/src/test/ui/generator/yield-while-ref-reborrowed.nll.stderr @@ -7,7 +7,7 @@ LL | let a = &mut *x; | - first borrow occurs due to use of `x` in generator ... LL | println!("{}", x); //~ ERROR - | ^ borrow occurs here + | ^ second borrow occurs here LL | b.resume(); | - first borrow later used here diff --git a/src/test/ui/nll/closure-borrow-spans.stderr b/src/test/ui/nll/closure-borrow-spans.stderr index 3e423dadd192c..98a261657b1e7 100644 --- a/src/test/ui/nll/closure-borrow-spans.stderr +++ b/src/test/ui/nll/closure-borrow-spans.stderr @@ -126,7 +126,7 @@ LL | let f = || *x = 0; | | | closure construction occurs here LL | let y = &x; //~ ERROR - | ^^ borrow occurs here + | ^^ second borrow occurs here LL | f.use_ref(); | - first borrow later used here @@ -138,7 +138,7 @@ LL | let f = || *x = 0; | | | closure construction occurs here LL | let y = &mut x; //~ ERROR - | ^^^^^^ borrow occurs here + | ^^^^^^ second borrow occurs here LL | f.use_ref(); | - first borrow later used here diff --git a/src/test/ui/nll/issue-55850.nll.stderr b/src/test/ui/nll/issue-55850.nll.stderr new file mode 100644 index 0000000000000..48aa2530cfbcb --- /dev/null +++ b/src/test/ui/nll/issue-55850.nll.stderr @@ -0,0 +1,18 @@ +error[E0597]: `s` does not live long enough + --> $DIR/issue-55850.rs:38:16 + | +LL | yield &s[..] + | ^ borrowed value does not live long enough +LL | }) + | - `s` dropped here while still borrowed + +error[E0626]: borrow may still be in use when generator yields + --> $DIR/issue-55850.rs:38:16 + | +LL | yield &s[..] + | -------^---- possible yield occurs here + +error: aborting due to 2 previous errors + +Some errors occurred: E0597, E0626. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/nll/issue-55850.rs b/src/test/ui/nll/issue-55850.rs new file mode 100644 index 0000000000000..f7745ba54d650 --- /dev/null +++ b/src/test/ui/nll/issue-55850.rs @@ -0,0 +1,44 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(unused_mut)] +#![feature(generators, generator_trait)] + +use std::ops::Generator; +use std::ops::GeneratorState::Yielded; + +pub struct GenIter(G); + +impl Iterator for GenIter +where + G: Generator, +{ + type Item = G::Yield; + + fn next(&mut self) -> Option { + unsafe { + match self.0.resume() { + Yielded(y) => Some(y), + _ => None + } + } + } +} + +fn bug<'a>() -> impl Iterator { + GenIter(move || { + let mut s = String::new(); + yield &s[..] + }) +} + +fn main() { + bug(); +} diff --git a/src/test/ui/nll/issue-55850.stderr b/src/test/ui/nll/issue-55850.stderr new file mode 100644 index 0000000000000..97ca1d358469c --- /dev/null +++ b/src/test/ui/nll/issue-55850.stderr @@ -0,0 +1,17 @@ +error[E0597]: `s` does not live long enough + --> $DIR/issue-55850.rs:38:16 + | +LL | yield &s[..] + | ^ borrowed value does not live long enough +LL | }) + | - borrowed value only lives until here + | +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 35:8... + --> $DIR/issue-55850.rs:35:8 + | +LL | fn bug<'a>() -> impl Iterator { + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.rs b/src/test/ui/rust-2018/dyn-trait-compatibility.rs index 9548df5959bd4..377c85fef490a 100644 --- a/src/test/ui/rust-2018/dyn-trait-compatibility.rs +++ b/src/test/ui/rust-2018/dyn-trait-compatibility.rs @@ -1,7 +1,7 @@ // edition:2018 type A0 = dyn; -type A1 = dyn::dyn; //~ERROR expected identifier, found reserved keyword +type A1 = dyn::dyn; //~ERROR expected identifier, found keyword `dyn` type A2 = dyn; //~ERROR expected identifier, found `<` type A3 = dyn<::dyn>; diff --git a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr index ea0483394b5ea..bd72f9c6786b2 100644 --- a/src/test/ui/rust-2018/dyn-trait-compatibility.stderr +++ b/src/test/ui/rust-2018/dyn-trait-compatibility.stderr @@ -1,8 +1,8 @@ -error: expected identifier, found reserved keyword `dyn` +error: expected identifier, found keyword `dyn` --> $DIR/dyn-trait-compatibility.rs:4:16 | -LL | type A1 = dyn::dyn; //~ERROR expected identifier, found reserved keyword - | ^^^ expected identifier, found reserved keyword +LL | type A1 = dyn::dyn; //~ERROR expected identifier, found keyword `dyn` + | ^^^ expected identifier, found keyword error: expected identifier, found `<` --> $DIR/dyn-trait-compatibility.rs:5:14 diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index bf95b31ae3ca4..d9834f9f0a004 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -606,7 +606,7 @@ impl Builder { let filename = path.file_name().unwrap().to_str().unwrap(); let sha256 = self.output.join(format!("{}.sha256", filename)); - t!(t!(File::create(&sha256)).write_all(&sha.stdout)); + t!(fs::write(&sha256, &sha.stdout)); let stdout = String::from_utf8_lossy(&sha.stdout); stdout.split_whitespace().next().unwrap().to_string() @@ -643,7 +643,7 @@ impl Builder { fn write(&self, contents: &str, channel_name: &str, suffix: &str) { let dst = self.output.join(format!("channel-rust-{}{}", channel_name, suffix)); - t!(t!(File::create(&dst)).write_all(contents.as_bytes())); + t!(fs::write(&dst, contents)); self.hash(&dst); self.sign(&dst); } diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 5b717c45254cc..ab74e7b7a7fd8 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -11,8 +11,7 @@ use std::env; use std::process::Command; use std::path::{Path, PathBuf}; -use std::fs::File; -use std::io::Write; +use std::fs; struct Test { repo: &'static str, @@ -91,10 +90,7 @@ fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) { println!("testing {}", test.repo); let dir = clone_repo(test, out_dir); if let Some(lockfile) = test.lock { - File::create(&dir.join("Cargo.lock")) - .expect("") - .write_all(lockfile.as_bytes()) - .expect(""); + fs::write(&dir.join("Cargo.lock"), lockfile).unwrap(); } if !run_cargo_test(cargo, &dir, test.packages) { panic!("tests failed for {}", test.repo); diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index dd2e5557c16d4..8d20a9e271705 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -119,10 +119,7 @@ fn parse_expected( line: &str, tag: &str, ) -> Option<(WhichLine, Error)> { - let start = match line.find(tag) { - Some(i) => i, - None => return None, - }; + let start = line.find(tag)?; let (follow, adjusts) = if line[start + tag.len()..].chars().next().unwrap() == '|' { (true, 0) } else { diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index ed2114b653015..f4a82aeb307dc 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -707,14 +707,8 @@ impl Config { fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> { if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match { - let from = match parse_normalization_string(&mut line) { - Some(s) => s, - None => return None, - }; - let to = match parse_normalization_string(&mut line) { - Some(s) => s, - None => return None, - }; + let from = parse_normalization_string(&mut line)?; + let to = parse_normalization_string(&mut line)?; Some((from, to)) } else { None @@ -873,14 +867,8 @@ fn expand_variables(mut value: String, config: &Config) -> String { /// ``` fn parse_normalization_string(line: &mut &str) -> Option { // FIXME support escapes in strings. - let begin = match line.find('"') { - Some(i) => i + 1, - None => return None, - }; - let end = match line[begin..].find('"') { - Some(i) => i + begin, - None => return None, - }; + let begin = line.find('"')? + 1; + let end = line[begin..].find('"')? + begin; let result = line[begin..end].to_owned(); *line = &line[end + 1..]; Some(result) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index f63950b448a14..65f6bff7eaf55 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -38,7 +38,7 @@ use getopts::Options; use std::env; use std::ffi::OsString; use std::fs; -use std::io::{self, Read}; +use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::process::Command; use test::ColorConfig; @@ -686,13 +686,11 @@ fn up_to_date( ) -> bool { let stamp_name = stamp(config, testpaths, revision); // Check hash. - let mut f = match fs::File::open(&stamp_name) { + let contents = match fs::read_to_string(&stamp_name) { Ok(f) => f, + Err(ref e) if e.kind() == ErrorKind::InvalidData => panic!("Can't read stamp contents"), Err(_) => return true, }; - let mut contents = String::new(); - f.read_to_string(&mut contents) - .expect("Can't read stamp contents"); let expected_hash = runtest::compute_stamp_hash(config); if contents != expected_hash { return true; diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index c654230e2032f..45527a7cce535 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -458,11 +458,7 @@ impl<'test> TestCx<'test> { None => 2, }; - let mut src = String::new(); - File::open(&self.testpaths.file) - .unwrap() - .read_to_string(&mut src) - .unwrap(); + let src = fs::read_to_string(&self.testpaths.file).unwrap(); let mut srcs = vec![src]; let mut round = 0; @@ -500,12 +496,7 @@ impl<'test> TestCx<'test> { let mut expected = match self.props.pp_exact { Some(ref file) => { let filepath = self.testpaths.file.parent().unwrap().join(file); - let mut s = String::new(); - File::open(&filepath) - .unwrap() - .read_to_string(&mut s) - .unwrap(); - s + fs::read_to_string(&filepath).unwrap() } None => srcs[srcs.len() - 2].clone(), }; @@ -1949,10 +1940,7 @@ impl<'test> TestCx<'test> { fn dump_output_file(&self, out: &str, extension: &str) { let outfile = self.make_out_name(extension); - File::create(&outfile) - .unwrap() - .write_all(out.as_bytes()) - .unwrap(); + fs::write(&outfile, out).unwrap(); } /// Create a filename for output with the given extension. Example: @@ -2149,11 +2137,7 @@ impl<'test> TestCx<'test> { path: &P, mut other_files: Option<&mut Vec>, ) -> Vec { - let mut file = - fs::File::open(path).expect("markdown_test_output_check_entry File::open failed"); - let mut content = String::new(); - file.read_to_string(&mut content) - .expect("markdown_test_output_check_entry read_to_string failed"); + let content = fs::read_to_string(&path).unwrap(); let mut ignore = false; content .lines() @@ -2826,11 +2810,7 @@ impl<'test> TestCx<'test> { } fn check_mir_dump(&self) { - let mut test_file_contents = String::new(); - fs::File::open(self.testpaths.file.clone()) - .unwrap() - .read_to_string(&mut test_file_contents) - .unwrap(); + let test_file_contents = fs::read_to_string(&self.testpaths.file).unwrap(); if let Some(idx) = test_file_contents.find("// END RUST SOURCE") { let (_, tests_text) = test_file_contents.split_at(idx + "// END_RUST SOURCE".len()); let tests_text_str = String::from(tests_text); @@ -2894,9 +2874,7 @@ impl<'test> TestCx<'test> { } self.check_mir_test_timestamp(test_name, &output_file); - let mut dumped_file = fs::File::open(output_file.clone()).unwrap(); - let mut dumped_string = String::new(); - dumped_file.read_to_string(&mut dumped_string).unwrap(); + let dumped_string = fs::read_to_string(&output_file).unwrap(); let mut dumped_lines = dumped_string .lines() .map(|l| nocomment_mir_line(l)) @@ -3108,19 +3086,13 @@ impl<'test> TestCx<'test> { } fn load_expected_output_from_path(&self, path: &Path) -> Result { - let mut result = String::new(); - match File::open(path).and_then(|mut f| f.read_to_string(&mut result)) { - Ok(_) => Ok(result), - Err(e) => Err(format!( - "failed to load expected output from `{}`: {}", - path.display(), - e - )), - } + fs::read_to_string(path).map_err(|err| { + format!("failed to load expected output from `{}`: {}", path.display(), err) + }) } fn delete_file(&self, file: &PathBuf) { - if let Err(e) = ::std::fs::remove_file(file) { + if let Err(e) = fs::remove_file(file) { self.fatal(&format!( "failed to delete `{}`: {}", file.display(), @@ -3182,16 +3154,13 @@ impl<'test> TestCx<'test> { for output_file in &files { if actual.is_empty() { self.delete_file(output_file); - } else { - match File::create(&output_file).and_then(|mut f| f.write_all(actual.as_bytes())) { - Ok(()) => {} - Err(e) => self.fatal(&format!( - "failed to write {} to `{}`: {}", - kind, - output_file.display(), - e - )), - } + } else if let Err(err) = fs::write(&output_file, &actual) { + self.fatal(&format!( + "failed to write {} to `{}`: {}", + kind, + output_file.display(), + err, + )); } } @@ -3243,9 +3212,8 @@ impl<'test> TestCx<'test> { } fn create_stamp(&self) { - let mut f = File::create(::stamp(&self.config, self.testpaths, self.revision)).unwrap(); - f.write_all(compute_stamp_hash(&self.config).as_bytes()) - .unwrap(); + let stamp = ::stamp(&self.config, self.testpaths, self.revision); + fs::write(&stamp, compute_stamp_hash(&self.config)).unwrap(); } } diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index a5556e1d570eb..03add412b6451 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -18,8 +18,8 @@ extern crate serialize as rustc_serialize; use std::collections::BTreeMap; use std::env; use std::error::Error; -use std::fs::{read_dir, File}; -use std::io::{Read, Write}; +use std::fs::{self, read_dir, File}; +use std::io::Write; use std::path::Path; use std::path::PathBuf; use std::cell::RefCell; @@ -210,8 +210,7 @@ fn load_all_errors(metadata_dir: &Path) -> Result Option { const REDIRECT: &'static str = "

Redirecting to bool { if !path.exists() { panic!("{} does not exist", path.display()); } - let mut contents = String::new(); - t!(t!(File::open(path)).read_to_string(&mut contents)); + let contents = t!(fs::read_to_string(&path)); let mut found_license = false; for line in contents.lines() { diff --git a/src/tools/tidy/src/extdeps.rs b/src/tools/tidy/src/extdeps.rs index a78d2d4ee4e15..377a7c33d75ae 100644 --- a/src/tools/tidy/src/extdeps.rs +++ b/src/tools/tidy/src/extdeps.rs @@ -10,8 +10,7 @@ // ! Check for external package sources. Allow only vendorable packages. -use std::fs::File; -use std::io::Read; +use std::fs; use std::path::Path; /// List of whitelisted sources for packages @@ -25,8 +24,7 @@ pub fn check(path: &Path, bad: &mut bool) { let path = path.join("../Cargo.lock"); // open and read the whole file - let mut cargo_lock = String::new(); - t!(t!(File::open(path)).read_to_string(&mut cargo_lock)); + let cargo_lock = t!(fs::read_to_string(&path)); // process each line for line in cargo_lock.lines() { diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 85b123e4af51f..b0bd5ba8dbdbd 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -20,7 +20,7 @@ use std::collections::HashMap; use std::fmt; -use std::fs::File; +use std::fs::{self, File}; use std::io::prelude::*; use std::path::Path; @@ -183,9 +183,7 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool { } pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features { - let mut contents = String::new(); - let path = base_src_path.join("libsyntax/feature_gate.rs"); - t!(t!(File::open(path)).read_to_string(&mut contents)); + let contents = t!(fs::read_to_string(base_src_path.join("libsyntax/feature_gate.rs"))); // we allow rustc-internal features to omit a tracking issue. // these features must be marked with `// rustc internal` in its own group.

", HDRS.len())?; write!(w, "{:?}", block.index())?; write!(w, "