From 112a3473d046c7f2e677de2b71259649b9e4b9fd Mon Sep 17 00:00:00 2001 From: Kinrany Date: Sat, 20 Jul 2019 23:12:57 +0300 Subject: [PATCH 01/11] Fix theme picker blur handler: always hide instead of switching --- src/librustdoc/html/render.rs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3cd520fd4b50b..c5cc04b9af555 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -874,15 +874,23 @@ fn write_shared( r#"var themes = document.getElementById("theme-choices"); var themePicker = document.getElementById("theme-picker"); +function showThemeButtonState() {{ + themes.style.display = "none"; + themePicker.style.borderBottomRightRadius = "3px"; + themePicker.style.borderBottomLeftRadius = "3px"; +}} + +function hideThemeButtonState() {{ + themes.style.display = "block"; + themePicker.style.borderBottomRightRadius = "0"; + themePicker.style.borderBottomLeftRadius = "0"; +}} + function switchThemeButtonState() {{ if (themes.style.display === "block") {{ - themes.style.display = "none"; - themePicker.style.borderBottomRightRadius = "3px"; - themePicker.style.borderBottomLeftRadius = "3px"; + showThemeButtonState(); }} else {{ - themes.style.display = "block"; - themePicker.style.borderBottomRightRadius = "0"; - themePicker.style.borderBottomLeftRadius = "0"; + hideThemeButtonState(); }} }}; @@ -895,7 +903,7 @@ function handleThemeButtonsBlur(e) {{ (!related || (related.id !== "themePicker" && (!related.parentNode || related.parentNode.id !== "theme-choices")))) {{ - switchThemeButtonState(); + hideThemeButtonState(); }} }} From 3e39ac718809c147141d4b6ed02b5db4a6779397 Mon Sep 17 00:00:00 2001 From: Kinrany Date: Sat, 20 Jul 2019 23:40:30 +0300 Subject: [PATCH 02/11] Update render.rs --- src/librustdoc/html/render.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c5cc04b9af555..3234889ca7cda 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -885,7 +885,7 @@ function hideThemeButtonState() {{ themePicker.style.borderBottomRightRadius = "0"; themePicker.style.borderBottomLeftRadius = "0"; }} - + function switchThemeButtonState() {{ if (themes.style.display === "block") {{ showThemeButtonState(); From 2e41ba8742c341eaf1ec1b5954e089e4d2c02dd0 Mon Sep 17 00:00:00 2001 From: Tim Vermeulen Date: Sat, 6 Jul 2019 23:22:20 +0200 Subject: [PATCH 03/11] Use internal iteration in the Sum and Product impls of Result and Option --- src/libcore/iter/adapters/mod.rs | 146 ++++++++----------------------- src/libcore/iter/mod.rs | 2 +- src/libcore/iter/traits/accum.rs | 10 +-- src/libcore/option.rs | 7 +- src/libcore/result.rs | 4 +- src/libcore/tests/iter.rs | 17 ++++ 6 files changed, 67 insertions(+), 119 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 8eae52ffd3277..2a8286d29b80c 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2063,137 +2063,65 @@ impl ExactSizeIterator for Inspect impl FusedIterator for Inspect where F: FnMut(&I::Item) {} -/// An iterator adapter that produces output as long as the underlying -/// iterator produces `Option::Some` values. -pub(crate) struct OptionShunt { - iter: I, - exited_early: bool, -} - -impl OptionShunt -where - I: Iterator>, -{ - /// Process the given iterator as if it yielded a `T` instead of a - /// `Option`. Any `None` value will stop the inner iterator and - /// the overall result will be a `None`. - pub fn process(iter: I, mut f: F) -> Option - where - F: FnMut(&mut Self) -> U, - { - let mut shunt = OptionShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - OptionShunt { - iter, - exited_early: false, - } - } - - /// Consume the adapter and rebuild a `Option` value. - fn reconstruct(self, val: U) -> Option { - if self.exited_early { - None - } else { - Some(val) - } - } -} - -impl Iterator for OptionShunt -where - I: Iterator>, -{ - type Item = T; - - fn next(&mut self) -> Option { - match self.iter.next() { - Some(Some(v)) => Some(v), - Some(None) => { - self.exited_early = true; - None - } - None => None, - } - } - - fn size_hint(&self) -> (usize, Option) { - if self.exited_early { - (0, Some(0)) - } else { - let (_, upper) = self.iter.size_hint(); - (0, upper) - } - } -} - /// An iterator adapter that produces output as long as the underlying /// iterator produces `Result::Ok` values. /// /// If an error is encountered, the iterator stops and the error is -/// stored. The error may be recovered later via `reconstruct`. -pub(crate) struct ResultShunt { +/// stored. +pub(crate) struct ResultShunt<'a, I, E> { iter: I, - error: Option, + error: &'a mut Result<(), E>, } -impl ResultShunt - where I: Iterator> +/// Process the given iterator as if it yielded a `T` instead of a +/// `Result`. Any errors will stop the inner iterator and +/// the overall result will be an error. +pub(crate) fn process_results(iter: I, mut f: F) -> Result +where + I: Iterator>, + for<'a> F: FnMut(ResultShunt<'a, I, E>) -> U, { - /// Process the given iterator as if it yielded a `T` instead of a - /// `Result`. Any errors will stop the inner iterator and - /// the overall result will be an error. - pub fn process(iter: I, mut f: F) -> Result - where F: FnMut(&mut Self) -> U - { - let mut shunt = ResultShunt::new(iter); - let value = f(shunt.by_ref()); - shunt.reconstruct(value) - } - - fn new(iter: I) -> Self { - ResultShunt { - iter, - error: None, - } - } - - /// Consume the adapter and rebuild a `Result` value. This should - /// *always* be called, otherwise any potential error would be - /// lost. - fn reconstruct(self, val: U) -> Result { - match self.error { - None => Ok(val), - Some(e) => Err(e), - } - } + let mut error = Ok(()); + let shunt = ResultShunt { + iter, + error: &mut error, + }; + let value = f(shunt); + error.map(|()| value) } -impl Iterator for ResultShunt +impl Iterator for ResultShunt<'_, I, E> where I: Iterator> { type Item = T; fn next(&mut self) -> Option { - match self.iter.next() { - Some(Ok(v)) => Some(v), - Some(Err(e)) => { - self.error = Some(e); - None - } - None => None, - } + self.find(|_| true) } fn size_hint(&self) -> (usize, Option) { - if self.error.is_some() { + if self.error.is_err() { (0, Some(0)) } else { let (_, upper) = self.iter.size_hint(); (0, upper) } } + + fn try_fold(&mut self, init: B, mut f: F) -> R + where + F: FnMut(B, Self::Item) -> R, + R: Try, + { + let error = &mut *self.error; + self.iter + .try_fold(init, |acc, x| match x { + Ok(x) => LoopState::from_try(f(acc, x)), + Err(e) => { + *error = Err(e); + LoopState::Break(Try::from_ok(acc)) + } + }) + .into_try() + } } diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 4a7d7f96b9b04..aba8e84d58be5 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -360,7 +360,7 @@ pub use self::adapters::Flatten; #[stable(feature = "iter_copied", since = "1.36.0")] pub use self::adapters::Copied; -pub(crate) use self::adapters::{TrustedRandomAccess, OptionShunt, ResultShunt}; +pub(crate) use self::adapters::{TrustedRandomAccess, process_results}; mod range; mod sources; diff --git a/src/libcore/iter/traits/accum.rs b/src/libcore/iter/traits/accum.rs index 01b64fb08acf7..812463e77f976 100644 --- a/src/libcore/iter/traits/accum.rs +++ b/src/libcore/iter/traits/accum.rs @@ -1,6 +1,6 @@ use crate::ops::{Mul, Add}; use crate::num::Wrapping; -use crate::iter::adapters::{OptionShunt, ResultShunt}; +use crate::iter; /// Trait to represent types that can be created by summing up an iterator. /// @@ -139,7 +139,7 @@ impl Sum> for Result fn sum(iter: I) -> Result where I: Iterator>, { - ResultShunt::process(iter, |i| i.sum()) + iter::process_results(iter, |i| i.sum()) } } @@ -153,7 +153,7 @@ impl Product> for Result fn product(iter: I) -> Result where I: Iterator>, { - ResultShunt::process(iter, |i| i.product()) + iter::process_results(iter, |i| i.product()) } } @@ -180,7 +180,7 @@ where where I: Iterator>, { - OptionShunt::process(iter, |i| i.sum()) + iter.map(|x| x.ok_or(())).sum::>().ok() } } @@ -196,6 +196,6 @@ where where I: Iterator>, { - OptionShunt::process(iter, |i| i.product()) + iter.map(|x| x.ok_or(())).product::>().ok() } } diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 70a87cfe5a78a..693ec0053223e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -135,7 +135,7 @@ #![stable(feature = "rust1", since = "1.0.0")] -use crate::iter::{FromIterator, FusedIterator, TrustedLen, OptionShunt}; +use crate::iter::{FromIterator, FusedIterator, TrustedLen}; use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}}; use crate::pin::Pin; @@ -1499,7 +1499,10 @@ impl> FromIterator> for Option { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. - OptionShunt::process(iter.into_iter(), |i| i.collect()) + iter.into_iter() + .map(|x| x.ok_or(())) + .collect::>() + .ok() } } diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 559877ddd5a1c..8c60a9c1b501d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -231,7 +231,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::fmt; -use crate::iter::{FromIterator, FusedIterator, TrustedLen, ResultShunt}; +use crate::iter::{self, FromIterator, FusedIterator, TrustedLen}; use crate::ops::{self, Deref, DerefMut}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). @@ -1343,7 +1343,7 @@ impl> FromIterator> for Result { // FIXME(#11084): This could be replaced with Iterator::scan when this // performance bug is closed. - ResultShunt::process(iter.into_iter(), |i| i.collect()) + iter::process_results(iter.into_iter(), |i| i.collect()) } } diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b7b0849e2129b..31530cc2c94c4 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1082,6 +1082,23 @@ fn test_iterator_sum_result() { assert_eq!(v.iter().cloned().sum::>(), Ok(10)); let v: &[Result] = &[Ok(1), Err(()), Ok(3), Ok(4)]; assert_eq!(v.iter().cloned().sum::>(), Err(())); + + #[derive(PartialEq, Debug)] + struct S(Result); + + impl Sum> for S { + fn sum>>(mut iter: I) -> Self { + // takes the sum by repeatedly calling `next` on `iter`, + // thus testing that repeated calls to `ResultShunt::try_fold` + // produce the expected results + Self(iter.by_ref().sum()) + } + } + + let v: &[Result] = &[Ok(1), Ok(2), Ok(3), Ok(4)]; + assert_eq!(v.iter().cloned().sum::(), S(Ok(10))); + let v: &[Result] = &[Ok(1), Err(()), Ok(3), Ok(4)]; + assert_eq!(v.iter().cloned().sum::(), S(Err(()))); } #[test] From d05c4d545963bbddb18062a8cc5a9ac489374d5e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 31 Jul 2019 15:04:25 -0700 Subject: [PATCH 04/11] Deduplicate rustc_demangle in librustc_codegen_llvm This commit removes the crates.io dependency of `rustc-demangle` from `rustc_codegen_llvm`. This crate is actually already pulled in to part of the `librustc_driver` build and with the upcoming pipelining implementation in Cargo it causes build issues if `rustc-demangle` is left to its own devices. This is not currently required, but once pipelining is enabled for rustc's own build it will be required to build correctly. --- Cargo.lock | 1 - src/librustc_codegen_llvm/Cargo.toml | 1 - src/librustc_codegen_llvm/lib.rs | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53f8ae0b09b17..efed009aa2ae0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2783,7 +2783,6 @@ dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_llvm 0.0.0", "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml index 291d32a06814d..5e1b0eafdec36 100644 --- a/src/librustc_codegen_llvm/Cargo.toml +++ b/src/librustc_codegen_llvm/Cargo.toml @@ -14,7 +14,6 @@ test = false cc = "1.0.1" # Used to locate MSVC num_cpus = "1.0" tempfile = "3.0" -rustc-demangle = "0.1.15" rustc_llvm = { path = "../librustc_llvm" } memmap = "0.6" diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index a630817fb3386..653dd8868f479 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -25,6 +25,7 @@ use back::write::{create_target_machine, create_informational_target_machine}; use syntax_pos::symbol::Symbol; +extern crate rustc_demangle; extern crate flate2; #[macro_use] extern crate bitflags; extern crate libc; From 18130ef044cfa83af341c4a3500ab576f8cc4c38 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 5 Aug 2019 10:21:25 -0400 Subject: [PATCH 05/11] Replace error callback with Result --- src/librustc_resolve/lib.rs | 47 +++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 1a203e73f0a86..3dd1d7d274d5a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1771,8 +1771,13 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { path: &ast::Path, is_value: bool, ) -> Res { - self.resolve_ast_path_cb(path, is_value, - |resolver, span, error| resolve_error(resolver, span, error)) + match self.resolve_ast_path_inner(path, is_value) { + Ok(r) => r, + Err((span, error)) => { + resolve_error(self, span, error); + Res::Err + } + } } fn resolve_str_path( @@ -1833,8 +1838,6 @@ impl<'a> Resolver<'a> { /// just that an error occurred. pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool) -> Result<(ast::Path, Res), ()> { - let mut errored = false; - let path = if path_str.starts_with("::") { ast::Path { span, @@ -1855,24 +1858,24 @@ impl<'a> Resolver<'a> { .collect(), } }; - let res = self.resolve_ast_path_cb(&path, is_value, |_, _, _| errored = true); - if errored || res == def::Res::Err { - Err(()) - } else { - Ok((path, res)) + match self.resolve_ast_path_inner(&path, is_value) { + Ok(res) => { + if res == Res::Err { + Err(()) + } else { + Ok((path, res)) + } + } + Err(_) => Err(()), } } /// Like `resolve_ast_path`, but takes a callback in case there was an error. - // FIXME(eddyb) use `Result` or something instead of callbacks. - fn resolve_ast_path_cb( + fn resolve_ast_path_inner( &mut self, path: &ast::Path, is_value: bool, - error_callback: F, - ) -> Res - where F: for<'c, 'b> FnOnce(&'c mut Resolver<'_>, Span, ResolutionError<'b>) - { + ) -> Result)> { let namespace = if is_value { ValueNS } else { TypeNS }; let span = path.span; let path = Segment::from_path(&path); @@ -1880,23 +1883,21 @@ impl<'a> Resolver<'a> { match self.resolve_path_without_parent_scope(&path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => - module.res().unwrap(), + Ok(module.res().unwrap()), PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => - path_res.base_res(), + Ok(path_res.base_res()), PathResult::NonModule(..) => { - error_callback(self, span, ResolutionError::FailedToResolve { + Err((span, ResolutionError::FailedToResolve { label: String::from("type-relative paths are not supported in this context"), suggestion: None, - }); - Res::Err + })) } PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), PathResult::Failed { span, label, suggestion, .. } => { - error_callback(self, span, ResolutionError::FailedToResolve { + Err((span, ResolutionError::FailedToResolve { label, suggestion, - }); - Res::Err + })) } } } From 3cd7f08ed1f801c2fa4983d9eef9162739922373 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 5 Aug 2019 12:25:32 -0400 Subject: [PATCH 06/11] Force callers of resolve_ast_path to deal with Res::Err correctly --- src/librustc_resolve/lib.rs | 12 ++---------- src/librustdoc/passes/collect_intra_doc_links.rs | 7 +++++++ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 3dd1d7d274d5a..ba70355899879 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1858,16 +1858,8 @@ impl<'a> Resolver<'a> { .collect(), } }; - match self.resolve_ast_path_inner(&path, is_value) { - Ok(res) => { - if res == Res::Err { - Err(()) - } else { - Ok((path, res)) - } - } - Err(_) => Err(()), - } + let res = self.resolve_ast_path_inner(&path, is_value).map_err(|_| ())?; + Ok((path, res)) } /// Like `resolve_ast_path`, but takes a callback in case there was an error. diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 04de3374d0587..84cfdd790b733 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -71,6 +71,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { resolver.resolve_str_path_error(DUMMY_SP, &path_str, ns == ValueNS) }) }); + let result = match result { + Ok((_, Res::Err)) => Err(()), + _ => result, + }; if let Ok((_, res)) = result { let res = res.map_id(|_| panic!("unexpected node_id")); @@ -134,6 +138,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let (_, ty_res) = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| { resolver.resolve_str_path_error(DUMMY_SP, &path, false) }))?; + if let Res::Err = ty_res { + return Err(()); + } let ty_res = ty_res.map_id(|_| panic!("unexpected node_id")); match ty_res { Res::Def(DefKind::Struct, did) From e1875742d024c9ac52889d26881ca39a2a14cd8e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 5 Aug 2019 20:13:59 +0200 Subject: [PATCH 07/11] assume_init: warn about valid != safe --- src/libcore/mem/maybe_uninit.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 64fdf504369f2..20367f724b6f3 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -402,6 +402,13 @@ impl MaybeUninit { /// /// [inv]: #initialization-invariant /// + /// On top of that, remember that most types have additional invariants beyond merely + /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] + /// is considered initialized because the only requirement the compiler knows about it + /// is that the data pointer must be non-null. Creating such a `Vec` does not cause + /// *immediate* undefined behavior, but will cause undefined behavior with most + /// safe operations (including dropping it). + /// /// # Examples /// /// Correct usage of this method: From d89bf91b2d804a773f9c56cdbfcfe25cf573c848 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 18 Jul 2019 23:38:23 +0200 Subject: [PATCH 08/11] Display methods from DerefMut in the sidebar as well --- src/librustdoc/html/render.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2774f2b4751ba..ea0ebe4710079 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4579,12 +4579,13 @@ fn get_methods( i: &clean::Impl, for_deref: bool, used_links: &mut FxHashSet, + deref_mut: bool, ) -> Vec { i.items.iter().filter_map(|item| { match item.name { // Maybe check with clean::Visibility::Public as well? Some(ref name) if !name.is_empty() && item.visibility.is_some() && item.is_method() => { - if !for_deref || should_render_item(item, false) { + if !for_deref || should_render_item(item, deref_mut) { Some(format!("{}", get_next_url(used_links, format!("method.{}", name)), name)) @@ -4625,7 +4626,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_none()) .flat_map(move |i| get_methods(i.inner_impl(), false, - &mut used_links_bor.borrow_mut())) + &mut used_links_bor.borrow_mut(), false)) .collect::>(); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); @@ -4659,7 +4660,8 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_none()) .flat_map(|i| get_methods(i.inner_impl(), true, - &mut used_links)) + &mut used_links, + true)) .collect::>(); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); From 4fb29f9fd2758a5c07328fc12aa771bb239f9450 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 6 Aug 2019 00:41:52 +0200 Subject: [PATCH 09/11] Add test for DerefMut methods --- src/test/rustdoc/deref-mut-methods.rs | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/rustdoc/deref-mut-methods.rs diff --git a/src/test/rustdoc/deref-mut-methods.rs b/src/test/rustdoc/deref-mut-methods.rs new file mode 100644 index 0000000000000..0e27fc90b69a6 --- /dev/null +++ b/src/test/rustdoc/deref-mut-methods.rs @@ -0,0 +1,29 @@ +#![crate_name = "foo"] + +use std::ops; + +pub struct Foo; + +impl Foo { + pub fn foo(&mut self) {} +} + +// @has foo/struct.Bar.html +// @has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo' +pub struct Bar { + foo: Foo, +} + +impl ops::Deref for Bar { + type Target = Foo; + + fn deref(&self) -> &Foo { + &self.foo + } +} + +impl ops::DerefMut for Bar { + fn deref_mut(&mut self) -> &mut Foo { + &mut self.foo + } +} From 1b9eb4ac4cb5ecc5a16a1ed781a88af4c65bfc2f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Aug 2019 09:47:42 +0200 Subject: [PATCH 10/11] be clear that 1-init Vec being valid (but not safe) is not a stable guarantee --- src/libcore/mem/maybe_uninit.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 20367f724b6f3..43c4b491ac89d 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -51,7 +51,8 @@ use crate::mem::ManuallyDrop; /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] -/// is considered initialized because the only requirement the compiler knows about it +/// is considered initialized (under the current implementation, this does not constitute +/// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most /// safe operations (including dropping it). @@ -404,7 +405,8 @@ impl MaybeUninit { /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] - /// is considered initialized because the only requirement the compiler knows about it + /// is considered initialized (under the current implementation, this does not constitute + /// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most /// safe operations (including dropping it). From 1821414b7bb496545ef147644cf5691db433ab5d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 6 Aug 2019 10:41:48 +0200 Subject: [PATCH 11/11] clarify --- src/libcore/mem/maybe_uninit.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/mem/maybe_uninit.rs b/src/libcore/mem/maybe_uninit.rs index 43c4b491ac89d..ff063759cba62 100644 --- a/src/libcore/mem/maybe_uninit.rs +++ b/src/libcore/mem/maybe_uninit.rs @@ -51,7 +51,7 @@ use crate::mem::ManuallyDrop; /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] -/// is considered initialized (under the current implementation, this does not constitute +/// is considered initialized (under the current implementation; this does not constitute /// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most @@ -405,7 +405,7 @@ impl MaybeUninit { /// /// On top of that, remember that most types have additional invariants beyond merely /// being considered initialized at the type level. For example, a `1`-initialized [`Vec`] - /// is considered initialized (under the current implementation, this does not constitute + /// is considered initialized (under the current implementation; this does not constitute /// a stable guarantee) because the only requirement the compiler knows about it /// is that the data pointer must be non-null. Creating such a `Vec` does not cause /// *immediate* undefined behavior, but will cause undefined behavior with most