diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 800952f7a5ece..77994a3f3a14a 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1859,6 +1859,18 @@ where B: ToOwned + ?Sized, Rc: From<&'a B> + From, { + /// Create a reference-counted pointer from + /// a clone-on-write pointer by copying its content. + /// + /// # Example + /// + /// ```rust + /// # use std::rc::Rc; + /// # use std::borrow::Cow; + /// let cow: Cow = Cow::Borrowed("eggplant"); + /// let shared: Rc = Rc::from(cow); + /// assert_eq!("eggplant", &shared[..]); + /// ``` #[inline] fn from(cow: Cow<'a, B>) -> Rc { match cow { diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 17927f5f5fdc4..72001ad1b5633 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2413,6 +2413,18 @@ where B: ToOwned + ?Sized, Arc: From<&'a B> + From, { + /// Create an atomically reference-counted pointer from + /// a clone-on-write pointer by copying its content. + /// + /// # Example + /// + /// ```rust + /// # use std::sync::Arc; + /// # use std::borrow::Cow; + /// let cow: Cow = Cow::Borrowed("eggplant"); + /// let shared: Arc = Arc::from(cow); + /// assert_eq!("eggplant", &shared[..]); + /// ``` #[inline] fn from(cow: Cow<'a, B>) -> Arc { match cow { diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index f99eb9777d8ac..9d9398fb56d8a 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -187,9 +187,8 @@ impl ControlFlow { #[cfg(bootstrap)] impl ControlFlow { /// Create a `ControlFlow` from any type implementing `Try`. - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn from_try(r: R) -> Self { + pub(crate) fn from_try(r: R) -> Self { match R::into_result(r) { Ok(v) => ControlFlow::Continue(v), Err(v) => ControlFlow::Break(R::from_error(v)), @@ -197,9 +196,8 @@ impl ControlFlow { } /// Convert a `ControlFlow` into any type implementing `Try`; - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn into_try(self) -> R { + pub(crate) fn into_try(self) -> R { match self { ControlFlow::Continue(v) => R::from_ok(v), ControlFlow::Break(v) => v, @@ -207,12 +205,14 @@ impl ControlFlow { } } +/// These are used only as part of implementing the iterator adapters. +/// They have mediocre names and non-obvious semantics, so aren't +/// currently on a path to potential stabilization. #[cfg(not(bootstrap))] impl ControlFlow { /// Create a `ControlFlow` from any type implementing `Try`. - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn from_try(r: R) -> Self { + pub(crate) fn from_try(r: R) -> Self { match R::branch(r) { ControlFlow::Continue(v) => ControlFlow::Continue(v), ControlFlow::Break(v) => ControlFlow::Break(R::from_residual(v)), @@ -220,9 +220,8 @@ impl ControlFlow { } /// Convert a `ControlFlow` into any type implementing `Try`; - #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] #[inline] - pub fn into_try(self) -> R { + pub(crate) fn into_try(self) -> R { match self { ControlFlow::Continue(v) => R::from_output(v), ControlFlow::Break(v) => v, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 0923175414edd..3bcea4e6d25ed 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -3096,7 +3096,11 @@ impl [T] { // SAFETY: the conditions for `ptr::copy` have all been checked above, // as have those for `ptr::add`. unsafe { - ptr::copy(self.as_ptr().add(src_start), self.as_mut_ptr().add(dest), count); + // Derive both `src_ptr` and `dest_ptr` from the same loan + let ptr = self.as_mut_ptr(); + let src_ptr = ptr.add(src_start); + let dest_ptr = ptr.add(dest); + ptr::copy(src_ptr, dest_ptr, count); } } diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 9b629e19be53d..a8261709cea9f 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1,11 +1,3 @@ -#![unstable( - feature = "ip", - reason = "extra functionality has not been \ - scrutinized to the level that it should \ - be to be stable", - issue = "27709" -)] - // Tests for this module #[cfg(all(test, not(target_os = "emscripten")))] mod tests; @@ -126,6 +118,7 @@ pub struct Ipv6Addr { #[allow(missing_docs)] #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)] +#[unstable(feature = "ip", issue = "27709")] pub enum Ipv6MulticastScope { InterfaceLocal, LinkLocal, @@ -199,6 +192,7 @@ impl IpAddr { /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1)).is_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ip", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_global(&self) -> bool { match self { @@ -249,6 +243,7 @@ impl IpAddr { /// ); /// ``` #[rustc_const_unstable(feature = "const_ip", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_documentation(&self) -> bool { match self { @@ -549,6 +544,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_global(&self) -> bool { // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two @@ -587,6 +583,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_shared(&self) -> bool { self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000) @@ -620,6 +617,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_ietf_protocol_assignment(&self) -> bool { self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0 @@ -644,6 +642,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_benchmarking(&self) -> bool { self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18 @@ -677,6 +676,7 @@ impl Ipv4Addr { /// assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false); /// ``` #[rustc_const_unstable(feature = "const_ipv4", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_reserved(&self) -> bool { self.octets()[0] & 240 == 240 && !self.is_broadcast() @@ -1234,6 +1234,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0x1c9, 0, 0, 0xafc8, 0, 0x1).is_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_global(&self) -> bool { match self.multicast_scope() { @@ -1260,6 +1261,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 @@ -1315,6 +1317,7 @@ impl Ipv6Addr { /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_link_local_strict(&self) -> bool { matches!(self.segments(), [0xfe80, 0, 0, 0, ..]) @@ -1369,6 +1372,7 @@ impl Ipv6Addr { /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4 /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406 #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 @@ -1409,6 +1413,7 @@ impl Ipv6Addr { /// /// [RFC 3879]: https://tools.ietf.org/html/rfc3879 #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_site_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfec0 @@ -1432,6 +1437,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 0).is_documentation(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_documentation(&self) -> bool { (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) @@ -1468,6 +1474,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_global(), true); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn is_unicast_global(&self) -> bool { !self.is_multicast() @@ -1494,6 +1501,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).multicast_scope(), None); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn multicast_scope(&self) -> Option { if self.is_multicast() { @@ -1555,6 +1563,7 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1).to_ipv4_mapped(), None); /// ``` #[rustc_const_unstable(feature = "const_ipv6", issue = "76205")] + #[unstable(feature = "ip", issue = "27709")] #[inline] pub const fn to_ipv4_mapped(&self) -> Option { match self.octets() { diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index 773ab18b2ce65..e7c5479ab9bb6 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -294,8 +294,14 @@ impl Mutex { /// # Errors /// /// If another user of this mutex panicked while holding the mutex, then - /// this call will return an error if the mutex would otherwise be - /// acquired. + /// this call will return the [`Poisoned`] error if the mutex would + /// otherwise be acquired. + /// + /// If the mutex could not be acquired because it is already locked, then + /// this call will return the [`WouldBlock`] error. + /// + /// [`Poisoned`]: TryLockError::Poisoned + /// [`WouldBlock`]: TryLockError::WouldBlock /// /// # Examples /// diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index b01bcec1361d7..9d521ab14cbf3 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -199,11 +199,17 @@ impl RwLock { /// /// # Errors /// - /// This function will return an error if the RwLock is poisoned. An RwLock - /// is poisoned whenever a writer panics while holding an exclusive lock. An - /// error will only be returned if the lock would have otherwise been + /// This function will return the [`Poisoned`] error if the RwLock is poisoned. + /// An RwLock is poisoned whenever a writer panics while holding an exclusive + /// lock. `Poisoned` will only be returned if the lock would have otherwise been /// acquired. /// + /// This function will return the [`WouldBlock`] error if the RwLock could not + /// be acquired because it was already locked exclusively. + /// + /// [`Poisoned`]: TryLockError::Poisoned + /// [`WouldBlock`]: TryLockError::WouldBlock + /// /// # Examples /// /// ``` @@ -281,10 +287,17 @@ impl RwLock { /// /// # Errors /// - /// This function will return an error if the RwLock is poisoned. An RwLock - /// is poisoned whenever a writer panics while holding an exclusive lock. An - /// error will only be returned if the lock would have otherwise been - /// acquired. + /// This function will return the [`Poisoned`] error if the RwLock is + /// poisoned. An RwLock is poisoned whenever a writer panics while holding + /// an exclusive lock. `Poisoned` will only be returned if the lock would have + /// otherwise been acquired. + /// + /// This function will return the [`WouldBlock`] error if the RwLock could not + /// be acquired because it was already locked exclusively. + /// + /// [`Poisoned`]: TryLockError::Poisoned + /// [`WouldBlock`]: TryLockError::WouldBlock + /// /// /// # Examples /// diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index bd5b3797ea825..149a899cef7a0 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -991,20 +991,28 @@ def update_submodules(self): ).decode(default_encoding).splitlines()] filtered_submodules = [] submodules_names = [] + llvm_checked_out = os.path.exists(os.path.join(self.rust_root, "src/llvm-project/.git")) + external_llvm_provided = self.get_toml('llvm-config') or self.downloading_llvm() + llvm_needed = not self.get_toml('codegen-backends', 'rust') \ + or "llvm" in self.get_toml('codegen-backends', 'rust') for module in submodules: - # This is handled by native::Llvm in rustbuild, not here if module.endswith("llvm-project"): - continue + # Don't sync the llvm-project submodule if an external LLVM was + # provided, if we are downloading LLVM or if the LLVM backend is + # not being built. Also, if the submodule has been initialized + # already, sync it anyways so that it doesn't mess up contributor + # pull requests. + if external_llvm_provided or not llvm_needed: + if self.get_toml('lld') != 'true' and not llvm_checked_out: + continue check = self.check_submodule(module, slow_submodules) filtered_submodules.append((module, check)) submodules_names.append(module) recorded = subprocess.Popen(["git", "ls-tree", "HEAD"] + submodules_names, cwd=self.rust_root, stdout=subprocess.PIPE) recorded = recorded.communicate()[0].decode(default_encoding).strip().splitlines() - # { filename: hash } recorded_submodules = {} for data in recorded: - # [mode, kind, hash, filename] data = data.split() recorded_submodules[data[3]] = data[2] for module in filtered_submodules: diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index a351290a4206f..2960dd3df6bf4 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -472,22 +472,12 @@ impl Build { slice::from_ref(&self.build.triple) } - /// If the LLVM submodule has been initialized already, sync it unconditionally. This avoids - /// contributors checking in a submodule change by accident. - pub fn maybe_update_llvm_submodule(&self) { - if self.in_tree_llvm_info.is_git() { - native::update_llvm_submodule(self); - } - } - /// Executes the entire build, as configured by the flags and configuration. pub fn build(&mut self) { unsafe { job::setup(self); } - self.maybe_update_llvm_submodule(); - if let Subcommand::Format { check, paths } = &self.config.cmd { return format::format(self, *check, &paths); } diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 44c281efe22be..bde0a96f03013 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -21,7 +21,7 @@ use build_helper::{output, t}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::util::{self, exe}; -use crate::{Build, GitRepo}; +use crate::GitRepo; use build_helper::up_to_date; pub struct Meta { @@ -91,85 +91,6 @@ pub fn prebuilt_llvm_config( Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() }) } -// modified from `check_submodule` and `update_submodule` in bootstrap.py -pub(crate) fn update_llvm_submodule(build: &Build) { - let llvm_project = &Path::new("src").join("llvm-project"); - - fn dir_is_empty(dir: &Path) -> bool { - t!(std::fs::read_dir(dir)).next().is_none() - } - - // NOTE: The check for the empty directory is here because when running x.py - // the first time, the llvm submodule won't be checked out. Check it out - // now so we can build it. - if !build.in_tree_llvm_info.is_git() && !dir_is_empty(&build.config.src.join(llvm_project)) { - return; - } - - // check_submodule - let checked_out = if build.config.fast_submodules { - Some(output( - Command::new("git") - .args(&["rev-parse", "HEAD"]) - .current_dir(build.config.src.join(llvm_project)), - )) - } else { - None - }; - - // update_submodules - let recorded = output( - Command::new("git") - .args(&["ls-tree", "HEAD"]) - .arg(llvm_project) - .current_dir(&build.config.src), - ); - let hash = - recorded.split(' ').nth(2).unwrap_or_else(|| panic!("unexpected output `{}`", recorded)); - - // update_submodule - if let Some(llvm_hash) = checked_out { - if hash == llvm_hash { - // already checked out - return; - } - } - - println!("Updating submodule {}", llvm_project.display()); - build.run( - Command::new("git") - .args(&["submodule", "-q", "sync"]) - .arg(llvm_project) - .current_dir(&build.config.src), - ); - - // Try passing `--progress` to start, then run git again without if that fails. - let update = |progress: bool| { - let mut git = Command::new("git"); - git.args(&["submodule", "update", "--init", "--recursive"]); - if progress { - git.arg("--progress"); - } - git.arg(llvm_project).current_dir(&build.config.src); - git - }; - // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails. - if !update(true).status().map_or(false, |status| status.success()) { - build.run(&mut update(false)); - } - - build.run( - Command::new("git") - .args(&["reset", "-q", "--hard"]) - .current_dir(build.config.src.join(llvm_project)), - ); - build.run( - Command::new("git") - .args(&["clean", "-qdfx"]) - .current_dir(build.config.src.join(llvm_project)), - ); -} - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Llvm { pub target: TargetSelection, @@ -207,9 +128,6 @@ impl Step for Llvm { Err(m) => m, }; - if !builder.config.dry_run { - update_llvm_submodule(builder); - } if builder.config.llvm_link_shared && (target.contains("windows") || target.contains("apple-darwin")) { diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 98b5bfd3b980a..64e4be6863a62 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -217,9 +217,8 @@ impl Step for ToolBuild { if tool == "tidy" { tool = "rust-tidy"; } - let cargo_out = - builder.cargo_out(compiler, self.mode, target).join(exe(tool, compiler.host)); - let bin = builder.tools_dir(compiler).join(exe(tool, compiler.host)); + let cargo_out = builder.cargo_out(compiler, self.mode, target).join(exe(tool, target)); + let bin = builder.tools_dir(compiler).join(exe(tool, target)); builder.copy(&cargo_out, &bin); Some(bin) } diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index b1ec072f3f8aa..80f804174ed08 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -130,7 +130,6 @@ pub fn make(host: &str) -> PathBuf { } } -#[track_caller] pub fn output(cmd: &mut Command) -> String { let output = match cmd.stderr(Stdio::inherit()).output() { Ok(status) => status, diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 1da3c411f17ad..302a115e8f718 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 1da3c411f17adb1ba5de1683bb6acee83362b54a +Subproject commit 302a115e8f71876dfc884aebb0ca5ccb02b8a962 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 569c3391f5c0c..7349d173fa28a 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 569c3391f5c0cc43433bc77831d17f8ff4d76602 +Subproject commit 7349d173fa28a0bb834cf0264a05286620ef0923 diff --git a/src/doc/reference b/src/doc/reference index 5aa457bf1b54b..9c68af3ce6ccc 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 5aa457bf1b54bd2cd5d4cf49797f29299bdf89a7 +Subproject commit 9c68af3ce6ccca2395e1868addef26a0542e9ddd diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 5f8c6da200ada..805e016c5792a 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 5f8c6da200ada77760a2fe1096938ef58151c9a6 +Subproject commit 805e016c5792ad2adabb66e348233067d5ea9f10 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 1e6c7fbda4c45..50de7f0682adc 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 1e6c7fbda4c45e85adf63ff3f82fa9c870b1447f +Subproject commit 50de7f0682adc5d95ce858fe6318d19b4b951553 diff --git a/src/doc/rustdoc/src/how-to-write-documentation.md b/src/doc/rustdoc/src/how-to-write-documentation.md index 688be7aedea38..f89495cca3a31 100644 --- a/src/doc/rustdoc/src/how-to-write-documentation.md +++ b/src/doc/rustdoc/src/how-to-write-documentation.md @@ -229,15 +229,13 @@ Example: ```md - [x] Complete task -- [ ] IncComplete task +- [ ] Incomplete task ``` -This will render as +This will render as: -
    -
  • -
  • -
+> - [x] Complete task +> - [ ] Incomplete task See the specification for the [task list extension] for more details. diff --git a/src/etc/gdb_lookup.py b/src/etc/gdb_lookup.py index a5a1824c84e78..292e91b4d5d61 100644 --- a/src/etc/gdb_lookup.py +++ b/src/etc/gdb_lookup.py @@ -5,7 +5,6 @@ from rust_types import * -rust_enabled = 'set language rust' in gdb.execute('complete set language ru', to_string=True) _gdb_version_matched = re.search('([0-9]+)\\.([0-9]+)', gdb.VERSION) gdb_version = [int(num) for num in _gdb_version_matched.groups()] if _gdb_version_matched else [] @@ -52,9 +51,10 @@ def lookup(valobj): return StdStringProvider(valobj) if rust_type == RustType.STD_OS_STRING: return StdOsStringProvider(valobj) - if rust_type == RustType.STD_STR and not rust_enabled: + if rust_type == RustType.STD_STR: return StdStrProvider(valobj) - + if rust_type == RustType.STD_SLICE: + return StdSliceProvider(valobj) if rust_type == RustType.STD_VEC: return StdVecProvider(valobj) if rust_type == RustType.STD_VEC_DEQUE: diff --git a/src/etc/gdb_providers.py b/src/etc/gdb_providers.py index f0ce13b269c59..0c46962794c75 100644 --- a/src/etc/gdb_providers.py +++ b/src/etc/gdb_providers.py @@ -85,6 +85,31 @@ def to_string(self): def display_hint(): return "string" +class StdSliceProvider: + def __init__(self, valobj): + self.valobj = valobj + self.length = int(valobj["length"]) + self.data_ptr = valobj["data_ptr"] + + def to_string(self): + return "{}(size={})".format(self.valobj.type, self.length) + + def children(self): + for index in xrange(self.length): + element_ptr = self.data_ptr + index + try: + # rust-lang/rust#64343: passing deref expr to `str` allows + # catching exception on garbage pointer + str(element_ptr.dereference()) + yield "[{}]".format(index), element_ptr.dereference() + except RuntimeError: + yield str(index), "inaccessible" + + break + + @staticmethod + def display_hint(): + return "array" class StdVecProvider: def __init__(self, valobj): diff --git a/src/etc/lldb_commands b/src/etc/lldb_commands index b8e6c6c0c89f1..4a1204ccc4be7 100644 --- a/src/etc/lldb_commands +++ b/src/etc/lldb_commands @@ -1,7 +1,7 @@ type synthetic add -l lldb_lookup.synthetic_lookup -x ".*" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)String$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^&str$" --category Rust -type summary add -F lldb_lookup.summary_lookup -e -x -h "^&\\[.+\\]$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?str$" --category Rust +type summary add -F lldb_lookup.summary_lookup -e -x -h "^&(mut )?\\[.+\\]$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(std::ffi::([a-z_]+::)+)OsString$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)VecDeque<.+>$" --category Rust diff --git a/src/etc/rust_types.py b/src/etc/rust_types.py index b49fd19ed4cbb..bbc945a7ddab0 100644 --- a/src/etc/rust_types.py +++ b/src/etc/rust_types.py @@ -34,8 +34,8 @@ class RustType(object): STD_STRING_REGEX = re.compile(r"^(alloc::(\w+::)+)String$") -STD_STR_REGEX = re.compile(r"^&str$") -STD_SLICE_REGEX = re.compile(r"^&\[.+\]$") +STD_STR_REGEX = re.compile(r"^&(mut )?str$") +STD_SLICE_REGEX = re.compile(r"^&(mut )?\[.+\]$") STD_OS_STRING_REGEX = re.compile(r"^(std::ffi::(\w+::)+)OsString$") STD_VEC_REGEX = re.compile(r"^(alloc::(\w+::)+)Vec<.+>$") STD_VEC_DEQUE_REGEX = re.compile(r"^(alloc::(\w+::)+)VecDeque<.+>$") diff --git a/src/test/debuginfo/pretty-huge-vec.rs b/src/test/debuginfo/pretty-huge-vec.rs index 67155b4e9f09e..84f76ba4e6e06 100644 --- a/src/test/debuginfo/pretty-huge-vec.rs +++ b/src/test/debuginfo/pretty-huge-vec.rs @@ -13,7 +13,7 @@ // gdb-check:$1 = Vec(size=1000000000) = {[...]...} // gdb-command: print slice -// gdb-check:$2 = &[u8] {data_ptr: [...], length: 1000000000} +// gdb-check:$2 = &[u8](size=1000000000) = {[...]...} #![allow(unused_variables)] diff --git a/src/test/debuginfo/pretty-slices.rs b/src/test/debuginfo/pretty-slices.rs new file mode 100644 index 0000000000000..aafd467740115 --- /dev/null +++ b/src/test/debuginfo/pretty-slices.rs @@ -0,0 +1,43 @@ +// compile-flags:-g + +// gdb-command: run + +// gdb-command: print slice +// gdb-check: $1 = &[i32](size=3) = {0, 1, 2} + +// gdb-command: print mut_slice +// gdb-check: $2 = &mut [i32](size=4) = {2, 3, 5, 7} + +// gdb-command: print str_slice +// gdb-check: $3 = "string slice" + +// gdb-command: print mut_str_slice +// gdb-check: $4 = "mutable string slice" + +// lldb-command: run + +// lldb-command: print slice +// lldb-check: (&[i32]) $0 = size=3 { [0] = 0 [1] = 1 [2] = 2 } + +// lldb-command: print mut_slice +// lldb-check: (&mut [i32]) $1 = size=4 { [0] = 2 [1] = 3 [2] = 5 [3] = 7 } + +// lldb-command: print str_slice +// lldb-check: (&str) $2 = "string slice" { data_ptr = [...] length = 12 } + +// lldb-command: print mut_str_slice +// lldb-check: (&mut str) $3 = "mutable string slice" { data_ptr = [...] length = 20 } + +fn b() {} + +fn main() { + + let slice: &[i32] = &[0, 1, 2]; + let mut_slice: &mut [i32] = &mut [2, 3, 5, 7]; + + let str_slice: &str = "string slice"; + let mut mut_str_slice_buffer = String::from("mutable string slice"); + let mut_str_slice: &mut str = mut_str_slice_buffer.as_mut_str(); + + b(); // #break +} diff --git a/src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr b/src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr deleted file mode 100644 index 8282bc3db0507..0000000000000 --- a/src/test/ui/cast/cast-ptr-to-int-const.with_feature.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block - --> $DIR/cast-ptr-to-int-const.rs:16:9 - | -LL | &Y as *const u32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int - | - = note: casting pointers to integers in constants - -error[E0133]: cast of pointer to int is unsafe and requires unsafe function or block - --> $DIR/cast-ptr-to-int-const.rs:23:5 - | -LL | &0 as *const i32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ cast of pointer to int - | - = note: casting pointers to integers in constants - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr b/src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr deleted file mode 100644 index c87fa1a14a4c8..0000000000000 --- a/src/test/ui/cast/cast-ptr-to-int-const.without_feature.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/cast-ptr-to-int-const.rs:8:9 - | -LL | main as usize - | ^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/cast-ptr-to-int-const.rs:12:9 - | -LL | &Y as *const u32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/cast-ptr-to-int-const.rs:16:9 - | -LL | &Y as *const u32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error[E0658]: casting pointers to integers in constant functions is unstable - --> $DIR/cast-ptr-to-int-const.rs:23:5 - | -LL | &0 as *const i32 as usize - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51910 for more information - = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/tools/cargo b/src/tools/cargo index 070e459c2d8b7..e931e4796b61d 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 070e459c2d8b79c5b2ac5218064e7603329c92ae +Subproject commit e931e4796b61de593aa1097649445e535c9c7ee0 diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 54b079a3e8610..02bd2087868ea 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1125,8 +1125,8 @@ impl<'test> TestCx<'test> { let rust_type_regexes = vec![ "^(alloc::([a-z_]+::)+)String$", - "^&str$", - "^&\\[.+\\]$", + "^&(mut )?str$", + "^&(mut )?\\[.+\\]$", "^(std::ffi::([a-z_]+::)+)OsString$", "^(alloc::([a-z_]+::)+)Vec<.+>$", "^(alloc::([a-z_]+::)+)VecDeque<.+>$",