From a297631bdcc7742b55cf5961fcbc505e91217c7d Mon Sep 17 00:00:00 2001 From: KaDiWa Date: Fri, 19 Aug 2022 18:53:27 +0200 Subject: [PATCH 01/11] use <[u8]>::escape_ascii instead of core::ascii::escape_default --- compiler/rustc_ast/src/util/literal.rs | 7 +----- compiler/rustc_codegen_ssa/src/back/link.rs | 25 +++++++------------- compiler/rustc_middle/src/mir/mod.rs | 10 +------- compiler/rustc_middle/src/ty/print/pretty.rs | 9 +------ library/core/src/ffi/c_str.rs | 9 ++----- library/proc_macro/src/lib.rs | 7 +----- library/std/src/os/unix/net/addr.rs | 16 ++----------- 7 files changed, 16 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index e6351d89c6c31..8b84631ea76ae 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -164,12 +164,7 @@ impl LitKind { } LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None), LitKind::ByteStr(ref bytes) => { - let string = bytes - .iter() - .cloned() - .flat_map(ascii::escape_default) - .map(Into::::into) - .collect::(); + let string = bytes.escape_ascii().to_string(); (token::ByteStr, Symbol::intern(&string), None) } LitKind::Byte(byte) => { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7f6947e3c79d8..5be7fec230c7b 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -44,7 +44,7 @@ use std::io::{BufWriter, Write}; use std::ops::Deref; use std::path::{Path, PathBuf}; use std::process::{ExitStatus, Output, Stdio}; -use std::{ascii, char, env, fmt, fs, io, mem, str}; +use std::{env, fmt, fs, io, mem, str}; pub fn ensure_removed(diag_handler: &Handler, path: &Path) { if let Err(e) = fs::remove_file(path) { @@ -552,14 +552,6 @@ fn link_staticlib<'a>( Ok(()) } -fn escape_stdout_stderr_string(s: &[u8]) -> String { - str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { - let mut x = "Non-UTF-8 output: ".to_string(); - x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); - x - }) -} - /// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a /// DWARF package. fn link_dwarf_object<'a>( @@ -866,7 +858,7 @@ fn link_natively<'a>( if !prog.status.success() { let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); - let escaped_output = escape_stdout_stderr_string(&output); + let escaped_output = escape_string(&output); let mut err = sess.struct_err(&format!( "linking with `{}` failed: {}", linker_path.display(), @@ -934,8 +926,8 @@ fn link_natively<'a>( sess.abort_if_errors(); } - info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr)); - info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout)); + info!("linker stderr:\n{}", escape_string(&prog.stderr)); + info!("linker stdout:\n{}", escape_string(&prog.stdout)); } Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; @@ -1065,11 +1057,10 @@ fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Opti } fn escape_string(s: &[u8]) -> String { - str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| { - let mut x = "Non-UTF-8 output: ".to_string(); - x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from)); - x - }) + match str::from_utf8(s) { + Ok(s) => s.to_owned(), + Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()), + } } fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 7ab71f9009d04..d3a205a533dbd 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2643,15 +2643,7 @@ fn pretty_print_const<'tcx>( } fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result { - fmt.write_str("b\"")?; - for &c in byte_str { - for e in std::ascii::escape_default(c) { - fmt.write_char(e as char)?; - } - } - fmt.write_str("\"")?; - - Ok(()) + write!(fmt, "b\"{}\"", byte_str.escape_ascii()) } fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec>) -> fmt::Result { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index cc55b7e8611af..753c92f8885cf 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1401,14 +1401,7 @@ pub trait PrettyPrinter<'tcx>: } fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result { - define_scoped_cx!(self); - p!("b\""); - for &c in byte_str { - for e in std::ascii::escape_default(c) { - self.write_char(e as char)?; - } - } - p!("\""); + write!(self, "b\"{}\"", byte_str.escape_ascii())?; Ok(self) } diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index d8b8ac4d8710b..970830045b812 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -1,7 +1,6 @@ -use crate::ascii; use crate::cmp::Ordering; use crate::ffi::c_char; -use crate::fmt::{self, Write}; +use crate::fmt; use crate::intrinsics; use crate::ops; use crate::slice; @@ -161,11 +160,7 @@ impl fmt::Display for FromBytesUntilNulError { #[stable(feature = "cstr_debug", since = "1.3.0")] impl fmt::Debug for CStr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "\"")?; - for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) { - f.write_char(byte as char)?; - } - write!(f, "\"") + write!(f, "\"{}\"", self.to_bytes().escape_ascii()) } } diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 8e478cd7bc8a2..495c1c5ae46c1 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -1353,12 +1353,7 @@ impl Literal { /// Byte string literal. #[stable(feature = "proc_macro_lib2", since = "1.29.0")] pub fn byte_string(bytes: &[u8]) -> Literal { - let string = bytes - .iter() - .cloned() - .flat_map(std::ascii::escape_default) - .map(Into::::into) - .collect::(); + let string = bytes.escape_ascii().to_string(); Literal::new(bridge::LitKind::ByteStr, &string, None) } diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 9aeae4b2cae69..6fcf9351256df 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -2,7 +2,7 @@ use crate::ffi::OsStr; use crate::os::unix::ffi::OsStrExt; use crate::path::Path; use crate::sys::cvt; -use crate::{ascii, fmt, io, mem, ptr}; +use crate::{fmt, io, mem, ptr}; // FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here? #[cfg(not(unix))] @@ -64,18 +64,6 @@ enum AddressKind<'a> { Abstract(&'a [u8]), } -struct AsciiEscaped<'a>(&'a [u8]); - -impl<'a> fmt::Display for AsciiEscaped<'a> { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(fmt, "\"")?; - for byte in self.0.iter().cloned().flat_map(ascii::escape_default) { - write!(fmt, "{}", byte as char)?; - } - write!(fmt, "\"") - } -} - /// An address associated with a Unix socket. /// /// # Examples @@ -343,7 +331,7 @@ impl fmt::Debug for SocketAddr { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { match self.address() { AddressKind::Unnamed => write!(fmt, "(unnamed)"), - AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)), + AddressKind::Abstract(name) => write!(fmt, "\"{}\" (abstract)", name.escape_ascii()), AddressKind::Pathname(path) => write!(fmt, "{path:?} (pathname)"), } } From 052887e4b4c86426423ecd6f244e3e25cd71dd49 Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Mon, 8 Aug 2022 16:58:27 -0700 Subject: [PATCH 02/11] Add inline-llvm option for disabling/enabling LLVM inlining --- compiler/rustc_codegen_llvm/src/attributes.rs | 4 ++++ compiler/rustc_session/src/options.rs | 2 ++ src/test/rustdoc-ui/z-help.stdout | 1 + 3 files changed, 7 insertions(+) diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index b38684a63e410..eff2436d41cac 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -35,6 +35,10 @@ pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attrib /// Get LLVM attribute for the provided inline heuristic. #[inline] fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll Attribute> { + if !cx.tcx.sess.opts.unstable_opts.inline_llvm { + // disable LLVM inlining + return Some(AttributeKind::NoInline.create_attr(cx.llcx)); + } match inline { InlineAttr::Hint => Some(AttributeKind::InlineHint.create_attr(cx.llcx)), InlineAttr::Always => Some(AttributeKind::AlwaysInline.create_attr(cx.llcx)), diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9f07394b61ab8..a25e3362a0c33 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1345,6 +1345,8 @@ options! { "hash spans relative to their parent item for incr. comp. (default: no)"), incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], "verify incr. comp. hashes of green query instances (default: no)"), + inline_llvm: bool = (true, parse_bool, [TRACKED], + "enable LLVM inlining (default: yes)"), inline_mir: Option = (None, parse_opt_bool, [TRACKED], "enable MIR inlining (default: no)"), inline_mir_threshold: Option = (None, parse_opt_number, [TRACKED], diff --git a/src/test/rustdoc-ui/z-help.stdout b/src/test/rustdoc-ui/z-help.stdout index 236469ce9797a..73aa0a577c4d5 100644 --- a/src/test/rustdoc-ui/z-help.stdout +++ b/src/test/rustdoc-ui/z-help.stdout @@ -54,6 +54,7 @@ -Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no) -Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no) -Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no) + -Z inline-llvm=val -- enable LLVM inlining (default: yes) -Z inline-mir=val -- enable MIR inlining (default: no) -Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50) -Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100) From 9c3cb2d9bf1a35a471a442f28bf9be6566c52559 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Sep 2022 17:50:40 +0200 Subject: [PATCH 03/11] Update browser-ui-test version to 0.10.0 --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index b5d0ec558fd62..2774f8587f40e 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.9.8 \ No newline at end of file +0.10.0 \ No newline at end of file From 975dd6cdea09253f4f3ae0e5c4217ea2cc2d5319 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 11 Sep 2022 08:29:38 +0800 Subject: [PATCH 04/11] fix #101626, suggest pub instead of public for const type item --- compiler/rustc_ast/src/token.rs | 1 + src/test/ui/parser/public-instead-of-pub-3.fixed | 9 +++++++++ src/test/ui/parser/public-instead-of-pub-3.rs | 9 +++++++++ src/test/ui/parser/public-instead-of-pub-3.stderr | 13 +++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 src/test/ui/parser/public-instead-of-pub-3.fixed create mode 100644 src/test/ui/parser/public-instead-of-pub-3.rs create mode 100644 src/test/ui/parser/public-instead-of-pub-3.stderr diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index bfc4db32d3751..97dfb7837674f 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -473,6 +473,7 @@ impl Token { kw::Extern, kw::Impl, kw::Unsafe, + kw::Const, kw::Static, kw::Union, kw::Macro, diff --git a/src/test/ui/parser/public-instead-of-pub-3.fixed b/src/test/ui/parser/public-instead-of-pub-3.fixed new file mode 100644 index 0000000000000..14f620f41e8cd --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-3.fixed @@ -0,0 +1,9 @@ +// run-rustfix +mod test { + pub const X: i32 = 123; + //~^ ERROR expected one of `!` or `::`, found keyword `const` +} + +fn main() { + println!("{}", test::X); +} diff --git a/src/test/ui/parser/public-instead-of-pub-3.rs b/src/test/ui/parser/public-instead-of-pub-3.rs new file mode 100644 index 0000000000000..ee27cb1a1a8b2 --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-3.rs @@ -0,0 +1,9 @@ +// run-rustfix +mod test { + public const X: i32 = 123; + //~^ ERROR expected one of `!` or `::`, found keyword `const` +} + +fn main() { + println!("{}", test::X); +} diff --git a/src/test/ui/parser/public-instead-of-pub-3.stderr b/src/test/ui/parser/public-instead-of-pub-3.stderr new file mode 100644 index 0000000000000..72efae08dda8e --- /dev/null +++ b/src/test/ui/parser/public-instead-of-pub-3.stderr @@ -0,0 +1,13 @@ +error: expected one of `!` or `::`, found keyword `const` + --> $DIR/public-instead-of-pub-3.rs:3:12 + | +LL | public const X: i32 = 123; + | ^^^^^ expected one of `!` or `::` + | +help: write `pub` instead of `public` to make the item public + | +LL | pub const X: i32 = 123; + | ~~~ + +error: aborting due to previous error + From fd21df7182affbf342f33f97353ee34ee7eb5441 Mon Sep 17 00:00:00 2001 From: LingMan Date: Sat, 10 Sep 2022 07:30:29 +0200 Subject: [PATCH 05/11] Fix naming format of IEEE 754 standard Currently the documentation of f64::min refers to "IEEE-754 2008" while the documentation of f64::minimum refers to "IEEE 754-2019". Note that one has the format IEEE,hyphen,number,space,year while the other is IEEE,space,number,hyphen,year. The official IEEE site [1] uses the later format and it is also the one most commonly used throughout the codebase. Update all comments and - more importantly - documentation to consistently use the official format. [1] https://standards.ieee.org/ieee/754/4211/ --- library/core/src/ffi/c_double.md | 4 ++-- library/core/src/ffi/c_float.md | 4 ++-- library/core/src/num/dec2flt/decimal.rs | 2 +- library/core/src/num/f32.rs | 14 +++++++------- library/core/src/num/f64.rs | 14 +++++++------- library/test/src/stats.rs | 2 +- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/library/core/src/ffi/c_double.md b/library/core/src/ffi/c_double.md index 57f4534829ec8..d49e29b6e6e7f 100644 --- a/library/core/src/ffi/c_double.md +++ b/library/core/src/ffi/c_double.md @@ -1,6 +1,6 @@ Equivalent to C's `double` type. -This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard. +This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard. -[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754 +[IEEE 754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754 [`float`]: c_float diff --git a/library/core/src/ffi/c_float.md b/library/core/src/ffi/c_float.md index 61e2abc05189d..36374ef436181 100644 --- a/library/core/src/ffi/c_float.md +++ b/library/core/src/ffi/c_float.md @@ -1,5 +1,5 @@ Equivalent to C's `float` type. -This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all. +This type will almost always be [`f32`], which is guaranteed to be an [IEEE 754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all. -[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754 +[IEEE 754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754 diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs index f8edc3625e0ab..2019f71e69b8c 100644 --- a/library/core/src/num/dec2flt/decimal.rs +++ b/library/core/src/num/dec2flt/decimal.rs @@ -32,7 +32,7 @@ impl Default for Decimal { impl Decimal { /// The maximum number of digits required to unambiguously round a float. /// - /// For a double-precision IEEE-754 float, this required 767 digits, + /// For a double-precision IEEE 754 float, this required 767 digits, /// so we store the max digits + 1. /// /// We can exactly represent a float in radix `b` from radix 2 if diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index c83b928efc18d..2c6a0ba64f266 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -394,7 +394,7 @@ impl f32 { /// Not a Number (NaN). /// - /// Note that IEEE-754 doesn't define just a single NaN value; + /// Note that IEEE 754 doesn't define just a single NaN value; /// a plethora of bit patterns are considered to be NaN. /// Furthermore, the standard makes a difference /// between a "signaling" and a "quiet" NaN, @@ -632,7 +632,7 @@ impl f32 { } /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with - /// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any + /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that /// the bit pattern of NaNs are conserved over arithmetic operations, the result of /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. @@ -654,7 +654,7 @@ impl f32 { } /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with - /// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any + /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that /// the bit pattern of NaNs are conserved over arithmetic operations, the result of /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. @@ -833,7 +833,7 @@ impl f32 { /// Returns the maximum of the two numbers, ignoring NaN. /// /// If one of the arguments is NaN, then the other argument is returned. - /// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs; + /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. /// This also matches the behavior of libm’s fmax. /// @@ -853,7 +853,7 @@ impl f32 { /// Returns the minimum of the two numbers, ignoring NaN. /// /// If one of the arguments is NaN, then the other argument is returned. - /// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs; + /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids minNum's problems with associativity. /// This also matches the behavior of libm’s fmin. /// @@ -1051,9 +1051,9 @@ impl f32 { /// It turns out this is incredibly portable, for two reasons: /// /// * Floats and Ints have the same endianness on all supported platforms. - /// * IEEE-754 very precisely specifies the bit layout of floats. + /// * IEEE 754 very precisely specifies the bit layout of floats. /// - /// However there is one caveat: prior to the 2008 version of IEEE-754, how + /// However there is one caveat: prior to the 2008 version of IEEE 754, how /// to interpret the NaN signaling bit wasn't actually specified. Most platforms /// (notably x86 and ARM) picked the interpretation that was ultimately /// standardized in 2008, but some didn't (notably MIPS). As a result, all diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 28d23f733debd..fd3c18ce29bd2 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -393,7 +393,7 @@ impl f64 { /// Not a Number (NaN). /// - /// Note that IEEE-754 doesn't define just a single NaN value; + /// Note that IEEE 754 doesn't define just a single NaN value; /// a plethora of bit patterns are considered to be NaN. /// Furthermore, the standard makes a difference /// between a "signaling" and a "quiet" NaN, @@ -624,7 +624,7 @@ impl f64 { } /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with - /// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any + /// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that /// the bit pattern of NaNs are conserved over arithmetic operations, the result of /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. @@ -655,7 +655,7 @@ impl f64 { } /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with - /// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any + /// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that /// the bit pattern of NaNs are conserved over arithmetic operations, the result of /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. @@ -844,7 +844,7 @@ impl f64 { /// Returns the maximum of the two numbers, ignoring NaN. /// /// If one of the arguments is NaN, then the other argument is returned. - /// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs; + /// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. /// This also matches the behavior of libm’s fmax. /// @@ -864,7 +864,7 @@ impl f64 { /// Returns the minimum of the two numbers, ignoring NaN. /// /// If one of the arguments is NaN, then the other argument is returned. - /// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs; + /// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs; /// this function handles all NaNs the same way and avoids minNum's problems with associativity. /// This also matches the behavior of libm’s fmin. /// @@ -1044,9 +1044,9 @@ impl f64 { /// It turns out this is incredibly portable, for two reasons: /// /// * Floats and Ints have the same endianness on all supported platforms. - /// * IEEE-754 very precisely specifies the bit layout of floats. + /// * IEEE 754 very precisely specifies the bit layout of floats. /// - /// However there is one caveat: prior to the 2008 version of IEEE-754, how + /// However there is one caveat: prior to the 2008 version of IEEE 754, how /// to interpret the NaN signaling bit wasn't actually specified. Most platforms /// (notably x86 and ARM) picked the interpretation that was ultimately /// standardized in 2008, but some didn't (notably MIPS). As a result, all diff --git a/library/test/src/stats.rs b/library/test/src/stats.rs index 40b05704b40cb..b33b080126131 100644 --- a/library/test/src/stats.rs +++ b/library/test/src/stats.rs @@ -14,7 +14,7 @@ pub trait Stats { /// Sum of the samples. /// /// Note: this method sacrifices performance at the altar of accuracy - /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at: + /// Depends on IEEE 754 arithmetic guarantees. See proof of correctness at: /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric /// Predicates"][paper] /// From fd2766e7fde443d46eb051bb5ef27bbb29ee101d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 11 Sep 2022 06:58:11 +0000 Subject: [PATCH 06/11] Check that the types in RPITITs are WF --- compiler/rustc_typeck/src/check/wfcheck.rs | 44 +++++++++++++++++++ src/test/ui/impl-trait/in-trait/wf-bounds.rs | 16 +++++++ .../ui/impl-trait/in-trait/wf-bounds.stderr | 33 ++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 src/test/ui/impl-trait/in-trait/wf-bounds.rs create mode 100644 src/test/ui/impl-trait/in-trait/wf-bounds.stderr diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 5c6c8aca17346..ba8e4470feca2 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1,4 +1,5 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter}; +use hir::def::DefKind; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; @@ -1530,6 +1531,49 @@ fn check_fn_or_method<'tcx>( ); check_where_clauses(wfcx, span, def_id); + + check_return_position_impl_trait_in_trait_bounds( + tcx, + wfcx, + def_id, + sig.output(), + hir_decl.output.span(), + ); +} + +/// Basically `check_associated_type_bounds`, but separated for now and should be +/// deduplicated when RPITITs get lowered into real associated items. +fn check_return_position_impl_trait_in_trait_bounds<'tcx>( + tcx: TyCtxt<'tcx>, + wfcx: &WfCheckingCtxt<'_, 'tcx>, + fn_def_id: LocalDefId, + fn_output: Ty<'tcx>, + span: Span, +) { + if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id()) + && assoc_item.container == ty::AssocItemContainer::TraitContainer + { + for arg in fn_output.walk() { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(proj) = ty.kind() + && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder + && tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id() + { + let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id); + let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { + let normalized_bound = wfcx.normalize(span, None, bound); + traits::wf::predicate_obligations( + wfcx.infcx, + wfcx.param_env, + wfcx.body_id, + normalized_bound, + bound_span, + ) + }); + wfcx.register_obligations(wf_obligations); + } + } + } } const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box`, \ diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.rs b/src/test/ui/impl-trait/in-trait/wf-bounds.rs new file mode 100644 index 0000000000000..2c71583b31236 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/wf-bounds.rs @@ -0,0 +1,16 @@ +// issue #101663 + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Wf {} + +trait Uwu { + fn nya() -> impl Wf>; + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + fn nya2() -> impl Wf<[u8]>; + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.stderr b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr new file mode 100644 index 0000000000000..92e36841b70c2 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr @@ -0,0 +1,33 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:9:22 + | +LL | fn nya() -> impl Wf>; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub struct Vec { + | ^ required by this bound in `Vec` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:12:23 + | +LL | fn nya2() -> impl Wf<[u8]>; + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Wf` + --> $DIR/wf-bounds.rs:6:10 + | +LL | trait Wf {} + | ^ required by this bound in `Wf` +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Wf {} + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 89b6488ef0417df6f82671e57c4761a816af3974 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 11 Sep 2022 09:13:55 +0000 Subject: [PATCH 07/11] Deny RPITIT for object safety --- compiler/rustc_middle/src/traits/mod.rs | 9 ++++ .../src/traits/object_safety.rs | 26 ++++++++++ .../ui/impl-trait/in-trait/object-safety.rs | 22 ++++++++ .../impl-trait/in-trait/object-safety.stderr | 50 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/test/ui/impl-trait/in-trait/object-safety.rs create mode 100644 src/test/ui/impl-trait/in-trait/object-safety.stderr diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 755d9f8f69667..981d44a26079b 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -908,6 +908,12 @@ impl ObjectSafetyViolation { ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => { format!("method `{}` references the `Self` type in its return type", name).into() } + ObjectSafetyViolation::Method( + name, + MethodViolationCode::ReferencesImplTraitInTrait, + _, + ) => format!("method `{}` references an `impl Trait` type in its return type", name) + .into(), ObjectSafetyViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, @@ -1014,6 +1020,9 @@ pub enum MethodViolationCode { /// e.g., `fn foo(&self) -> Self` ReferencesSelfOutput, + /// e.g., `fn foo(&self) -> impl Sized` + ReferencesImplTraitInTrait, + /// e.g., `fn foo(&self) where Self: Clone` WhereClauseReferencesSelf, diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 612f513090888..5542f187f93f7 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -13,6 +13,7 @@ use super::elaborate_predicates; use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; +use hir::def::DefKind; use rustc_errors::{FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -431,6 +432,9 @@ fn virtual_call_violation_for_method<'tcx>( if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) { return Some(MethodViolationCode::ReferencesSelfOutput); } + if contains_illegal_impl_trait_in_trait(tcx, sig.output()) { + return Some(MethodViolationCode::ReferencesImplTraitInTrait); + } // We can't monomorphize things like `fn foo(...)`. let own_counts = tcx.generics_of(method.def_id).own_counts(); @@ -793,6 +797,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( ControlFlow::CONTINUE } } + ty::Projection(ref data) + if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder => + { + // We'll deny these later in their own pass + ControlFlow::CONTINUE + } ty::Projection(ref data) => { // This is a projected type `::X`. @@ -861,6 +871,22 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( .is_break() } +pub fn contains_illegal_impl_trait_in_trait<'tcx>( + tcx: TyCtxt<'tcx>, + ty: ty::Binder<'tcx, Ty<'tcx>>, +) -> bool { + // FIXME(RPITIT): Perhaps we should use a visitor here? + ty.skip_binder().walk().any(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(proj) = ty.kind() + { + tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder + } else { + false + } + }) +} + pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { object_safety_violations, ..*providers }; } diff --git a/src/test/ui/impl-trait/in-trait/object-safety.rs b/src/test/ui/impl-trait/in-trait/object-safety.rs new file mode 100644 index 0000000000000..dd35b9a2d8a75 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/object-safety.rs @@ -0,0 +1,22 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait Foo { + fn baz(&self) -> impl Debug; +} + +impl Foo for u32 { + fn baz(&self) -> u32 { + 32 + } +} + +fn main() { + let i = Box::new(42_u32) as Box; + //~^ ERROR the trait `Foo` cannot be made into an object + //~| ERROR the trait `Foo` cannot be made into an object + let s = i.baz(); + //~^ ERROR the trait `Foo` cannot be made into an object +} diff --git a/src/test/ui/impl-trait/in-trait/object-safety.stderr b/src/test/ui/impl-trait/in-trait/object-safety.stderr new file mode 100644 index 0000000000000..9a1554b5e1cbd --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/object-safety.stderr @@ -0,0 +1,50 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:17:33 + | +LL | let i = Box::new(42_u32) as Box; + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:7:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:20:13 + | +LL | let s = i.baz(); + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:7:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:17:13 + | +LL | let i = Box::new(42_u32) as Box; + | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety.rs:7:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + = note: required for `Box` to implement `CoerceUnsized>` + = note: required by cast to type `Box` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. From c3fcfa82728cb55b8e4dc6e2c8492d0ed79e174a Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Sun, 11 Sep 2022 20:32:47 +0100 Subject: [PATCH 08/11] Rustdoc-Json: Add tests for trait impls. --- .../impls/auxiliary/foreign_struct.rs | 1 + .../impls/auxiliary/foreign_trait.rs | 1 + .../rustdoc-json/impls/foreign_for_local.rs | 18 ++++++++++++++++ .../rustdoc-json/impls/local_for_foreign.rs | 18 ++++++++++++++++ .../rustdoc-json/impls/local_for_local.rs | 15 +++++++++++++ .../impls/local_for_local_primitive.rs | 21 +++++++++++++++++++ .../rustdoc-json/impls/local_for_primitive.rs | 7 +++++++ 7 files changed, 81 insertions(+) create mode 100644 src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs create mode 100644 src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs create mode 100644 src/test/rustdoc-json/impls/foreign_for_local.rs create mode 100644 src/test/rustdoc-json/impls/local_for_foreign.rs create mode 100644 src/test/rustdoc-json/impls/local_for_local.rs create mode 100644 src/test/rustdoc-json/impls/local_for_local_primitive.rs create mode 100644 src/test/rustdoc-json/impls/local_for_primitive.rs diff --git a/src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs b/src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs new file mode 100644 index 0000000000000..832d0fce59909 --- /dev/null +++ b/src/test/rustdoc-json/impls/auxiliary/foreign_struct.rs @@ -0,0 +1 @@ +pub struct ForeignStruct; diff --git a/src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs b/src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs new file mode 100644 index 0000000000000..2c81bee61282e --- /dev/null +++ b/src/test/rustdoc-json/impls/auxiliary/foreign_trait.rs @@ -0,0 +1 @@ +pub trait ForeignTrait {} diff --git a/src/test/rustdoc-json/impls/foreign_for_local.rs b/src/test/rustdoc-json/impls/foreign_for_local.rs new file mode 100644 index 0000000000000..290c2d571e874 --- /dev/null +++ b/src/test/rustdoc-json/impls/foreign_for_local.rs @@ -0,0 +1,18 @@ +// aux-build: foreign_trait.rs +extern crate foreign_trait; + +/// ForeignTrait id hack +pub use foreign_trait::ForeignTrait as _; +// @set ForeignTrait = "$.index[*][?(@.docs=='ForeignTrait id hack')].inner.id" + +pub struct LocalStruct; +// @set LocalStruct = "$.index[*][?(@.name=='LocalStruct')].id" + +/// foreign for local +impl foreign_trait::ForeignTrait for LocalStruct {} + +// @set impl = "$.index[*][?(@.docs=='foreign for local')].id" +// @is "$.index[*][?(@.docs=='foreign for local')].inner.for.inner.id" $LocalStruct +// @is "$.index[*][?(@.docs=='foreign for local')].inner.trait.id" $ForeignTrait + +// @has "$.index[*][?(@.name=='LocalStruct')].inner.impls[*]" $impl diff --git a/src/test/rustdoc-json/impls/local_for_foreign.rs b/src/test/rustdoc-json/impls/local_for_foreign.rs new file mode 100644 index 0000000000000..74f2f08b5a42f --- /dev/null +++ b/src/test/rustdoc-json/impls/local_for_foreign.rs @@ -0,0 +1,18 @@ +// aux-build: foreign_struct.rs +extern crate foreign_struct; + +/// ForeignStruct id hack +pub use foreign_struct::ForeignStruct as _; +// @set ForeignStruct = "$.index[*][?(@.docs=='ForeignStruct id hack')].inner.id" + +pub trait LocalTrait {} +// @set LocalTrait = "$.index[*][?(@.name=='LocalTrait')].id" + +/// local for foreign +impl LocalTrait for foreign_struct::ForeignStruct {} + +// @set impl = "$.index[*][?(@.docs=='local for foreign')].id" +// @is "$.index[*][?(@.docs=='local for foreign')].inner.trait.id" $LocalTrait +// @is "$.index[*][?(@.docs=='local for foreign')].inner.for.inner.id" $ForeignStruct + +// @is "$.index[*][?(@.name=='LocalTrait')].inner.implementations[*]" $impl diff --git a/src/test/rustdoc-json/impls/local_for_local.rs b/src/test/rustdoc-json/impls/local_for_local.rs new file mode 100644 index 0000000000000..93dedb7ec92d2 --- /dev/null +++ b/src/test/rustdoc-json/impls/local_for_local.rs @@ -0,0 +1,15 @@ +#![feature(no_core)] +#![no_core] + +// @set struct = "$.index[*][?(@.name=='Struct')].id" +pub struct Struct; +// @set trait = "$.index[*][?(@.name=='Trait')].id" +pub trait Trait {} +// @set impl = "$.index[*][?(@.docs=='impl')].id" +/// impl +impl Trait for Struct {} + +// @is "$.index[*][?(@.name=='Struct')].inner.impls[*]" $impl +// @is "$.index[*][?(@.name=='Trait')].inner.implementations[*]" $impl +// @is "$.index[*][?(@.docs=='impl')].inner.trait.id" $trait +// @is "$.index[*][?(@.docs=='impl')].inner.for.inner.id" $struct diff --git a/src/test/rustdoc-json/impls/local_for_local_primitive.rs b/src/test/rustdoc-json/impls/local_for_local_primitive.rs new file mode 100644 index 0000000000000..38e7e2658dfd5 --- /dev/null +++ b/src/test/rustdoc-json/impls/local_for_local_primitive.rs @@ -0,0 +1,21 @@ +#![feature(no_core)] +#![feature(rustdoc_internals)] +#![no_core] + +// @set Local = "$.index[*][?(@.name=='Local')].id" +pub trait Local {} + +// @is "$.index[*][?(@.docs=='Local for bool')].inner.trait.id" $Local +// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.kind" '"primitive"' +// @is "$.index[*][?(@.docs=='Local for bool')].inner.for.inner" '"bool"' +/// Local for bool +impl Local for bool {} + +// @set impl = "$.index[*][?(@.docs=='Local for bool')].id" +// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl + +// FIXME(#101695): Test bool's `impls` include "Local for bool" +// @has "$.index[*][?(@.name=='bool')]" +#[doc(primitive = "bool")] +/// Boolean docs +mod prim_bool {} diff --git a/src/test/rustdoc-json/impls/local_for_primitive.rs b/src/test/rustdoc-json/impls/local_for_primitive.rs new file mode 100644 index 0000000000000..7702a526fd844 --- /dev/null +++ b/src/test/rustdoc-json/impls/local_for_primitive.rs @@ -0,0 +1,7 @@ +// @set local = "$.index[*][?(@.name=='Local')]" +pub trait Local {} + +// @set impl = "$.index[*][?(@.docs=='local for bool')].id" +// @is "$.index[*][?(@.name=='Local')].inner.implementations[*]" $impl +/// local for bool +impl Local for bool {} From d010f95af1b5bc3188b8fcf5bfcaf9aadbfe2299 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 10 Sep 2022 17:36:17 +0200 Subject: [PATCH 09/11] Update tests for new browser-ui-test version --- src/test/rustdoc-gui/docblock-table-overflow.goml | 4 ++-- src/test/rustdoc-gui/sidebar-mobile-scroll.goml | 8 ++++---- src/test/rustdoc-gui/sidebar-source-code-display.goml | 6 +++--- src/test/rustdoc-gui/toggle-click-deadspace.goml | 5 ++++- src/test/rustdoc-gui/type-declation-overflow.goml | 4 ++-- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/test/rustdoc-gui/docblock-table-overflow.goml b/src/test/rustdoc-gui/docblock-table-overflow.goml index af76d2ea42760..7f97cf220cc55 100644 --- a/src/test/rustdoc-gui/docblock-table-overflow.goml +++ b/src/test/rustdoc-gui/docblock-table-overflow.goml @@ -6,7 +6,7 @@ size: (1100, 800) compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["scrollWidth"]) assert-property: (".top-doc .docblock", {"scrollWidth": "801"}) // However, since there is overflow in the , its scroll width is bigger. -assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"}) +assert-property: (".top-doc .docblock table", {"scrollWidth": "1572"}) // Checking it works on other doc blocks as well... @@ -18,4 +18,4 @@ compare-elements-property: ( ) assert-property: ("#implementations-list > details .docblock", {"scrollWidth": "801"}) // However, since there is overflow in the
, its scroll width is bigger. -assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1573"}) +assert-property: ("#implementations-list > details .docblock table", {"scrollWidth": "1572"}) diff --git a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml index b3bcea253388f..dc50185f01b25 100644 --- a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml +++ b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml @@ -6,7 +6,7 @@ assert-css: (".sidebar", {"display": "block", "left": "-1000px"}) // Scroll down. scroll-to: "//h2[@id='blanket-implementations']" -assert-window-property: {"pageYOffset": "702"} +assert-window-property: {"pageYOffset": "643"} // Open the sidebar menu. click: ".sidebar-menu-toggle" @@ -21,11 +21,11 @@ assert-window-property: {"pageYOffset": "0"} // Close the sidebar menu. Make sure the scroll position gets restored. click: ".sidebar-menu-toggle" wait-for-css: (".sidebar", {"left": "-1000px"}) -assert-window-property: {"pageYOffset": "702"} +assert-window-property: {"pageYOffset": "643"} // Now test that scrollability returns when the browser window is just resized. click: ".sidebar-menu-toggle" wait-for-css: (".sidebar", {"left": "0px"}) assert-window-property: {"pageYOffset": "0"} -size: (900, 900) -assert-window-property: {"pageYOffset": "702"} +size: (900, 600) +assert-window-property: {"pageYOffset": "643"} diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml index e4662a10ed5da..4321efcdb1712 100644 --- a/src/test/rustdoc-gui/sidebar-source-code-display.goml +++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml @@ -224,14 +224,14 @@ click: "#sidebar-toggle" wait-for-css: (".sidebar", {"width": "0px"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' -assert-window-property: {"pageYOffset": "2519"} +assert-window-property: {"pageYOffset": "2542"} // Expanding the sidebar... click: "#sidebar-toggle" wait-for-css: (".sidebar", {"width": "500px"}) click: "#sidebar-toggle" wait-for-css: (".sidebar", {"width": "0px"}) // The "scrollTop" property should be the same. -assert-window-property: {"pageYOffset": "2519"} +assert-window-property: {"pageYOffset": "2542"} // We now check that the scroll position is restored if the window is resized. size: (500, 700) @@ -239,7 +239,7 @@ click: "#sidebar-toggle" wait-for-css: ("#source-sidebar", {"visibility": "visible"}) assert-window-property: {"pageYOffset": "0"} size: (900, 900) -assert-window-property: {"pageYOffset": "2519"} +assert-window-property: {"pageYOffset": "2542"} size: (500, 700) click: "#sidebar-toggle" wait-for-css: ("#source-sidebar", {"visibility": "hidden"}) diff --git a/src/test/rustdoc-gui/toggle-click-deadspace.goml b/src/test/rustdoc-gui/toggle-click-deadspace.goml index 4a328c9f9e06e..8c3a0bf5bb78f 100644 --- a/src/test/rustdoc-gui/toggle-click-deadspace.goml +++ b/src/test/rustdoc-gui/toggle-click-deadspace.goml @@ -4,7 +4,10 @@ goto: file://|DOC_PATH|/lib2/struct.Foo.html assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""}) click: "h4.code-header" // This is the position of "pub" in "pub fn a_method" assert-attribute: (".impl-items .rustdoc-toggle", {"open": ""}) -click: ".impl-items .rustdoc-toggle summary::before" // This is the position of "[-]" next to that pub fn. +click-with-offset: ( + ".impl-items .rustdoc-toggle summary", + {"x": -24, "y": 8}, // This is the position of "[-]" next to that pub fn. +) assert-attribute-false: (".impl-items .rustdoc-toggle", {"open": ""}) // Click the "Trait" part of "impl Trait" and verify it navigates. diff --git a/src/test/rustdoc-gui/type-declation-overflow.goml b/src/test/rustdoc-gui/type-declation-overflow.goml index 85e03c45e700e..9a46908f9333b 100644 --- a/src/test/rustdoc-gui/type-declation-overflow.goml +++ b/src/test/rustdoc-gui/type-declation-overflow.goml @@ -32,6 +32,6 @@ assert-property: (".item-decl pre", {"scrollWidth": "950"}) size: (600, 600) goto: file://|DOC_PATH|/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html // It shouldn't have an overflow in the topbar either. -assert-property: (".mobile-topbar .location", {"scrollWidth": "502"}) -assert-property: (".mobile-topbar .location", {"clientWidth": "502"}) +assert-property: (".mobile-topbar .location", {"scrollWidth": "500"}) +assert-property: (".mobile-topbar .location", {"clientWidth": "500"}) assert-css: (".mobile-topbar .location", {"overflow-x": "hidden"}) From bff8078fb41f34f65dbde7d25ed465ff1c3c4b2b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 11 Sep 2022 18:15:09 -0700 Subject: [PATCH 10/11] rustdoc: remove no-op `#search { margin-left: 0 }` This rule was added in c729e4dca7581fcd060978bcb0d7f98ea4eb6b82 to remove an unnecessary left margin that was present on desktop. This desktop-mode margin was itself removed in 135281ed1525db15edd8ebd092aa10aa40df2386. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 31fced21ce833..cefed3f42ec5e 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1892,7 +1892,6 @@ in storage.js plus the media query with (min-width: 701px) } #search { - margin-left: 0; padding: 0; } From 2d239fbb9cb0cbc81e01ab0675e27f57e1812813 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sun, 11 Sep 2022 18:43:52 -0700 Subject: [PATCH 11/11] rustdoc: remove no-op `#search` The padding rule was added in 135281ed1525db15edd8ebd092aa10aa40df2386 when converting the rule for #main, but didn't do anything even then. --- src/librustdoc/html/static/css/rustdoc.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index cefed3f42ec5e..72e04decbe3e0 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1891,10 +1891,6 @@ in storage.js plus the media query with (min-width: 701px) margin-top: 10px; } - #search { - padding: 0; - } - .anchor { display: none !important; }