From a8de713e26cb0f8e8ae4a7ecb0bf8a413b539926 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sun, 9 Aug 2020 13:25:18 +0200 Subject: [PATCH 01/18] Improve rendering of crate features via doc(cfg) --- src/librustdoc/clean/cfg.rs | 7 +++++++ src/test/rustdoc/duplicate-cfg.rs | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 53979d27052d3..20da28d1c5b98 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -413,6 +413,13 @@ impl<'a> fmt::Display for Html<'a> { return write!(fmt, "target feature {}", feat); } } + (sym::feature, Some(feat)) => { + if self.1 { + return write!(fmt, "{}", feat); + } else { + return write!(fmt, "crate feature {}", feat); + } + } _ => "", }; if !human_readable.is_empty() { diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs index 9ccc5d7882eb8..f6d4e9968a301 100644 --- a/src/test/rustdoc/duplicate-cfg.rs +++ b/src/test/rustdoc/duplicate-cfg.rs @@ -4,13 +4,13 @@ #![feature(doc_cfg)] // @has 'foo/struct.Foo.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.' #[doc(cfg(feature = "sync"))] #[doc(cfg(feature = "sync"))] pub struct Foo; // @has 'foo/bar/struct.Bar.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.' #[doc(cfg(feature = "sync"))] pub mod bar { #[doc(cfg(feature = "sync"))] @@ -18,7 +18,7 @@ pub mod bar { } // @has 'foo/baz/struct.Baz.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" and feature="send" only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send only.' #[doc(cfg(all(feature = "sync", feature = "send")))] pub mod baz { #[doc(cfg(feature = "sync"))] @@ -26,7 +26,7 @@ pub mod baz { } // @has 'foo/qux/struct.Qux.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" and feature="send" only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send only.' #[doc(cfg(feature = "sync"))] pub mod qux { #[doc(cfg(all(feature = "sync", feature = "send")))] @@ -34,7 +34,7 @@ pub mod qux { } // @has 'foo/quux/struct.Quux.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on feature="sync" and feature="send" and foo and bar only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send and foo and bar only.' #[doc(cfg(all(feature = "sync", feature = "send", foo)))] pub mod quux { #[doc(cfg(all(feature = "send", feature = "sync", bar)))] From 234ec956ab91d4aef51b63f25b78d176aa364a60 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sun, 9 Aug 2020 14:01:19 +0200 Subject: [PATCH 02/18] Render longhand multiple crate/target features nicer --- src/librustdoc/clean/cfg.rs | 51 +++++++++++++++++++++++++++++-- src/test/rustdoc/duplicate-cfg.rs | 4 +-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 20da28d1c5b98..3741d517f6afd 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -324,21 +324,68 @@ impl<'a> fmt::Display for Html<'a> { Cfg::Any(ref sub_cfgs) => { let separator = if sub_cfgs.iter().all(Cfg::is_simple) { " or " } else { ", or " }; + + let short_longhand = !self.1 && { + let all_crate_features = sub_cfgs + .iter() + .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); + let all_target_features = sub_cfgs + .iter() + .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_)))); + + if all_crate_features { + fmt.write_str("crate features ")?; + true + } else if all_target_features { + fmt.write_str("target features ")?; + true + } else { + false + } + }; + for (i, sub_cfg) in sub_cfgs.iter().enumerate() { if i != 0 { fmt.write_str(separator)?; } - write_with_opt_paren(fmt, !sub_cfg.is_all(), Html(sub_cfg, self.1))?; + if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { + write!(fmt, "{}", feat)?; + } else { + write_with_opt_paren(fmt, !sub_cfg.is_all(), Html(sub_cfg, self.1))?; + } } Ok(()) } Cfg::All(ref sub_cfgs) => { + let short_longhand = !self.1 && { + let all_crate_features = sub_cfgs + .iter() + .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); + let all_target_features = sub_cfgs + .iter() + .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::target_feature, Some(_)))); + + if all_crate_features { + fmt.write_str("crate features ")?; + true + } else if all_target_features { + fmt.write_str("target features ")?; + true + } else { + false + } + }; + for (i, sub_cfg) in sub_cfgs.iter().enumerate() { if i != 0 { fmt.write_str(" and ")?; } - write_with_opt_paren(fmt, !sub_cfg.is_simple(), Html(sub_cfg, self.1))?; + if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { + write!(fmt, "{}", feat)?; + } else { + write_with_opt_paren(fmt, !sub_cfg.is_simple(), Html(sub_cfg, self.1))?; + } } Ok(()) } diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs index f6d4e9968a301..99d02bc288c4a 100644 --- a/src/test/rustdoc/duplicate-cfg.rs +++ b/src/test/rustdoc/duplicate-cfg.rs @@ -18,7 +18,7 @@ pub mod bar { } // @has 'foo/baz/struct.Baz.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate features sync and send only.' #[doc(cfg(all(feature = "sync", feature = "send")))] pub mod baz { #[doc(cfg(feature = "sync"))] @@ -26,7 +26,7 @@ pub mod baz { } // @has 'foo/qux/struct.Qux.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send only.' +// @has '-' '//*[@class="stab portability"]' 'This is supported on crate features sync and send only.' #[doc(cfg(feature = "sync"))] pub mod qux { #[doc(cfg(all(feature = "sync", feature = "send")))] From 3328bd9a0f19b4c7bb8932b262583b8edf885338 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Tue, 18 Aug 2020 22:19:02 +0200 Subject: [PATCH 03/18] Add long cfg description to tooltip on short description --- src/librustdoc/clean/cfg.rs | 115 +++++++++++++++++++++--------- src/librustdoc/html/render/mod.rs | 10 +-- src/test/rustdoc/duplicate-cfg.rs | 18 ++++- 3 files changed, 105 insertions(+), 38 deletions(-) diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 3741d517f6afd..1839683b61004 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -135,7 +135,7 @@ impl Cfg { /// Renders the configuration for human display, as a short HTML description. pub(crate) fn render_short_html(&self) -> String { - let mut msg = Html(self, true).to_string(); + let mut msg = Display(self, Format::ShortHtml).to_string(); if self.should_capitalize_first_letter() { if let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric()) { msg[i..i + 1].make_ascii_uppercase(); @@ -148,7 +148,11 @@ impl Cfg { pub(crate) fn render_long_html(&self) -> String { let on = if self.should_use_with_in_description() { "with" } else { "on" }; - let mut msg = format!("This is supported {} {}", on, Html(self, false)); + let mut msg = format!( + "This is supported {} {}", + on, + Display(self, Format::LongHtml) + ); if self.should_append_only_to_description() { msg.push_str(" only"); } @@ -156,6 +160,17 @@ impl Cfg { msg } + /// Renders the configuration for long display, as a long plain text description. + pub(crate) fn render_long_plain(&self) -> String { + let on = if self.should_use_with_in_description() { "with" } else { "on" }; + + let mut msg = format!("This is supported {} {}", on, Display(self, Format::LongPlain)); + if self.should_append_only_to_description() { + msg.push_str(" only"); + } + msg + } + fn should_capitalize_first_letter(&self) -> bool { match *self { Cfg::False | Cfg::True | Cfg::Not(..) => true, @@ -286,9 +301,31 @@ impl ops::BitOr for Cfg { } } -/// Pretty-print wrapper for a `Cfg`. Also indicates whether the "short-form" rendering should be -/// used. -struct Html<'a>(&'a Cfg, bool); +#[derive(Clone, Copy)] +enum Format { + LongHtml, + LongPlain, + ShortHtml, +} + +impl Format { + fn is_long(self) -> bool { + match self { + Format::LongHtml | Format::LongPlain => true, + Format::ShortHtml => false, + } + } + + fn is_html(self) -> bool { + match self { + Format::LongHtml | Format::ShortHtml => true, + Format::LongPlain => false, + } + } +} + +/// Pretty-print wrapper for a `Cfg`. Also indicates what form of rendering should be used. +struct Display<'a>(&'a Cfg, Format); fn write_with_opt_paren( fmt: &mut fmt::Formatter<'_>, @@ -305,7 +342,7 @@ fn write_with_opt_paren( Ok(()) } -impl<'a> fmt::Display for Html<'a> { +impl<'a> fmt::Display for Display<'a> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match *self.0 { Cfg::Not(ref child) => match **child { @@ -314,18 +351,18 @@ impl<'a> fmt::Display for Html<'a> { if sub_cfgs.iter().all(Cfg::is_simple) { " nor " } else { ", nor " }; for (i, sub_cfg) in sub_cfgs.iter().enumerate() { fmt.write_str(if i == 0 { "neither " } else { separator })?; - write_with_opt_paren(fmt, !sub_cfg.is_all(), Html(sub_cfg, self.1))?; + write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?; } Ok(()) } - ref simple @ Cfg::Cfg(..) => write!(fmt, "non-{}", Html(simple, self.1)), - ref c => write!(fmt, "not ({})", Html(c, self.1)), + ref simple @ Cfg::Cfg(..) => write!(fmt, "non-{}", Display(simple, self.1)), + ref c => write!(fmt, "not ({})", Display(c, self.1)), }, Cfg::Any(ref sub_cfgs) => { let separator = if sub_cfgs.iter().all(Cfg::is_simple) { " or " } else { ", or " }; - let short_longhand = !self.1 && { + let short_longhand = self.1.is_long() && { let all_crate_features = sub_cfgs .iter() .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); @@ -349,16 +386,20 @@ impl<'a> fmt::Display for Html<'a> { fmt.write_str(separator)?; } if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { - write!(fmt, "{}", feat)?; + if self.1.is_html() { + write!(fmt, "{}", feat)?; + } else { + write!(fmt, "`{}`", feat)?; + } } else { - write_with_opt_paren(fmt, !sub_cfg.is_all(), Html(sub_cfg, self.1))?; + write_with_opt_paren(fmt, !sub_cfg.is_all(), Display(sub_cfg, self.1))?; } } Ok(()) } Cfg::All(ref sub_cfgs) => { - let short_longhand = !self.1 && { + let short_longhand = self.1.is_long() && { let all_crate_features = sub_cfgs .iter() .all(|sub_cfg| matches!(sub_cfg, Cfg::Cfg(sym::feature, Some(_)))); @@ -382,9 +423,13 @@ impl<'a> fmt::Display for Html<'a> { fmt.write_str(" and ")?; } if let (true, Cfg::Cfg(_, Some(feat))) = (short_longhand, sub_cfg) { - write!(fmt, "{}", feat)?; + if self.1.is_html() { + write!(fmt, "{}", feat)?; + } else { + write!(fmt, "`{}`", feat)?; + } } else { - write_with_opt_paren(fmt, !sub_cfg.is_simple(), Html(sub_cfg, self.1))?; + write_with_opt_paren(fmt, !sub_cfg.is_simple(), Display(sub_cfg, self.1))?; } } Ok(()) @@ -453,33 +498,39 @@ impl<'a> fmt::Display for Html<'a> { }, (sym::target_endian, Some(endian)) => return write!(fmt, "{}-endian", endian), (sym::target_pointer_width, Some(bits)) => return write!(fmt, "{}-bit", bits), - (sym::target_feature, Some(feat)) => { - if self.1 { - return write!(fmt, "{}", feat); - } else { + (sym::target_feature, Some(feat)) => match self.1 { + Format::LongHtml => { return write!(fmt, "target feature {}", feat); } - } - (sym::feature, Some(feat)) => { - if self.1 { - return write!(fmt, "{}", feat); - } else { + Format::LongPlain => return write!(fmt, "target feature `{}`", feat), + Format::ShortHtml => return write!(fmt, "{}", feat), + }, + (sym::feature, Some(feat)) => match self.1 { + Format::LongHtml => { return write!(fmt, "crate feature {}", feat); } - } + Format::LongPlain => return write!(fmt, "crate feature `{}`", feat), + Format::ShortHtml => return write!(fmt, "{}", feat), + }, _ => "", }; if !human_readable.is_empty() { fmt.write_str(human_readable) } else if let Some(v) = value { - write!( - fmt, - "{}=\"{}\"", - Escape(&name.as_str()), - Escape(&v.as_str()) - ) - } else { + if self.1.is_html() { + write!( + fmt, + r#"{}="{}""#, + Escape(&name.as_str()), + Escape(&v.as_str()) + ) + } else { + write!(fmt, r#"`{}="{}"`"#, name, v) + } + } else if self.1.is_html() { write!(fmt, "{}", Escape(&name.as_str())) + } else { + write!(fmt, "`{}`", name) } } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 5fb2d9f6f917c..de0964f530200 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2108,8 +2108,8 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean: fn stability_tags(item: &clean::Item) -> String { let mut tags = String::new(); - fn tag_html(class: &str, contents: &str) -> String { - format!(r#"{}"#, class, contents) + fn tag_html(class: &str, title: &str, contents: &str) -> String { + format!(r#"{}"#, class, Escape(title), contents) } // The trailing space after each tag is to space it properly against the rest of the docs. @@ -2118,7 +2118,7 @@ fn stability_tags(item: &clean::Item) -> String { if !stability::deprecation_in_effect(depr.is_since_rustc_version, depr.since.as_deref()) { message = "Deprecation planned"; } - tags += &tag_html("deprecated", message); + tags += &tag_html("deprecated", "", message); } // The "rustc_private" crates are permanently unstable so it makes no sense @@ -2129,11 +2129,11 @@ fn stability_tags(item: &clean::Item) -> String { .map(|s| s.level == stability::Unstable && s.feature.as_deref() != Some("rustc_private")) == Some(true) { - tags += &tag_html("unstable", "Experimental"); + tags += &tag_html("unstable", "", "Experimental"); } if let Some(ref cfg) = item.attrs.cfg { - tags += &tag_html("portability", &cfg.render_short_html()); + tags += &tag_html("portability", &cfg.render_long_plain(), &cfg.render_short_html()); } tags diff --git a/src/test/rustdoc/duplicate-cfg.rs b/src/test/rustdoc/duplicate-cfg.rs index 99d02bc288c4a..47ba362c97789 100644 --- a/src/test/rustdoc/duplicate-cfg.rs +++ b/src/test/rustdoc/duplicate-cfg.rs @@ -3,12 +3,20 @@ #![crate_name = "foo"] #![feature(doc_cfg)] +// @has 'foo/index.html' +// @matches '-' '//*[@class="module-item"]//*[@class="stab portability"]' '^sync$' +// @has '-' '//*[@class="module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate feature `sync` only' + // @has 'foo/struct.Foo.html' -// @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.' +// @has '-' '//*[@class="stab portability"]' 'sync' #[doc(cfg(feature = "sync"))] #[doc(cfg(feature = "sync"))] pub struct Foo; +// @has 'foo/bar/index.html' +// @matches '-' '//*[@class="module-item"]//*[@class="stab portability"]' '^sync$' +// @has '-' '//*[@class="module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate feature `sync` only' + // @has 'foo/bar/struct.Bar.html' // @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync only.' #[doc(cfg(feature = "sync"))] @@ -17,6 +25,10 @@ pub mod bar { pub struct Bar; } +// @has 'foo/baz/index.html' +// @matches '-' '//*[@class="module-item"]//*[@class="stab portability"]' '^sync and send$' +// @has '-' '//*[@class="module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate features `sync` and `send` only' + // @has 'foo/baz/struct.Baz.html' // @has '-' '//*[@class="stab portability"]' 'This is supported on crate features sync and send only.' #[doc(cfg(all(feature = "sync", feature = "send")))] @@ -33,6 +45,10 @@ pub mod qux { pub struct Qux; } +// @has 'foo/quux/index.html' +// @matches '-' '//*[@class="module-item"]//*[@class="stab portability"]' '^sync and send and foo and bar$' +// @has '-' '//*[@class="module-item"]//*[@class="stab portability"]/@title' 'This is supported on crate feature `sync` and crate feature `send` and `foo` and `bar` only' + // @has 'foo/quux/struct.Quux.html' // @has '-' '//*[@class="stab portability"]' 'This is supported on crate feature sync and crate feature send and foo and bar only.' #[doc(cfg(all(feature = "sync", feature = "send", foo)))] From 511ee052a0c2381bb2e6b3cecefb9ee69ebf2467 Mon Sep 17 00:00:00 2001 From: Camelid Date: Tue, 25 Aug 2020 16:53:33 -0700 Subject: [PATCH 04/18] Use intra-doc links in `core::macros` Also cleaned up some things and added a few more links. --- library/core/src/macros/mod.rs | 10 +++++----- library/core/src/macros/panic.md | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index d26f2124f15fd..4e0da1fc4a6a3 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -333,16 +333,16 @@ macro_rules! r#try { /// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be /// formatted according to the specified format string and the result will be passed to the writer. /// The writer may be any value with a `write_fmt` method; generally this comes from an -/// implementation of either the [`std::fmt::Write`] or the [`std::io::Write`] trait. The macro -/// returns whatever the `write_fmt` method returns; commonly a [`std::fmt::Result`], or an +/// implementation of either the [`fmt::Write`] or the [`io::Write`] trait. The macro +/// returns whatever the `write_fmt` method returns; commonly a [`fmt::Result`], or an /// [`io::Result`]. /// /// See [`std::fmt`] for more information on the format string syntax. /// /// [`std::fmt`]: crate::fmt -/// [`std::fmt::Write`]: crate::fmt::Write -/// [`std::io::Write`]: ../std/io/trait.Write.html -/// [`std::fmt::Result`]: crate::fmt::Result +/// [`fmt::Write`]: crate::fmt::Write +/// [`io::Write`]: ../std/io/trait.Write.html +/// [`fmt::Result`]: crate::fmt::Result /// [`io::Result`]: ../std/io/type.Result.html /// /// # Examples diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index 3ecfc43be049b..a02e74d5e5a4d 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -5,12 +5,12 @@ to the caller of the program. `panic!` should be used when a program reaches an unrecoverable state. This macro is the perfect way to assert conditions in example code and in -tests. `panic!` is closely tied with the `unwrap` method of both [`Option`] -and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set -to None or Err variants. +tests. `panic!` is closely tied with the `unwrap` method of both +[`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call +`panic!` when they are set to [`None`] or [`Err`] variants. This macro is used to inject panic into a Rust thread, causing the thread to -panic entirely. Each thread's panic can be reaped as the `Box` type, +panic entirely. Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, and the single-argument form of the `panic!` macro will be the value which is transmitted. @@ -24,11 +24,11 @@ The multi-argument form of this macro panics with a string and has the See also the macro [`compile_error!`], for raising errors during compilation. -[runwrap]: ../std/result/enum.Result.html#method.unwrap -[`Option`]: ../std/option/enum.Option.html#method.unwrap -[`Result`]: ../std/result/enum.Result.html +[ounwrap]: Option::unwrap +[runwrap]: Result::unwrap +[`Box`]: ../std/boxed/struct.Box.html +[`Any`]: crate::any::Any [`format!`]: ../std/macro.format.html -[`compile_error!`]: ../std/macro.compile_error.html [book]: ../book/ch09-00-error-handling.html # Current implementation From c73d4cddcc828a0822c29bf8649db3f5eb35c5ec Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 26 Aug 2020 14:51:02 +0200 Subject: [PATCH 05/18] Clean up E0761 explanation --- src/librustc_error_codes/error_codes/E0761.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0761.md b/src/librustc_error_codes/error_codes/E0761.md index c01574e413cfa..e112674fbcc49 100644 --- a/src/librustc_error_codes/error_codes/E0761.md +++ b/src/librustc_error_codes/error_codes/E0761.md @@ -2,24 +2,20 @@ Multiple candidate files were found for an out-of-line module. Erroneous code example: -```rust +```ignore (multiple source files required for compile_fail) // file: ambiguous_module/mod.rs fn foo() {} -``` -```rust // file: ambiguous_module.rs fn foo() {} -``` -```ignore (multiple source files required for compile_fail) +// file: lib.rs + mod ambiguous_module; // error: file for module `ambiguous_module` // found at both ambiguous_module.rs and // ambiguous_module.rs/mod.rs - -fn main() {} ``` Please remove this ambiguity by deleting/renaming one of the candidate files. From 0cca5978a454fe7087d0182a8bfa1372a6aae320 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 26 Aug 2020 17:02:24 +0300 Subject: [PATCH 06/18] Fix potential UB in align_offset docs --- library/core/src/ptr/const_ptr.rs | 2 +- library/core/src/ptr/mut_ptr.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index fc70dec16f618..d09cdb44e0837 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -836,7 +836,7 @@ impl *const T { /// # use std::mem::align_of; /// # unsafe { /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = &x[n] as *const u8; + /// let ptr = x.as_ptr().add(n) as *const u8; /// let offset = ptr.align_offset(align_of::()); /// if offset < x.len() - n - 1 { /// let u16_ptr = ptr.add(offset) as *const u16; diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 2d25f21e55c76..537aa20bf1dbc 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1094,7 +1094,7 @@ impl *mut T { /// # use std::mem::align_of; /// # unsafe { /// let x = [5u8, 6u8, 7u8, 8u8, 9u8]; - /// let ptr = &x[n] as *const u8; + /// let ptr = x.as_ptr().add(n) as *const u8; /// let offset = ptr.align_offset(align_of::()); /// if offset < x.len() - n - 1 { /// let u16_ptr = ptr.add(offset) as *const u16; From 16d8d4b899c8f23456027d0baec6ed83d256507c Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Wed, 26 Aug 2020 22:41:56 +0800 Subject: [PATCH 07/18] Error use explicit intra-doc link and fix text --- library/std/src/error.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 84e686c2fef81..9869ccec54638 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -33,15 +33,14 @@ use crate::string; /// themselves through the [`Display`] and [`Debug`] traits, and may provide /// cause chain information: /// -/// The [`source`] method is generally used when errors cross "abstraction -/// boundaries". If one module must report an error that is caused by an error -/// from a lower-level module, it can allow access to that error via the -/// [`source`] method. This makes it possible for the high-level module to -/// provide its own errors while also revealing some of the implementation for -/// debugging via [`source`] chains. +/// The [`Error::source`] method is generally used when errors cross +/// "abstraction boundaries". If one module must report an error that is caused +/// by an error from a lower-level module, it can allow accessing that error +/// via the [`Error::source`] method. This makes it possible for the high-level +/// module to provide its own errors while also revealing some of the +/// implementation for debugging via [`Error::source`] chains. /// /// [`Result`]: Result -/// [`source`]: Error::source #[stable(feature = "rust1", since = "1.0.0")] pub trait Error: Debug + Display { /// The lower-level source of this error, if any. @@ -636,7 +635,7 @@ impl dyn Error { } /// Returns an iterator starting with the current error and continuing with - /// recursively calling [`source`]. + /// recursively calling [`Error::source`]. /// /// If you want to omit the current error and only use its sources, /// use `skip(1)`. @@ -686,8 +685,6 @@ impl dyn Error { /// assert!(iter.next().is_none()); /// assert!(iter.next().is_none()); /// ``` - /// - /// [`source`]: Error::source #[unstable(feature = "error_iter", issue = "58520")] #[inline] pub fn chain(&self) -> Chain<'_> { From 9ea45935728651e985d70649a476ad89d0bee15e Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Wed, 26 Aug 2020 23:21:44 +0800 Subject: [PATCH 08/18] Use [xxx()] rather than the [xxx] function Co-authored-by: Joshua Nelson --- library/std/src/error.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 9869ccec54638..2c1aada8a4fab 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -33,10 +33,10 @@ use crate::string; /// themselves through the [`Display`] and [`Debug`] traits, and may provide /// cause chain information: /// -/// The [`Error::source`] method is generally used when errors cross +/// [`Error::source()`] is generally used when errors cross /// "abstraction boundaries". If one module must report an error that is caused /// by an error from a lower-level module, it can allow accessing that error -/// via the [`Error::source`] method. This makes it possible for the high-level +/// via [`Error::source()`]. This makes it possible for the high-level /// module to provide its own errors while also revealing some of the /// implementation for debugging via [`Error::source`] chains. /// From 39f5ebcd7401b050ca948a28db9bf105b9ca6a88 Mon Sep 17 00:00:00 2001 From: aticu <15schnic@gmail.com> Date: Thu, 27 Aug 2020 01:16:18 +0200 Subject: [PATCH 09/18] Fix typo in `std::hint::black_box` docs --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 461b4c79a1d1c..d40a380286762 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -101,7 +101,7 @@ pub fn spin_loop() { /// [`std::convert::identity`]: https://doc.rust-lang.org/core/convert/fn.identity.html /// /// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can -/// use `x` in any possible valid way that Rust code is allowed to without introducing undefined +/// use `dummy` in any possible valid way that Rust code is allowed to without introducing undefined /// behavior in the calling code. This property makes `black_box` useful for writing code in which /// certain optimizations are not desired, such as benchmarks. /// From ed9df28655607a17f01714b67930bdddba14fb26 Mon Sep 17 00:00:00 2001 From: kadmin Date: Thu, 27 Aug 2020 02:18:38 +0000 Subject: [PATCH 10/18] Fix ICE due to carriage return w/ multibyte char Based off of https://github.com/kfitch/rust/commit/972560b83f80e1219b5735ff3d751c034115b08e --- src/librustc_parse_format/lib.rs | 2 +- src/test/ui/issues/issue-70381.rs | 6 ++++++ src/test/ui/issues/issue-70381.stderr | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-70381.rs create mode 100644 src/test/ui/issues/issue-70381.stderr diff --git a/src/librustc_parse_format/lib.rs b/src/librustc_parse_format/lib.rs index ebb3aa3866e43..e07b8b86aef8e 100644 --- a/src/librustc_parse_format/lib.rs +++ b/src/librustc_parse_format/lib.rs @@ -760,7 +760,7 @@ fn find_skips_from_snippet( (' ' | '\n' | '\t', _) if eat_ws => { skips.push(pos); } - ('\\', Some((next_pos, 'n' | 't' | '0' | '\\' | '\'' | '\"'))) => { + ('\\', Some((next_pos, 'n' | 't' | 'r' | '0' | '\\' | '\'' | '\"'))) => { skips.push(*next_pos); let _ = s.next(); } diff --git a/src/test/ui/issues/issue-70381.rs b/src/test/ui/issues/issue-70381.rs new file mode 100644 index 0000000000000..3df8277b87372 --- /dev/null +++ b/src/test/ui/issues/issue-70381.rs @@ -0,0 +1,6 @@ +// Test that multi-byte unicode characters with missing parameters do not ICE. + +fn main() { + println!("\r¡{}") + //~^ ERROR 1 positional argument in format string +} diff --git a/src/test/ui/issues/issue-70381.stderr b/src/test/ui/issues/issue-70381.stderr new file mode 100644 index 0000000000000..96b8e656991c2 --- /dev/null +++ b/src/test/ui/issues/issue-70381.stderr @@ -0,0 +1,8 @@ +error: 1 positional argument in format string, but no arguments were given + --> $DIR/issue-70381.rs:4:16 + | +LL | println!("\r¡{}") + | ^^ + +error: aborting due to previous error + From 3a814f3f579d94938ebdbbd7d4508236d7b64233 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Thu, 27 Aug 2020 23:30:15 +0800 Subject: [PATCH 11/18] Reduce duplicate doc link in error Co-authored-by: Joshua Nelson --- library/std/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 2c1aada8a4fab..d3b0f8ceb68a6 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -38,7 +38,7 @@ use crate::string; /// by an error from a lower-level module, it can allow accessing that error /// via [`Error::source()`]. This makes it possible for the high-level /// module to provide its own errors while also revealing some of the -/// implementation for debugging via [`Error::source`] chains. +/// implementation for debugging via `source` chains. /// /// [`Result`]: Result #[stable(feature = "rust1", since = "1.0.0")] From df975cf9c27681da7751c12f19850e67940593df Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 27 Aug 2020 18:20:15 +0200 Subject: [PATCH 12/18] Rename rustdoc/test -> rustdoc/doctest This modules contains the implementation of doctests, and not the tests of rustdoc itself. This name is confusing, so let's rename it to doctest for clarity. --- src/librustdoc/{test.rs => doctest.rs} | 0 src/librustdoc/{test => doctest}/tests.rs | 0 src/librustdoc/html/markdown.rs | 6 +++--- src/librustdoc/lib.rs | 4 ++-- src/librustdoc/markdown.rs | 2 +- src/librustdoc/passes/doc_test_lints.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) rename src/librustdoc/{test.rs => doctest.rs} (100%) rename src/librustdoc/{test => doctest}/tests.rs (100%) diff --git a/src/librustdoc/test.rs b/src/librustdoc/doctest.rs similarity index 100% rename from src/librustdoc/test.rs rename to src/librustdoc/doctest.rs diff --git a/src/librustdoc/test/tests.rs b/src/librustdoc/doctest/tests.rs similarity index 100% rename from src/librustdoc/test/tests.rs rename to src/librustdoc/doctest/tests.rs diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b2589e5b806e8..56499f736e163 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -34,9 +34,9 @@ use std::fmt::Write; use std::ops::Range; use std::str; +use crate::doctest; use crate::html::highlight; use crate::html::toc::TocBuilder; -use crate::test; use pulldown_cmark::{html, CodeBlockKind, CowStr, Event, Options, Parser, Tag}; @@ -243,7 +243,7 @@ impl<'a, I: Iterator>> Iterator for CodeBlocks<'_, 'a, I> { .collect::>>() .join("\n"); let krate = krate.as_ref().map(|s| &**s); - let (test, _) = test::make_test(&test, krate, false, &Default::default(), edition); + let (test, _) = doctest::make_test(&test, krate, false, &Default::default(), edition); let channel = if test.contains("#![feature(") { "&version=nightly" } else { "" }; let edition_string = format!("&edition={}", edition); @@ -568,7 +568,7 @@ impl<'a, I: Iterator>> Iterator for Footnotes<'a, I> { } } -pub fn find_testable_code( +pub fn find_testable_code( doc: &str, tests: &mut T, error_codes: ErrorCodes, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b5e246b5d17a5..8658b39b45578 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -64,13 +64,13 @@ mod docfs; mod doctree; #[macro_use] mod error; +mod doctest; mod fold; crate mod formats; pub mod html; mod json; mod markdown; mod passes; -mod test; mod theme; mod visit_ast; mod visit_lib; @@ -476,7 +476,7 @@ fn main_options(options: config::Options) -> MainResult { match (options.should_test, options.markdown_input()) { (true, true) => return wrap_return(&diag, markdown::test(options)), - (true, false) => return test::run(options), + (true, false) => return doctest::run(options), (false, true) => { return wrap_return( &diag, diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs index 89d184e35cb06..3a87e1c46a615 100644 --- a/src/librustdoc/markdown.rs +++ b/src/librustdoc/markdown.rs @@ -7,10 +7,10 @@ use rustc_span::edition::Edition; use rustc_span::source_map::DUMMY_SP; use crate::config::{Options, RenderOptions}; +use crate::doctest::{Collector, TestOptions}; use crate::html::escape::Escape; use crate::html::markdown; use crate::html::markdown::{find_testable_code, ErrorCodes, IdMap, Markdown, MarkdownWithToc}; -use crate::test::{Collector, TestOptions}; /// Separate any lines at the start of the file that begin with `# ` or `%`. fn extract_leading_metadata(s: &str) -> (Vec<&str>, &str) { diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index 367f93cfd3893..cbbe86dc433f3 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -54,7 +54,7 @@ impl Tests { } } -impl crate::test::Tester for Tests { +impl crate::doctest::Tester for Tests { fn add_test(&mut self, _: String, _: LangString, _: usize) { self.found_tests += 1; } From c933d697d826dc917161881bdb651eedd6ca5ffc Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 26 Aug 2020 12:25:19 -0700 Subject: [PATCH 13/18] Use intra-doc links in `core::future::future` --- library/core/src/future/future.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index d9b91acc3ad7b..e279d80112a73 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -23,7 +23,7 @@ use crate::task::{Context, Poll}; /// When using a future, you generally won't call `poll` directly, but instead /// `.await` the value. /// -/// [`Waker`]: ../task/struct.Waker.html +/// [`Waker`]: crate::task::Waker #[doc(spotlight)] #[must_use = "futures do nothing unless you `.await` or poll them"] #[stable(feature = "futures_api", since = "1.36.0")] @@ -91,11 +91,10 @@ pub trait Future { /// (memory corruption, incorrect use of `unsafe` functions, or the like), /// regardless of the future's state. /// - /// [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending - /// [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready - /// [`Context`]: ../task/struct.Context.html - /// [`Waker`]: ../task/struct.Waker.html - /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake + /// [`Poll::Pending`]: Poll::Pending + /// [`Poll::Ready(val)`]: Poll::Ready + /// [`Waker`]: crate::task::Waker + /// [`Waker::wake`]: crate::task::Waker::wake #[lang = "poll"] #[stable(feature = "futures_api", since = "1.36.0")] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; From 707298d52c2d4ef831a7987013f5a5517218c1ef Mon Sep 17 00:00:00 2001 From: Camelid Date: Wed, 26 Aug 2020 12:26:26 -0700 Subject: [PATCH 14/18] Use intra-doc links in `core::num::dec2flt` --- library/core/src/num/dec2flt/mod.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index c83c6b0eccbc7..ed6202bb82f0f 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -166,10 +166,6 @@ from_str_float_impl!(f64); /// /// This error is used as the error type for the [`FromStr`] implementation /// for [`f32`] and [`f64`]. -/// -/// [`FromStr`]: ../str/trait.FromStr.html -/// [`f32`]: ../../std/primitive.f32.html -/// [`f64`]: ../../std/primitive.f64.html #[derive(Debug, Clone, PartialEq, Eq)] #[stable(feature = "rust1", since = "1.0.0")] pub struct ParseFloatError { From 65b37ce09093ea9a657ac37dd24db2f6343d6710 Mon Sep 17 00:00:00 2001 From: tinaun Date: Thu, 27 Aug 2020 14:41:18 -0400 Subject: [PATCH 15/18] fix wording in release notes C-like enums are still allowed to impl drop, you just can't cast them to numbers --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 37aed7735455b..64fe2df3c496c 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -51,7 +51,7 @@ Compatibility Notes ------------------- - [The target configuration option `abi_blacklist` has been renamed to `unsupported_abis`.][74150] The old name will still continue to work. -- [Rustc will now warn if you have a C-like enum that implements `Drop`.][72331] +- [Rustc will now warn if you cast a C-like enum that implements `Drop`.][72331] This was previously accepted but will become a hard error in a future release. - [Rustc will fail to compile if you have a struct with `#[repr(i128)]` or `#[repr(u128)]`.][74109] This representation is currently only From dd96996c7091c5c382e52e5faeacc2ef3288e9ec Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 27 Aug 2020 11:52:36 -0700 Subject: [PATCH 16/18] Add InstrProfilingPlatformFuchsia.c to profiler_builtins All other Platform files included in `llvm-project/compiler-rt` were present, except Fuchsia. Now that there is a functional end-to-end version of `-Zinstrument-coverage`, I need to start building and testing coverage-enabled Rust programs on Fuchsia, and this file is required. --- library/profiler_builtins/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/profiler_builtins/build.rs b/library/profiler_builtins/build.rs index b674f73ebf390..2a5d5853fec64 100644 --- a/library/profiler_builtins/build.rs +++ b/library/profiler_builtins/build.rs @@ -20,6 +20,7 @@ fn main() { "InstrProfilingMergeFile.c", "InstrProfilingNameVar.c", "InstrProfilingPlatformDarwin.c", + "InstrProfilingPlatformFuchsia.c", "InstrProfilingPlatformLinux.c", "InstrProfilingPlatformOther.c", "InstrProfilingPlatformWindows.c", From 55cd2433dc2f5025137a96d65bf681dd64b6f7f7 Mon Sep 17 00:00:00 2001 From: Rich Kadel Date: Thu, 27 Aug 2020 12:27:18 -0700 Subject: [PATCH 17/18] Adds --bless support to test/run-make-fulldeps The ability to "bless" output for some of these tests is critical to making it practical to adapt tests to unrelated changes. This is needed for new coverage tests, as shown in PR #75828 (or its derivative). --- src/tools/compiletest/src/runtest.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 124a9adcab91a..965b20f5202e0 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2782,6 +2782,18 @@ impl<'test> TestCx<'test> { cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static").env("IS_MUSL_HOST", "1"); } + if self.config.bless { + cmd.env("RUSTC_BLESS_TEST", "--bless"); + // Assume this option is active if the environment variable is "defined", with _any_ value. + // As an example, a `Makefile` can use this option by: + // + // ifdef RUSTC_BLESS_TEST + // cp "$(TMPDIR)"/actual_something.ext expected_something.ext + // else + // $(DIFF) expected_something.ext "$(TMPDIR)"/actual_something.ext + // endif + } + if self.config.target.contains("msvc") && self.config.cc != "" { // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe` // and that `lib.exe` lives next to it. From 39cd1846061a15905469cd99f22868a7935c8a03 Mon Sep 17 00:00:00 2001 From: Camelid <37223377+camelid@users.noreply.github.com> Date: Thu, 27 Aug 2020 19:42:23 -0700 Subject: [PATCH 18/18] Remove unnecessary intra-doc link Co-authored-by: Joshua Nelson --- library/core/src/future/future.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index e279d80112a73..e9a99ddb6b1bd 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -91,7 +91,6 @@ pub trait Future { /// (memory corruption, incorrect use of `unsafe` functions, or the like), /// regardless of the future's state. /// - /// [`Poll::Pending`]: Poll::Pending /// [`Poll::Ready(val)`]: Poll::Ready /// [`Waker`]: crate::task::Waker /// [`Waker::wake`]: crate::task::Waker::wake