From 289ad1ac3882135fd3bc1387536978248dead9da Mon Sep 17 00:00:00 2001 From: zohnannor Date: Fri, 12 Aug 2022 22:43:52 +0300 Subject: [PATCH 01/13] Clarify `array:from_fn` documentation --- library/core/src/array/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index c9823a136bc42..4d1ba6b1650c1 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -31,6 +31,10 @@ pub use iter::IntoIter; /// # Example /// /// ```rust +/// // type inference is helping us here, the way `from_fn` knows how many +/// // elements to produce is the length of array down there: only arrays of +/// // equal lengths can be compared, so the const generic parameter `N` is +/// // inferred to be 5, thus creating array of 5 elements. /// let array = core::array::from_fn(|i| i); /// assert_eq!(array, [0, 1, 2, 3, 4]); /// ``` From 908bdea178065aceb0dd46f91c93d6c347b49ab4 Mon Sep 17 00:00:00 2001 From: Tim Hutt Date: Sat, 10 Sep 2022 12:02:54 +0100 Subject: [PATCH 02/13] Document surprising and dangerous fs::Permissions behaviour on Unix This documents the very surprising behaviour that `set_readonly(false)` will make a file *world writable* on Unix. I would go so far as to say that this function should be deprecated on Unix, or maybe even entirely. But documenting the bad behaviour is a good first step. --- library/std/src/fs.rs | 67 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index c6c78dc3939e7..188ff00e1f8dd 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -1365,6 +1365,34 @@ impl FileTimes { impl Permissions { /// Returns `true` if these permissions describe a readonly (unwritable) file. /// + /// # Note + /// + /// This function does not take Access Control Lists (ACLs) or Unix group + /// membership into account. + /// + /// # Windows + /// + /// On Windows this returns [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants). + /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail + /// but the user may still have permission to change this flag. If + /// `FILE_ATTRIBUTE_READONLY` is *not* set then writes may still fail due + /// to lack of write permission. + /// The behavior of this attribute for directories depends on the Windows + /// version. + /// + /// # Unix (including macOS) + /// + /// On Unix-based platforms this checks if *any* of the owner, group or others + /// write permission bits are set. It does not check if the current + /// user is in the file's assigned group. It also does not check ACLs. + /// Therefore even if this returns true you may not be able to write to the + /// file, and vice versa. The [`PermissionsExt`] trait gives direct access + /// to the permission bits but also does not read ACLs. If you need to + /// accurately know whether or not a file is writable use the `access()` + /// function from libc. + /// + /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt + /// /// # Examples /// /// ```no_run @@ -1390,8 +1418,40 @@ impl Permissions { /// using the resulting `Permission` will update file permissions to allow /// writing. /// - /// This operation does **not** modify the filesystem. To modify the - /// filesystem use the [`set_permissions`] function. + /// This operation does **not** modify the files attributes. This only + /// changes the in-memory value of these attributes for this `Permissions` + /// instance. To modify the files attributes use the [`set_permissions`] + /// function which commits these attribute changes to the file. + /// + /// # Note + /// + /// `set_readonly(false)` makes the file *world-writable* on Unix. + /// You can use the [`PermissionsExt`] trait on Unix to avoid this issue. + /// + /// It also does not take Access Control Lists (ACLs) or Unix group + /// membership into account. + /// + /// # Windows + /// + /// On Windows this sets or clears [`FILE_ATTRIBUTE_READONLY`](https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants). + /// If `FILE_ATTRIBUTE_READONLY` is set then writes to the file will fail + /// but the user may still have permission to change this flag. If + /// `FILE_ATTRIBUTE_READONLY` is *not* set then the write may still fail if + /// the user does not have permission to write to the file. + /// + /// In Windows 7 and earlier this attribute prevents deleting empty + /// directories. It does not prevent modifying the directory contents. + /// On later versions of Windows this attribute is ignored for directories. + /// + /// # Unix (including macOS) + /// + /// On Unix-based platforms this sets or clears the write access bit for + /// the owner, group *and* others, equivalent to `chmod a+w ` + /// or `chmod a-w ` respectively. The latter will grant write access + /// to all users! You can use the [`PermissionsExt`] trait on Unix + /// to avoid this issue. + /// + /// [`PermissionsExt`]: crate::os::unix::fs::PermissionsExt /// /// # Examples /// @@ -1405,7 +1465,8 @@ impl Permissions { /// /// permissions.set_readonly(true); /// - /// // filesystem doesn't change + /// // filesystem doesn't change, only the in memory state of the + /// // readonly permission /// assert_eq!(false, metadata.permissions().readonly()); /// /// // just this particular `permissions`. From 76bec177bca25a35aa55a364bb8d2d66e0d5d45e Mon Sep 17 00:00:00 2001 From: Tomoaki Kawada Date: Thu, 13 Oct 2022 14:16:12 +0900 Subject: [PATCH 03/13] kmc-solid: Handle errors returned by `SOLID_FS_ReadDir` --- library/std/src/sys/solid/fs.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/solid/fs.rs b/library/std/src/sys/solid/fs.rs index 9692222534eaa..6c66b93a3e1a3 100644 --- a/library/std/src/sys/solid/fs.rs +++ b/library/std/src/sys/solid/fs.rs @@ -175,15 +175,19 @@ impl Iterator for ReadDir { type Item = io::Result; fn next(&mut self) -> Option> { - unsafe { - let mut out_dirent = MaybeUninit::uninit(); - error::SolidError::err_if_negative(abi::SOLID_FS_ReadDir( + let entry = unsafe { + let mut out_entry = MaybeUninit::uninit(); + match error::SolidError::err_if_negative(abi::SOLID_FS_ReadDir( self.inner.dirp, - out_dirent.as_mut_ptr(), - )) - .ok()?; - Some(Ok(DirEntry { entry: out_dirent.assume_init(), inner: Arc::clone(&self.inner) })) - } + out_entry.as_mut_ptr(), + )) { + Ok(_) => out_entry.assume_init(), + Err(e) if e.as_raw() == abi::SOLID_ERR_NOTFOUND => return None, + Err(e) => return Some(Err(e.as_io_error())), + } + }; + + (entry.d_name[0] != 0).then(|| Ok(DirEntry { entry, inner: Arc::clone(&self.inner) })) } } From f543770de26849fee46d7974ba9212e402c22151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Wed, 19 Oct 2022 17:27:08 +0200 Subject: [PATCH 04/13] rustdoc: Do not filter out `Self: Sized` bounds --- src/librustdoc/clean/mod.rs | 41 +++++++++++-------- .../inline_cross/auxiliary/issue-24183.rs | 14 +++++++ ...ssue-24183.method_no_where_self_sized.html | 1 + src/test/rustdoc/inline_cross/issue-24183.rs | 18 ++++++++ 4 files changed, 56 insertions(+), 18 deletions(-) create mode 100644 src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs create mode 100644 src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html create mode 100644 src/test/rustdoc/inline_cross/issue-24183.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5f674ed7441ba..70f8c70877627 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -774,31 +774,36 @@ fn clean_ty_generics<'tcx>( let mut where_predicates = where_predicates.into_iter().flat_map(|p| clean_predicate(*p, cx)).collect::>(); - // Type parameters have a Sized bound by default unless removed with - // ?Sized. Scan through the predicates and mark any type parameter with - // a Sized bound, removing the bounds as we find them. + // In the surface language, all type parameters except `Self` have an + // implicit `Sized` bound unless removed with `?Sized`. + // However, in the list of where-predicates below, `Sized` appears like a + // normal bound: It's either present (the type is sized) or + // absent (the type is unsized) but never *maybe* (i.e. `?Sized`). // - // Note that associated types also have a sized bound by default, but we + // This is unsuitable for rendering. + // Thus, as a first step remove all `Sized` bounds that should be implicit. + // + // Note that associated types also have an implicit `Sized` bound but we // don't actually know the set of associated types right here so that's - // handled in cleaning associated types + // handled when cleaning associated types. let mut sized_params = FxHashSet::default(); - where_predicates.retain(|pred| match *pred { - WherePredicate::BoundPredicate { ty: Generic(ref g), ref bounds, .. } => { - if bounds.iter().any(|b| b.is_sized_bound(cx)) { - sized_params.insert(*g); - false - } else { - true - } + where_predicates.retain(|pred| { + if let WherePredicate::BoundPredicate { ty: Generic(g), bounds, .. } = pred + && *g != kw::SelfUpper + && bounds.iter().any(|b| b.is_sized_bound(cx)) + { + sized_params.insert(*g); + false + } else { + true } - _ => true, }); - // Run through the type parameters again and insert a ?Sized - // unbound for any we didn't find to be Sized. + // As a final step, go through the type parameters again and insert a + // `?Sized` bound for each one we didn't find to be `Sized`. for tp in &stripped_params { - if matches!(tp.kind, types::GenericParamDefKind::Type { .. }) - && !sized_params.contains(&tp.name) + if let types::GenericParamDefKind::Type { .. } = tp.kind + && !sized_params.contains(&tp.name) { where_predicates.push(WherePredicate::BoundPredicate { ty: Type::Generic(tp.name), diff --git a/src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs b/src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs new file mode 100644 index 0000000000000..e7a13acc6f864 --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/issue-24183.rs @@ -0,0 +1,14 @@ +#![crate_type = "lib"] + +pub trait U/*: ?Sized */ { + fn modified(self) -> Self + where + Self: Sized + { + self + } + + fn touch(&self)/* where Self: ?Sized */{} +} + +pub trait S: Sized {} diff --git a/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html new file mode 100644 index 0000000000000..6955a961499ba --- /dev/null +++ b/src/test/rustdoc/inline_cross/issue-24183.method_no_where_self_sized.html @@ -0,0 +1 @@ +

fn touch(&self)

\ No newline at end of file diff --git a/src/test/rustdoc/inline_cross/issue-24183.rs b/src/test/rustdoc/inline_cross/issue-24183.rs new file mode 100644 index 0000000000000..d11b6955f3c0f --- /dev/null +++ b/src/test/rustdoc/inline_cross/issue-24183.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] +#![crate_name = "usr"] + +// aux-crate:issue_24183=issue-24183.rs +// edition: 2021 + +// @has usr/trait.U.html +// @has - '//*[@class="item-decl"]' "pub trait U {" +// @has - '//*[@id="method.modified"]' \ +// "fn modified(self) -> Self\ +// where \ +// Self: Sized" +// @snapshot method_no_where_self_sized - '//*[@id="method.touch"]/*[@class="code-header"]' +pub use issue_24183::U; + +// @has usr/trait.S.html +// @has - '//*[@class="item-decl"]' 'pub trait S: Sized {' +pub use issue_24183::S; From 1225c3f6b8976b96eff4444cd7416a5d14eb3cd4 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 17 Oct 2022 05:54:13 +0800 Subject: [PATCH 05/13] fix #103112, add diagnostic for calling a function with the same name when a Macro is not found --- compiler/rustc_resolve/src/macros.rs | 22 +++++++++++++++++++-- src/test/ui/suggestions/issue-103112.rs | 4 ++++ src/test/ui/suggestions/issue-103112.stderr | 14 +++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/suggestions/issue-103112.rs create mode 100644 src/test/ui/suggestions/issue-103112.stderr diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f6f0b3c11391b..71264ffc877de 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -12,7 +12,7 @@ use rustc_attr::StabilityLevel; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::compile_declarative_macro; @@ -694,7 +694,25 @@ impl<'a> Resolver<'a> { check_consistency(self, &path, path_span, kind, initial_res, res) } path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed { .. } => { + let mut suggestion = None; let (span, label) = if let PathResult::Failed { span, label, .. } = path_res { + // try to suggest if it's not a macro, maybe a function + if let PathResult::NonModule(partial_res) = self.resolve_path( + &path, + Some(ValueNS), + &parent_scope, + Some(Finalize::new(ast::CRATE_NODE_ID, path_span)), + None, + ) && partial_res.unresolved_segments() == 0 { + let sm = self.session.source_map(); + let span = sm.span_extend_while(span, |c| c == '!').unwrap_or(span); + let code = sm.span_to_snippet(span).unwrap(); + suggestion = Some( + (vec![(span, code.trim_end_matches('!').to_string())], + format!("{} is not a macro, but a {}, try to remove `!`", Segment::names_to_string(&path), partial_res.base_res().descr()), + Applicability::MaybeIncorrect) + ); + } (span, label) } else { ( @@ -708,7 +726,7 @@ impl<'a> Resolver<'a> { }; self.report_error( span, - ResolutionError::FailedToResolve { label, suggestion: None }, + ResolutionError::FailedToResolve { label, suggestion }, ); } PathResult::Module(..) | PathResult::Indeterminate => unreachable!(), diff --git a/src/test/ui/suggestions/issue-103112.rs b/src/test/ui/suggestions/issue-103112.rs new file mode 100644 index 0000000000000..111ae7c73080d --- /dev/null +++ b/src/test/ui/suggestions/issue-103112.rs @@ -0,0 +1,4 @@ +fn main() { + std::process::abort!(); + //~^ ERROR: failed to resolve +} diff --git a/src/test/ui/suggestions/issue-103112.stderr b/src/test/ui/suggestions/issue-103112.stderr new file mode 100644 index 0000000000000..3518ef4c65271 --- /dev/null +++ b/src/test/ui/suggestions/issue-103112.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: could not find `abort` in `process` + --> $DIR/issue-103112.rs:2:19 + | +LL | std::process::abort!(); + | ^^^^^ could not find `abort` in `process` + | +help: std::process::abort is not a macro, but a function, try to remove `!` + | +LL | std::process::abort(); + | ~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. From f90bf50d475eb9240c5bdeef3102c235335180c4 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 18 Oct 2022 01:58:22 +0800 Subject: [PATCH 06/13] fix span for suggestion --- compiler/rustc_resolve/src/macros.rs | 20 +++++++------------- src/test/ui/suggestions/issue-103112.stderr | 5 +++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 71264ffc877de..9526296f95115 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -697,21 +697,15 @@ impl<'a> Resolver<'a> { let mut suggestion = None; let (span, label) = if let PathResult::Failed { span, label, .. } = path_res { // try to suggest if it's not a macro, maybe a function - if let PathResult::NonModule(partial_res) = self.resolve_path( - &path, - Some(ValueNS), - &parent_scope, - Some(Finalize::new(ast::CRATE_NODE_ID, path_span)), - None, - ) && partial_res.unresolved_segments() == 0 { + if let PathResult::NonModule(partial_res) = self.maybe_resolve_path(&path, Some(ValueNS), &parent_scope) + && partial_res.unresolved_segments() == 0 { let sm = self.session.source_map(); - let span = sm.span_extend_while(span, |c| c == '!').unwrap_or(span); - let code = sm.span_to_snippet(span).unwrap(); - suggestion = Some( - (vec![(span, code.trim_end_matches('!').to_string())], + let exclamation_span = sm.next_point(span); + suggestion = Some(( + vec![(exclamation_span, "".to_string())], format!("{} is not a macro, but a {}, try to remove `!`", Segment::names_to_string(&path), partial_res.base_res().descr()), - Applicability::MaybeIncorrect) - ); + Applicability::MaybeIncorrect + )); } (span, label) } else { diff --git a/src/test/ui/suggestions/issue-103112.stderr b/src/test/ui/suggestions/issue-103112.stderr index 3518ef4c65271..4ca7fdf9b5a2a 100644 --- a/src/test/ui/suggestions/issue-103112.stderr +++ b/src/test/ui/suggestions/issue-103112.stderr @@ -6,8 +6,9 @@ LL | std::process::abort!(); | help: std::process::abort is not a macro, but a function, try to remove `!` | -LL | std::process::abort(); - | ~~~~~ +LL - std::process::abort!(); +LL + std::process::abort(); + | error: aborting due to previous error From bdc4acb7bfc17955b9cdc04efbe5a4e89d94755e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 21 Oct 2022 15:13:12 +0200 Subject: [PATCH 07/13] bootstrap: also create rustc-src component in sysroot --- src/bootstrap/compile.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4ccdabe4bb67d..4ec4f071944d6 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1155,6 +1155,20 @@ impl Step for Sysroot { ); } } + // Same for the rustc-src component. + let sysroot_lib_rustlib_rustcsrc = sysroot.join("lib/rustlib/rustc-src"); + t!(fs::create_dir_all(&sysroot_lib_rustlib_rustcsrc)); + let sysroot_lib_rustlib_rustcsrc_rust = sysroot_lib_rustlib_rustcsrc.join("rust"); + if let Err(e) = + symlink_dir(&builder.config, &builder.src, &sysroot_lib_rustlib_rustcsrc_rust) + { + eprintln!( + "warning: creating symbolic link `{}` to `{}` failed with {}", + sysroot_lib_rustlib_rustcsrc_rust.display(), + builder.src.display(), + e, + ); + } INTERNER.intern_path(sysroot) } From c0cda2b2781a7cd66cc5d6672e390edfdbf7fc64 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Oct 2022 20:18:16 +0000 Subject: [PATCH 08/13] Pretty print lifetimes captured by RPIT --- compiler/rustc_middle/src/ty/print/pretty.rs | 16 ++++++++++++++++ src/test/ui/impl-trait/hidden-lifetimes.stderr | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 0b06ccc19ecc8..2a229e0474382 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -16,6 +16,7 @@ use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; +use smallvec::SmallVec; use std::cell::Cell; use std::char; @@ -794,6 +795,7 @@ pub trait PrettyPrinter<'tcx>: let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); let mut is_sized = false; + let mut lifetimes = SmallVec::<[ty::Region<'tcx>; 1]>::new(); for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) { let predicate = predicate.subst(tcx, substs); @@ -825,6 +827,9 @@ pub trait PrettyPrinter<'tcx>: &mut fn_traits, ); } + ty::PredicateKind::TypeOutlives(outlives) => { + lifetimes.push(outlives.1); + } _ => {} } } @@ -978,6 +983,17 @@ pub trait PrettyPrinter<'tcx>: write!(self, "Sized")?; } + if let [re] = lifetimes.as_slice() + && re.is_static() + { + // Don't print a single static lifetime + } else { + for re in lifetimes { + write!(self, " + ")?; + self = self.print_region(re)?; + } + } + Ok(self) } diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr index efc228de58be5..de06ded7acdb6 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.stderr +++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr @@ -1,4 +1,4 @@ -error[E0700]: hidden type for `impl Swap` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds --> $DIR/hidden-lifetimes.rs:29:5 | LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { @@ -11,7 +11,7 @@ help: to declare that the `impl Trait` captures `'b`, you can add an explicit `' LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a + 'b { | ++++ -error[E0700]: hidden type for `impl Swap` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `impl Swap + 'a` captures lifetime that does not appear in bounds --> $DIR/hidden-lifetimes.rs:46:5 | LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc>) -> impl Swap + 'a { From 36662dfc83cb297c21f410eea60deb3ef6d0e940 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 22 Oct 2022 15:37:46 +0100 Subject: [PATCH 09/13] Fix wrapped valid-range handling in ty_find_init_error Rust's niche handling allows for wrapping valid ranges with end < start; for instance, a valid range with start=43 and end=41 means a niche of 42. Most places in the compiler handle this correctly, but ty_find_init_error assumed that `lo > 0` means the type cannot contain a zero. Fix it to handle wrapping ranges. Add a test to cover this case. --- compiler/rustc_lint/src/builtin.rs | 5 +- src/test/ui/lint/invalid_value.rs | 7 ++ src/test/ui/lint/invalid_value.stderr | 113 ++++++++++++++------------ 3 files changed, 73 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 715ba4ca156d4..ff477dc9337c1 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2570,7 +2570,10 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { // return `Bound::Excluded`. (And we have tests checking that we // handle the attribute correctly.) // We don't add a span since users cannot declare such types anyway. - (Bound::Included(lo), _) if lo > 0 => { + (Bound::Included(lo), Bound::Included(hi)) if 0 < lo && lo < hi => { + return Some((format!("`{}` must be non-null", ty), None)); + } + (Bound::Included(lo), Bound::Unbounded) if 0 < lo => { return Some((format!("`{}` must be non-null", ty), None)); } (Bound::Included(_), _) | (_, Bound::Included(_)) diff --git a/src/test/ui/lint/invalid_value.rs b/src/test/ui/lint/invalid_value.rs index 946a0e3886139..57d8cbe7c9341 100644 --- a/src/test/ui/lint/invalid_value.rs +++ b/src/test/ui/lint/invalid_value.rs @@ -44,6 +44,10 @@ enum TwoUninhabited { B(Void), } +#[rustc_layout_scalar_valid_range_start(254)] +#[rustc_layout_scalar_valid_range_end(1)] +pub(crate) struct WrapAroundRange(u8); + #[allow(unused)] fn generic() { unsafe { @@ -131,6 +135,9 @@ fn main() { let _val: *const [()] = mem::zeroed(); let _val: *const [()] = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: WrapAroundRange = mem::zeroed(); + let _val: WrapAroundRange = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + // Things where 0 is okay due to rustc implementation details, // but that are not guaranteed to keep working. let _val: Result = mem::zeroed(); diff --git a/src/test/ui/lint/invalid_value.stderr b/src/test/ui/lint/invalid_value.stderr index 3901692001abd..76afb765f0f05 100644 --- a/src/test/ui/lint/invalid_value.stderr +++ b/src/test/ui/lint/invalid_value.stderr @@ -1,5 +1,5 @@ error: the type `&T` does not permit zero-initialization - --> $DIR/invalid_value.rs:50:32 + --> $DIR/invalid_value.rs:54:32 | LL | let _val: &'static T = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | #![deny(invalid_value)] | ^^^^^^^^^^^^^ error: the type `&T` does not permit being left uninitialized - --> $DIR/invalid_value.rs:51:32 + --> $DIR/invalid_value.rs:55:32 | LL | let _val: &'static T = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | let _val: &'static T = mem::uninitialized(); = note: references must be non-null error: the type `Wrap<&T>` does not permit zero-initialization - --> $DIR/invalid_value.rs:53:38 + --> $DIR/invalid_value.rs:57:38 | LL | let _val: Wrap<&'static T> = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -41,7 +41,7 @@ LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `Wrap<&T>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:54:38 + --> $DIR/invalid_value.rs:58:38 | LL | let _val: Wrap<&'static T> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -56,7 +56,7 @@ LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `!` does not permit zero-initialization - --> $DIR/invalid_value.rs:61:23 + --> $DIR/invalid_value.rs:65:23 | LL | let _val: ! = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -67,7 +67,7 @@ LL | let _val: ! = mem::zeroed(); = note: the `!` type has no valid value error: the type `!` does not permit being left uninitialized - --> $DIR/invalid_value.rs:62:23 + --> $DIR/invalid_value.rs:66:23 | LL | let _val: ! = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -78,7 +78,7 @@ LL | let _val: ! = mem::uninitialized(); = note: the `!` type has no valid value error: the type `(i32, !)` does not permit zero-initialization - --> $DIR/invalid_value.rs:64:30 + --> $DIR/invalid_value.rs:68:30 | LL | let _val: (i32, !) = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _val: (i32, !) = mem::zeroed(); = note: the `!` type has no valid value error: the type `(i32, !)` does not permit being left uninitialized - --> $DIR/invalid_value.rs:65:30 + --> $DIR/invalid_value.rs:69:30 | LL | let _val: (i32, !) = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | let _val: (i32, !) = mem::uninitialized(); = note: integers must not be uninitialized error: the type `Void` does not permit zero-initialization - --> $DIR/invalid_value.rs:67:26 + --> $DIR/invalid_value.rs:71:26 | LL | let _val: Void = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -115,7 +115,7 @@ LL | enum Void {} | ^^^^^^^^^ error: the type `Void` does not permit being left uninitialized - --> $DIR/invalid_value.rs:68:26 + --> $DIR/invalid_value.rs:72:26 | LL | let _val: Void = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | enum Void {} | ^^^^^^^^^ error: the type `&i32` does not permit zero-initialization - --> $DIR/invalid_value.rs:70:34 + --> $DIR/invalid_value.rs:74:34 | LL | let _val: &'static i32 = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -141,7 +141,7 @@ LL | let _val: &'static i32 = mem::zeroed(); = note: references must be non-null error: the type `&i32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:71:34 + --> $DIR/invalid_value.rs:75:34 | LL | let _val: &'static i32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -152,7 +152,7 @@ LL | let _val: &'static i32 = mem::uninitialized(); = note: references must be non-null error: the type `Ref` does not permit zero-initialization - --> $DIR/invalid_value.rs:73:25 + --> $DIR/invalid_value.rs:77:25 | LL | let _val: Ref = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | struct Ref(&'static i32); | ^^^^^^^^^^^^ error: the type `Ref` does not permit being left uninitialized - --> $DIR/invalid_value.rs:74:25 + --> $DIR/invalid_value.rs:78:25 | LL | let _val: Ref = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ LL | struct Ref(&'static i32); | ^^^^^^^^^^^^ error: the type `fn()` does not permit zero-initialization - --> $DIR/invalid_value.rs:76:26 + --> $DIR/invalid_value.rs:80:26 | LL | let _val: fn() = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -193,7 +193,7 @@ LL | let _val: fn() = mem::zeroed(); = note: function pointers must be non-null error: the type `fn()` does not permit being left uninitialized - --> $DIR/invalid_value.rs:77:26 + --> $DIR/invalid_value.rs:81:26 | LL | let _val: fn() = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -204,7 +204,7 @@ LL | let _val: fn() = mem::uninitialized(); = note: function pointers must be non-null error: the type `Wrap` does not permit zero-initialization - --> $DIR/invalid_value.rs:79:32 + --> $DIR/invalid_value.rs:83:32 | LL | let _val: Wrap = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -219,7 +219,7 @@ LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `Wrap` does not permit being left uninitialized - --> $DIR/invalid_value.rs:80:32 + --> $DIR/invalid_value.rs:84:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -234,7 +234,7 @@ LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `WrapEnum` does not permit zero-initialization - --> $DIR/invalid_value.rs:82:36 + --> $DIR/invalid_value.rs:86:36 | LL | let _val: WrapEnum = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -249,7 +249,7 @@ LL | enum WrapEnum { Wrapped(T) } | ^ error: the type `WrapEnum` does not permit being left uninitialized - --> $DIR/invalid_value.rs:83:36 + --> $DIR/invalid_value.rs:87:36 | LL | let _val: WrapEnum = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -264,7 +264,7 @@ LL | enum WrapEnum { Wrapped(T) } | ^ error: the type `Wrap<(RefPair, i32)>` does not permit zero-initialization - --> $DIR/invalid_value.rs:85:42 + --> $DIR/invalid_value.rs:89:42 | LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -279,7 +279,7 @@ LL | struct RefPair((&'static i32, i32)); | ^^^^^^^^^^^^^^^^^^^ error: the type `Wrap<(RefPair, i32)>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:86:42 + --> $DIR/invalid_value.rs:90:42 | LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -294,7 +294,7 @@ LL | struct RefPair((&'static i32, i32)); | ^^^^^^^^^^^^^^^^^^^ error: the type `NonNull` does not permit zero-initialization - --> $DIR/invalid_value.rs:88:34 + --> $DIR/invalid_value.rs:92:34 | LL | let _val: NonNull = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -305,7 +305,7 @@ LL | let _val: NonNull = mem::zeroed(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/invalid_value.rs:89:34 + --> $DIR/invalid_value.rs:93:34 | LL | let _val: NonNull = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -316,7 +316,7 @@ LL | let _val: NonNull = mem::uninitialized(); = note: `std::ptr::NonNull` must be non-null error: the type `(NonZeroU32, i32)` does not permit zero-initialization - --> $DIR/invalid_value.rs:91:39 + --> $DIR/invalid_value.rs:95:39 | LL | let _val: (NonZeroU32, i32) = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -327,7 +327,7 @@ LL | let _val: (NonZeroU32, i32) = mem::zeroed(); = note: `std::num::NonZeroU32` must be non-null error: the type `(NonZeroU32, i32)` does not permit being left uninitialized - --> $DIR/invalid_value.rs:92:39 + --> $DIR/invalid_value.rs:96:39 | LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -338,7 +338,7 @@ LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); = note: `std::num::NonZeroU32` must be non-null error: the type `*const dyn Send` does not permit zero-initialization - --> $DIR/invalid_value.rs:94:37 + --> $DIR/invalid_value.rs:98:37 | LL | let _val: *const dyn Send = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -349,7 +349,7 @@ LL | let _val: *const dyn Send = mem::zeroed(); = note: the vtable of a wide raw pointer must be non-null error: the type `*const dyn Send` does not permit being left uninitialized - --> $DIR/invalid_value.rs:95:37 + --> $DIR/invalid_value.rs:99:37 | LL | let _val: *const dyn Send = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -360,7 +360,7 @@ LL | let _val: *const dyn Send = mem::uninitialized(); = note: the vtable of a wide raw pointer must be non-null error: the type `[fn(); 2]` does not permit zero-initialization - --> $DIR/invalid_value.rs:97:31 + --> $DIR/invalid_value.rs:101:31 | LL | let _val: [fn(); 2] = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -371,7 +371,7 @@ LL | let _val: [fn(); 2] = mem::zeroed(); = note: function pointers must be non-null error: the type `[fn(); 2]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:98:31 + --> $DIR/invalid_value.rs:102:31 | LL | let _val: [fn(); 2] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -382,7 +382,7 @@ LL | let _val: [fn(); 2] = mem::uninitialized(); = note: function pointers must be non-null error: the type `TwoUninhabited` does not permit zero-initialization - --> $DIR/invalid_value.rs:100:36 + --> $DIR/invalid_value.rs:104:36 | LL | let _val: TwoUninhabited = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -397,7 +397,7 @@ LL | enum TwoUninhabited { | ^^^^^^^^^^^^^^^^^^^ error: the type `TwoUninhabited` does not permit being left uninitialized - --> $DIR/invalid_value.rs:101:36 + --> $DIR/invalid_value.rs:105:36 | LL | let _val: TwoUninhabited = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -412,7 +412,7 @@ LL | enum TwoUninhabited { | ^^^^^^^^^^^^^^^^^^^ error: the type `OneFruitNonZero` does not permit zero-initialization - --> $DIR/invalid_value.rs:103:37 + --> $DIR/invalid_value.rs:107:37 | LL | let _val: OneFruitNonZero = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -427,7 +427,7 @@ LL | Banana(NonZeroU32), | ^^^^^^^^^^ error: the type `OneFruitNonZero` does not permit being left uninitialized - --> $DIR/invalid_value.rs:104:37 + --> $DIR/invalid_value.rs:108:37 | LL | let _val: OneFruitNonZero = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -442,7 +442,7 @@ LL | Banana(NonZeroU32), | ^^^^^^^^^^ error: the type `bool` does not permit being left uninitialized - --> $DIR/invalid_value.rs:108:26 + --> $DIR/invalid_value.rs:112:26 | LL | let _val: bool = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -453,7 +453,7 @@ LL | let _val: bool = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `Wrap` does not permit being left uninitialized - --> $DIR/invalid_value.rs:111:32 + --> $DIR/invalid_value.rs:115:32 | LL | let _val: Wrap = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -468,7 +468,7 @@ LL | struct Wrap { wrapped: T } | ^^^^^^^^^^ error: the type `NonBig` does not permit being left uninitialized - --> $DIR/invalid_value.rs:114:28 + --> $DIR/invalid_value.rs:118:28 | LL | let _val: NonBig = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -479,7 +479,7 @@ LL | let _val: NonBig = mem::uninitialized(); = note: `NonBig` must be initialized inside its custom valid range error: the type `Fruit` does not permit being left uninitialized - --> $DIR/invalid_value.rs:117:27 + --> $DIR/invalid_value.rs:121:27 | LL | let _val: Fruit = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -494,7 +494,7 @@ LL | enum Fruit { | ^^^^^^^^^^ error: the type `[bool; 2]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:120:31 + --> $DIR/invalid_value.rs:124:31 | LL | let _val: [bool; 2] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -505,7 +505,7 @@ LL | let _val: [bool; 2] = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `i32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:123:25 + --> $DIR/invalid_value.rs:127:25 | LL | let _val: i32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -516,7 +516,7 @@ LL | let _val: i32 = mem::uninitialized(); = note: integers must not be uninitialized error: the type `f32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:126:25 + --> $DIR/invalid_value.rs:130:25 | LL | let _val: f32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -527,7 +527,7 @@ LL | let _val: f32 = mem::uninitialized(); = note: floats must not be uninitialized error: the type `*const ()` does not permit being left uninitialized - --> $DIR/invalid_value.rs:129:31 + --> $DIR/invalid_value.rs:133:31 | LL | let _val: *const () = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -538,7 +538,7 @@ LL | let _val: *const () = mem::uninitialized(); = note: raw pointers must not be uninitialized error: the type `*const [()]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:132:33 + --> $DIR/invalid_value.rs:136:33 | LL | let _val: *const [()] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -548,8 +548,19 @@ LL | let _val: *const [()] = mem::uninitialized(); | = note: raw pointers must not be uninitialized +error: the type `WrapAroundRange` does not permit being left uninitialized + --> $DIR/invalid_value.rs:139:37 + | +LL | let _val: WrapAroundRange = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done + | + = note: `WrapAroundRange` must be initialized inside its custom valid range + error: the type `Result` does not permit being left uninitialized - --> $DIR/invalid_value.rs:137:38 + --> $DIR/invalid_value.rs:144:38 | LL | let _val: Result = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -564,7 +575,7 @@ LL | pub enum Result { | ^^^^^^^^^^^^^^^^^^^^^ error: the type `&i32` does not permit zero-initialization - --> $DIR/invalid_value.rs:145:34 + --> $DIR/invalid_value.rs:152:34 | LL | let _val: &'static i32 = mem::transmute(0usize); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -575,7 +586,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); = note: references must be non-null error: the type `&[i32]` does not permit zero-initialization - --> $DIR/invalid_value.rs:146:36 + --> $DIR/invalid_value.rs:153:36 | LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -586,7 +597,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); = note: references must be non-null error: the type `NonZeroU32` does not permit zero-initialization - --> $DIR/invalid_value.rs:147:32 + --> $DIR/invalid_value.rs:154:32 | LL | let _val: NonZeroU32 = mem::transmute(0); | ^^^^^^^^^^^^^^^^^ @@ -597,7 +608,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); = note: `std::num::NonZeroU32` must be non-null error: the type `NonNull` does not permit zero-initialization - --> $DIR/invalid_value.rs:150:34 + --> $DIR/invalid_value.rs:157:34 | LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -608,7 +619,7 @@ LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `NonNull` does not permit being left uninitialized - --> $DIR/invalid_value.rs:151:34 + --> $DIR/invalid_value.rs:158:34 | LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -619,7 +630,7 @@ LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); = note: `std::ptr::NonNull` must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/invalid_value.rs:152:26 + --> $DIR/invalid_value.rs:159:26 | LL | let _val: bool = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -629,5 +640,5 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init(); | = note: booleans must be either `true` or `false` -error: aborting due to 50 previous errors +error: aborting due to 51 previous errors From 7ff9bc18cd807fec16100e52a780689af233cf29 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 22 Oct 2022 21:28:53 -0700 Subject: [PATCH 10/13] rustdoc: remove no-op CSS `.code-header { border-bottom: none }` The code headers are always h3 or h4, which don't have border-bottom by default anyway. --- 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 9785e1f54c1a4..5a8acc8af6471 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -184,7 +184,6 @@ h4.code-header { } .code-header { font-weight: 600; - border-bottom-style: none; margin: 0; padding: 0; } From f112c3a4186868c02c583eb1094bd4e7bb082357 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 23 Oct 2022 15:40:56 +0200 Subject: [PATCH 11/13] Use functions for jump-to-def-background rustodoc GUI test --- .../rustdoc-gui/jump-to-def-background.goml | 55 ++++++------------- 1 file changed, 17 insertions(+), 38 deletions(-) diff --git a/src/test/rustdoc-gui/jump-to-def-background.goml b/src/test/rustdoc-gui/jump-to-def-background.goml index 31c7d0ce3c88d..b65faf13d0c53 100644 --- a/src/test/rustdoc-gui/jump-to-def-background.goml +++ b/src/test/rustdoc-gui/jump-to-def-background.goml @@ -1,43 +1,22 @@ // We check the background color on the jump to definition links in the source code page. goto: "file://" + |DOC_PATH| + "/src/link_to_definition/lib.rs.html" -// Set the theme to dark. -local-storage: { - "rustdoc-theme": "dark", - "rustdoc-preferred-dark-theme": "dark", - "rustdoc-use-system-theme": "false", -} -// We reload the page so the local storage settings are being used. -reload: - -assert-css: ( - "body.source .example-wrap pre.rust a", - {"background-color": "rgb(51, 51, 51)"}, - ALL, -) - -// Set the theme to ayu. -local-storage: { - "rustdoc-theme": "ayu", - "rustdoc-preferred-dark-theme": "ayu", - "rustdoc-use-system-theme": "false", -} -// We reload the page so the local storage settings are being used. -reload: - -assert-css: ( - "body.source .example-wrap pre.rust a", - {"background-color": "rgb(51, 51, 51)"}, - ALL, +define-function: ( + "check-background-color", + (theme, background_color), + [ + // Set the theme. + ("local-storage", { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }), + // We reload the page so the local storage settings are being used. + ("reload"), + ("assert-css", ( + "body.source .example-wrap pre.rust a", + {"background-color": |background_color|}, + ALL, + )), + ], ) -// Set the theme to light. -local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"} -// We reload the page so the local storage settings are being used. -reload: - -assert-css: ( - "body.source .example-wrap pre.rust a", - {"background-color": "rgb(238, 238, 238)"}, - ALL, -) +call-function: ("check-background-color", ("ayu", "rgb(51, 51, 51)")) +call-function: ("check-background-color", ("dark", "rgb(51, 51, 51)")) +call-function: ("check-background-color", ("light", "rgb(238, 238, 238)")) From 560433ac868e584538efaafdef9108d94d5f682a Mon Sep 17 00:00:00 2001 From: Andrew Tribick Date: Sun, 23 Oct 2022 18:59:24 +0200 Subject: [PATCH 12/13] MaybeUninit: use assume_init_drop() in the partially initialized array example --- library/core/src/mem/maybe_uninit.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index efad9a9391b4c..7757c95de9d2a 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -146,7 +146,6 @@ use crate::slice; /// /// ``` /// use std::mem::MaybeUninit; -/// use std::ptr; /// /// // Create an uninitialized array of `MaybeUninit`. The `assume_init` is /// // safe because the type we are claiming to have initialized here is a @@ -162,7 +161,7 @@ use crate::slice; /// /// // For each item in the array, drop if we allocated it. /// for elem in &mut data[0..data_len] { -/// unsafe { ptr::drop_in_place(elem.as_mut_ptr()); } +/// unsafe { elem.assume_init_drop(); } /// } /// ``` /// From c5df62041950b2279191804841a51077826df9a0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 23 Oct 2022 17:21:43 +0000 Subject: [PATCH 13/13] Annotate static lifetimes too --- compiler/rustc_middle/src/ty/print/pretty.rs | 12 +++--------- .../ui/associated-type-bounds/inside-adt.rs | 4 ++-- .../associated-type-bounds/inside-adt.stderr | 10 +++++----- src/test/ui/associated-types/issue-87261.rs | 6 +++--- .../ui/associated-types/issue-87261.stderr | 18 +++++++++--------- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 2a229e0474382..b1523068799c9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -983,15 +983,9 @@ pub trait PrettyPrinter<'tcx>: write!(self, "Sized")?; } - if let [re] = lifetimes.as_slice() - && re.is_static() - { - // Don't print a single static lifetime - } else { - for re in lifetimes { - write!(self, " + ")?; - self = self.print_region(re)?; - } + for re in lifetimes { + write!(self, " + ")?; + self = self.print_region(re)?; } Ok(self) diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs index f26037f070766..8eb8c44bb420e 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.rs +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -16,7 +16,7 @@ enum E2 { V(Box>) } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions enum E3 { V(dyn Iterator) } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator + 'static)` +//~| ERROR the size for values of type `(dyn Iterator + 'static)` union U1 { f: ManuallyDrop> } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions @@ -25,6 +25,6 @@ union U2 { f: ManuallyDrop>> } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions union U3 { f: ManuallyDrop> } //~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator + 'static)` +//~| ERROR the size for values of type `(dyn Iterator + 'static)` fn main() {} diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr index 978390fa71235..dbfcfa5806309 100644 --- a/src/test/ui/associated-type-bounds/inside-adt.stderr +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -70,13 +70,13 @@ help: the `Box` type always has a statically known size and allocates its conten LL | enum E1 { V(Box>) } | ++++ + -error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time +error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time --> $DIR/inside-adt.rs:17:13 | LL | enum E3 { V(dyn Iterator) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = help: the trait `Sized` is not implemented for `(dyn Iterator + 'static)` = note: no field of an enum variant may have a dynamically sized type = help: change the field's type to have a statically known size help: borrowed types always have a statically known size @@ -107,14 +107,14 @@ help: the `Box` type always has a statically known size and allocates its conten LL | union U1 { f: Box>> } | ++++ + -error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time +error[E0277]: the size for values of type `(dyn Iterator + 'static)` cannot be known at compilation time --> $DIR/inside-adt.rs:26:15 | LL | union U3 { f: ManuallyDrop> } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | - = help: within `ManuallyDrop<(dyn Iterator + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator + 'static)` - = note: required because it appears within the type `ManuallyDrop<(dyn Iterator + 'static)>` + = help: within `ManuallyDrop<(dyn Iterator + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator + 'static)` + = note: required because it appears within the type `ManuallyDrop<(dyn Iterator + 'static)>` = note: no field of a union may have a dynamically sized type = help: change the field's type to have a statically known size help: borrowed types always have a statically known size diff --git a/src/test/ui/associated-types/issue-87261.rs b/src/test/ui/associated-types/issue-87261.rs index 384561f8ccd7e..e8548d402fae5 100644 --- a/src/test/ui/associated-types/issue-87261.rs +++ b/src/test/ui/associated-types/issue-87261.rs @@ -77,10 +77,10 @@ where fn main() { accepts_trait(returns_opaque()); - //~^ ERROR type mismatch resolving `::Associated == ()` + //~^ ERROR type mismatch resolving `::Associated == ()` accepts_trait(returns_opaque_derived()); - //~^ ERROR type mismatch resolving `::Associated == ()` + //~^ ERROR type mismatch resolving `::Associated == ()` accepts_trait(returns_opaque_foo()); //~^ ERROR type mismatch resolving `::Associated == ()` @@ -89,7 +89,7 @@ fn main() { //~^ ERROR type mismatch resolving `::Associated == ()` accepts_generic_trait(returns_opaque_generic()); - //~^ ERROR type mismatch resolving ` as GenericTrait<()>>::Associated == ()` + //~^ ERROR type mismatch resolving ` + 'static as GenericTrait<()>>::Associated == ()` accepts_generic_trait(returns_opaque_generic_foo()); //~^ ERROR type mismatch resolving ` + Foo as GenericTrait<()>>::Associated == ()` diff --git a/src/test/ui/associated-types/issue-87261.stderr b/src/test/ui/associated-types/issue-87261.stderr index f24423dd10666..2cce6b947025e 100644 --- a/src/test/ui/associated-types/issue-87261.stderr +++ b/src/test/ui/associated-types/issue-87261.stderr @@ -132,7 +132,7 @@ note: required by a bound in `accepts_generic_trait` LL | fn accepts_generic_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` -error[E0271]: type mismatch resolving `::Associated == ()` +error[E0271]: type mismatch resolving `::Associated == ()` --> $DIR/issue-87261.rs:79:19 | LL | fn returns_opaque() -> impl Trait + 'static { @@ -144,18 +144,18 @@ LL | accepts_trait(returns_opaque()); | required by a bound introduced by this call | = note: expected unit type `()` - found associated type `::Associated` + found associated type `::Associated` note: required by a bound in `accepts_trait` --> $DIR/issue-87261.rs:43:27 | LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` -help: consider constraining the associated type `::Associated` to `()` +help: consider constraining the associated type `::Associated` to `()` | LL | fn returns_opaque() -> impl Trait + 'static { | +++++++++++++++++ -error[E0271]: type mismatch resolving `::Associated == ()` +error[E0271]: type mismatch resolving `::Associated == ()` --> $DIR/issue-87261.rs:82:19 | LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { @@ -167,13 +167,13 @@ LL | accepts_trait(returns_opaque_derived()); | required by a bound introduced by this call | = note: expected unit type `()` - found associated type `::Associated` + found associated type `::Associated` note: required by a bound in `accepts_trait` --> $DIR/issue-87261.rs:43:27 | LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` -help: consider constraining the associated type `::Associated` to `()` +help: consider constraining the associated type `::Associated` to `()` | LL | fn returns_opaque_derived() -> impl DerivedTrait + 'static { | +++++++++++++++++ @@ -222,7 +222,7 @@ note: required by a bound in `accepts_trait` LL | fn accepts_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_trait` -error[E0271]: type mismatch resolving ` as GenericTrait<()>>::Associated == ()` +error[E0271]: type mismatch resolving ` + 'static as GenericTrait<()>>::Associated == ()` --> $DIR/issue-87261.rs:91:27 | LL | fn returns_opaque_generic() -> impl GenericTrait<()> + 'static { @@ -234,13 +234,13 @@ LL | accepts_generic_trait(returns_opaque_generic()); | required by a bound introduced by this call | = note: expected unit type `()` - found associated type ` as GenericTrait<()>>::Associated` + found associated type ` + 'static as GenericTrait<()>>::Associated` note: required by a bound in `accepts_generic_trait` --> $DIR/issue-87261.rs:44:46 | LL | fn accepts_generic_trait>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `accepts_generic_trait` -help: consider constraining the associated type ` as GenericTrait<()>>::Associated` to `()` +help: consider constraining the associated type ` + 'static as GenericTrait<()>>::Associated` to `()` | LL | fn returns_opaque_generic() -> impl GenericTrait<(), Associated = ()> + 'static { | +++++++++++++++++