about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs19
-rw-r--r--compiler/rustc_macros/src/diagnostics/error.rs10
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs2
-rw-r--r--compiler/rustc_macros/src/diagnostics/utils.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs16
-rw-r--r--library/core/src/slice/raw.rs24
-rw-r--r--src/doc/style-guide/src/README.md63
-rw-r--r--src/doc/style-guide/src/SUMMARY.md8
-rw-r--r--src/doc/style-guide/src/advice.md6
-rw-r--r--src/doc/style-guide/src/cargo.md21
-rw-r--r--src/doc/style-guide/src/expressions.md2
-rw-r--r--src/doc/style-guide/src/items.md30
-rw-r--r--src/doc/style-guide/src/principles.md32
-rw-r--r--src/doc/style-guide/src/statements.md12
-rw-r--r--src/librustdoc/html/format.rs17
-rw-r--r--src/librustdoc/html/render/mod.rs4
-rw-r--r--tests/rustdoc/where.SWhere_Echo_impl.html2
-rw-r--r--tests/rustdoc/where.SWhere_Simd_item-decl.html2
-rw-r--r--tests/rustdoc/where.alpha_trait_decl.html3
-rw-r--r--tests/rustdoc/where.bravo_trait_decl.html5
-rw-r--r--tests/rustdoc/where.charlie_fn_decl.html2
-rw-r--r--tests/rustdoc/where.golf_type_alias_decl.html2
-rw-r--r--tests/rustdoc/where.rs5
-rw-r--r--tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs40
-rw-r--r--tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr17
-rw-r--r--tests/ui/error-codes/E0283.stderr4
-rw-r--r--tests/ui/error-codes/E0790.stderr4
-rw-r--r--tests/ui/use/use-keyword.rs2
29 files changed, 242 insertions, 116 deletions
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index acca1a1477f..a4e0e773a81 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -278,7 +278,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
         move_from_span: Span,
         move_from_desc: &str,
     ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> {
-        struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc,)
+        struct_span_err!(self, move_from_span, E0507, "cannot move out of {}", move_from_desc)
     }
 
     /// Signal an error due to an attempt to move out of the interior
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index e759fd6bc94..762176ecfc7 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -12,6 +12,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir_analysis::autoderef::{self, Autoderef};
 use rustc_infer::infer::canonical::OriginalQueryValues;
 use rustc_infer::infer::canonical::{Canonical, QueryResponse};
+use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_infer::infer::DefineOpaqueTypes;
 use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
 use rustc_middle::middle::stability;
@@ -448,15 +449,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 }
             } else {
-                // Encountered a real ambiguity, so abort the lookup. If `ty` is not
-                // an `Err`, report the right "type annotations needed" error pointing
-                // to it.
+                // Ended up encountering a type variable when doing autoderef,
+                // but it may not be a type variable after processing obligations
+                // in our local `FnCtxt`, so don't call `structurally_resolved_type`.
                 let ty = &bad_ty.ty;
                 let ty = self
                     .probe_instantiate_query_response(span, &orig_values, ty)
                     .unwrap_or_else(|_| span_bug!(span, "instantiating {:?} failed?", ty));
-                let ty = self.structurally_resolved_type(span, ty.value);
-                assert!(matches!(ty.kind(), ty::Error(_)));
+                let ty = self.resolve_vars_if_possible(ty.value);
+                let guar = match *ty.kind() {
+                    ty::Infer(ty::TyVar(_)) => self
+                        .err_ctxt()
+                        .emit_inference_failure_err(self.body_id, span, ty.into(), E0282, true)
+                        .emit(),
+                    ty::Error(guar) => guar,
+                    _ => bug!("unexpected bad final type in method autoderef"),
+                };
+                self.demand_eqtype(span, ty, self.tcx.ty_error(guar));
                 return Err(MethodError::NoMatch(NoMatchData {
                     static_candidates: Vec::new(),
                     unsatisfied_predicates: Vec::new(),
diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs
index b37dc826d28..84b18a62028 100644
--- a/compiler/rustc_macros/src/diagnostics/error.rs
+++ b/compiler/rustc_macros/src/diagnostics/error.rs
@@ -54,7 +54,7 @@ fn path_to_string(path: &syn::Path) -> String {
 
 /// Returns an error diagnostic on span `span` with msg `msg`.
 #[must_use]
-pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic {
+pub(crate) fn span_err<T: Into<String>>(span: impl MultiSpan, msg: T) -> Diagnostic {
     Diagnostic::spanned(span, Level::Error, msg)
 }
 
@@ -77,11 +77,9 @@ pub(crate) fn invalid_attr(attr: &Attribute) -> Diagnostic {
     let span = attr.span().unwrap();
     let path = path_to_string(attr.path());
     match attr.meta {
-        Meta::Path(_) => span_err(span, &format!("`#[{path}]` is not a valid attribute")),
-        Meta::NameValue(_) => {
-            span_err(span, &format!("`#[{path} = ...]` is not a valid attribute"))
-        }
-        Meta::List(_) => span_err(span, &format!("`#[{path}(...)]` is not a valid attribute")),
+        Meta::Path(_) => span_err(span, format!("`#[{path}]` is not a valid attribute")),
+        Meta::NameValue(_) => span_err(span, format!("`#[{path} = ...]` is not a valid attribute")),
+        Meta::List(_) => span_err(span, format!("`#[{path}(...)]` is not a valid attribute")),
     }
 }
 
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index e3d9eb96574..e8dc986914e 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -200,7 +200,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
 
                 throw_span_err!(
                     attr.span().unwrap(),
-                    &format!(
+                    format!(
                         "diagnostic slug must be first argument of a `#[{name}(...)]` attribute"
                     )
                 );
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index 85dd9f6a3ce..12563292181 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -347,7 +347,7 @@ pub(crate) trait HasFieldMap {
                 None => {
                     span_err(
                         span.unwrap(),
-                        &format!("`{field}` doesn't refer to a field on this type"),
+                        format!("`{field}` doesn't refer to a field on this type"),
                     )
                     .emit();
                     quote! {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 75a92af714b..67745f04641 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -2382,17 +2382,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             && let Some(impl_def_id) = trait_impls.non_blanket_impls().values().flatten().next()
                         {
                             let non_blanket_impl_count = trait_impls.non_blanket_impls().values().flatten().count();
-                            let message = if non_blanket_impl_count == 1 {
-                                "use the fully-qualified path to the only available implementation".to_string()
-                            } else {
+                            // If there is only one implementation of the trait, suggest using it.
+                            // Otherwise, use a placeholder comment for the implementation.
+                            let (message, impl_suggestion) = if non_blanket_impl_count == 1 {(
+                                "use the fully-qualified path to the only available implementation".to_string(),
+                                format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
+                            )} else {(
                                 format!(
                                     "use a fully-qualified path to a specific available implementation ({} found)",
                                     non_blanket_impl_count
-                                )
-                            };
+                                ),
+                                "</* self type */ as ".to_string()
+                            )};
                             let mut suggestions = vec![(
                                 path.span.shrink_to_lo(),
-                                format!("<{} as ", self.tcx.type_of(impl_def_id).subst_identity())
+                                impl_suggestion
                             )];
                             if let Some(generic_arg) = trait_path_segment.args {
                                 let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext);
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 052fd34d0b6..48a6eb03b5e 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -32,7 +32,8 @@ use crate::ptr;
 /// * The memory referenced by the returned slice must not be mutated for the duration
 ///   of lifetime `'a`, except inside an `UnsafeCell`.
 ///
-/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`,
+///   and adding that size to `data` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
 /// # Caveat
@@ -125,7 +126,8 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
 ///   (not derived from the return value) for the duration of lifetime `'a`.
 ///   Both read and write accesses are forbidden.
 ///
-/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`,
+///   and adding that size to `data` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
 /// [valid]: ptr#safety
@@ -179,15 +181,16 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] {
 ///   the last element, such that the offset from the end to the start pointer is
 ///   the length of the slice.
 ///
-/// * The range must contain `N` consecutive properly initialized values of type `T`:
+/// * The entire memory range of this slice must be contained within a single allocated object!
+///   Slices can never span across multiple allocated objects.
 ///
-///     * The entire memory range of this slice must be contained within a single allocated object!
-///       Slices can never span across multiple allocated objects.
+/// * The range must contain `N` consecutive properly initialized values of type `T`.
 ///
 /// * The memory referenced by the returned slice must not be mutated for the duration
 ///   of lifetime `'a`, except inside an `UnsafeCell`.
 ///
-/// * The total length of the range must be no larger than `isize::MAX`.
+/// * The total length of the range must be no larger than `isize::MAX`,
+///   and adding that size to `data` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
 /// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements.
@@ -247,16 +250,17 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] {
 ///   the last element, such that the offset from the end to the start pointer is
 ///   the length of the slice.
 ///
-/// * The range must contain `N` consecutive properly initialized values of type `T`:
+/// * The entire memory range of this slice must be contained within a single allocated object!
+///   Slices can never span across multiple allocated objects.
 ///
-///     * The entire memory range of this slice must be contained within a single allocated object!
-///       Slices can never span across multiple allocated objects.
+/// * The range must contain `N` consecutive properly initialized values of type `T`.
 ///
 /// * The memory referenced by the returned slice must not be accessed through any other pointer
 ///   (not derived from the return value) for the duration of lifetime `'a`.
 ///   Both read and write accesses are forbidden.
 ///
-/// * The total length of the range must be no larger than `isize::MAX`.
+/// * The total length of the range must be no larger than `isize::MAX`,
+///   and adding that size to `data` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
 /// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements.
diff --git a/src/doc/style-guide/src/README.md b/src/doc/style-guide/src/README.md
index adb73a7eef6..75013bb3df9 100644
--- a/src/doc/style-guide/src/README.md
+++ b/src/doc/style-guide/src/README.md
@@ -16,9 +16,21 @@ Rust code has similar formatting, less mental effort is required to comprehend a
 new project, lowering the barrier to entry for new developers.
 
 Thus, there are productivity benefits to using a formatting tool (such as
-rustfmt), and even larger benefits by using a community-consistent formatting,
-typically by using a formatting tool's default settings.
+`rustfmt`), and even larger benefits by using a community-consistent
+formatting, typically by using a formatting tool's default settings.
 
+## The default Rust style
+
+The Rust Style Guide defines the default Rust style, and *recommends* that
+developers and tools follow the default Rust style. Tools such as `rustfmt` use
+the style guide as a reference for the default style. Everything in this style
+guide, whether or not it uses language such as "must" or the imperative mood
+such as "insert a space ..." or "break the line after ...", refers to the
+default style.
+
+This should not be interpreted as forbidding developers from following a
+non-default style, or forbidding tools from adding any particular configuration
+options.
 
 ## Formatting conventions
 
@@ -28,8 +40,47 @@ typically by using a formatting tool's default settings.
 * Each level of indentation must be four spaces (that is, all indentation
   outside of string literals and comments must be a multiple of four).
 * The maximum width for a line is 100 characters.
-* A tool should be configurable for all three of these variables.
+* A tool may choose to make some of these configurable.
+
+#### Block indent
+
+Prefer block indent over visual indent:
+
+```rust
+// Block indent
+a_function_call(
+    foo,
+    bar,
+);
+
+// Visual indent
+a_function_call(foo,
+                bar);
+```
 
+This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above
+example) and less rightward drift.
+
+### Trailing commas
+
+Lists should have a trailing comma when followed by a newline:
+
+```rust
+function_call(
+    argument,
+    another_argument,
+);
+
+let array = [
+    element,
+    another_element,
+    yet_another_element,
+];
+```
+
+This makes moving code (e.g., by copy and paste) easier, and makes diffs
+smaller, as appending or removing items does not require modifying another line
+to add or remove a comma.
 
 ### Blank lines
 
@@ -48,11 +99,7 @@ fn bar() {}
 fn baz() {}
 ```
 
-Formatting tools should make the bounds on blank lines configurable: there
-should be separate minimum and maximum numbers of newlines between both
-statements and (top-level) items (i.e., four options). As described above, the
-defaults for both statements and items should be minimum: 1, maximum: 2.
-
+Formatting tools may wish to make the bounds on blank lines configurable.
 
 ### [Module-level items](items.md)
 ### [Statements](statements.md)
diff --git a/src/doc/style-guide/src/SUMMARY.md b/src/doc/style-guide/src/SUMMARY.md
index 004692fa6a2..59fe9fdc669 100644
--- a/src/doc/style-guide/src/SUMMARY.md
+++ b/src/doc/style-guide/src/SUMMARY.md
@@ -2,10 +2,10 @@
 
 [Introduction](README.md)
 
-- [Module-level items](items.md)
+- [Items](items.md)
 - [Statements](statements.md)
 - [Expressions](expressions.md)
-- [Types](types.md)
-- [Non-formatting conventions](advice.md)
+- [Types and Bounds](types.md)
+- [Other style advice](advice.md)
 - [`Cargo.toml` conventions](cargo.md)
-- [Principles used for deciding these guidelines](principles.md)
+- [Guiding principles and rationale](principles.md)
diff --git a/src/doc/style-guide/src/advice.md b/src/doc/style-guide/src/advice.md
index ab4b92b0a24..9a617be509c 100644
--- a/src/doc/style-guide/src/advice.md
+++ b/src/doc/style-guide/src/advice.md
@@ -25,9 +25,9 @@ if y {
  * Local variables shall be `snake_case`,
  * Macro names shall be `snake_case`,
  * Constants (`const`s and immutable `static`s) shall be `SCREAMING_SNAKE_CASE`.
- * When a name is forbidden because it is a reserved word (e.g., `crate`), use a
-   trailing underscore to make the name legal (e.g., `crate_`), or use raw
-   identifiers if possible.
+ * When a name is forbidden because it is a reserved word (such as `crate`),
+   either use a raw identifier (`r#crate`) or use a trailing underscore
+   (`crate_`). Don't misspell the word (`krate`).
 
 ### Modules
 
diff --git a/src/doc/style-guide/src/cargo.md b/src/doc/style-guide/src/cargo.md
index 13b96ca8c5e..d3b67ae4582 100644
--- a/src/doc/style-guide/src/cargo.md
+++ b/src/doc/style-guide/src/cargo.md
@@ -1,4 +1,4 @@
-# Cargo.toml conventions
+# `Cargo.toml` conventions
 
 ## Formatting conventions
 
@@ -25,16 +25,17 @@ not indent any key names; start all key names at the start of a line.
 Use multi-line strings (rather than newline escape sequences) for any string
 values that include multiple lines, such as the crate description.
 
-For array values, such as a list of authors, put the entire list on the same
+For array values, such as a list of features, put the entire list on the same
 line as the key, if it fits. Otherwise, use block indentation: put a newline
 after the opening square bracket, indent each item by one indentation level,
 put a comma after each item (including the last), and put the closing square
 bracket at the start of a line by itself after the last item.
 
 ```rust
-authors = [
-    "A Uthor <a.uthor@example.org>",
-    "Another Author <author@example.net>",
+some_feature = [
+    "another_feature",
+    "yet_another_feature",
+    "some_dependency?/some_feature",
 ]
 ```
 
@@ -54,11 +55,11 @@ version = "4.5.6"
 
 ## Metadata conventions
 
-The authors list should consist of strings that each contain an author name
-followed by an email address in angle brackets: `Full Name <email@address>`.
-It should not contain bare email addresses, or names without email addresses.
-(The authors list may also include a mailing list address without an associated
-name.)
+The authors list, if present, should consist of strings that each contain an
+author name followed by an email address in angle brackets: `Full Name
+<email@address>`. It should not contain bare email addresses, or names without
+email addresses. (The authors list may also include a mailing list address
+without an associated name.)
 
 The license field must contain a valid [SPDX
 expression](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60),
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 96f66c89c25..8271b42da4c 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -690,7 +690,7 @@ Where it is possible to use a block form on the right-hand side and avoid
 breaking the left-hand side, do that. E.g.
 
 ```rust
-    // Assuming the following line does done fit in the max width
+    // Assuming the following line does not fit in the max width
     a_very_long_pattern | another_pattern => ALongStructName {
         ...
     },
diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md
index 2835975355f..1e0e60248bf 100644
--- a/src/doc/style-guide/src/items.md
+++ b/src/doc/style-guide/src/items.md
@@ -1,5 +1,10 @@
 ## Items
 
+Items consist of the set of things permitted at the top level of a module.
+However, Rust also allows some items to appear within some other types of
+items, such as within a function. The same formatting conventions apply whether
+an item appears at module level or within another item.
+
 `extern crate` statements must be first in a file. They must be ordered
 alphabetically.
 
@@ -15,8 +20,8 @@ Tools should make the above ordering optional.
 
 ### Function definitions
 
-In Rust, one finds functions by searching for `fn [function-name]`; It's
-important that you style your code so that it's very searchable in this way.
+In Rust, people often find functions by searching for `fn [function-name]`, so
+the formatting of function definitions shold enable this.
 
 The proper ordering and spacing is:
 
@@ -63,8 +68,9 @@ let y = (11, 22, 33);
 
 In the declaration, put each variant on its own line, block indented.
 
-Format each variant accordingly as either a struct, tuple struct, or identifier,
-which doesn't require special formatting (but without the `struct` keyword.
+Format each variant accordingly as either a struct (but without the `struct`
+keyword), a tuple struct, or an identifier (which doesn't require special
+formatting):
 
 ```rust
 enum FooBar {
@@ -139,7 +145,7 @@ union Foo {
 
 Put the whole struct on one line if possible. Types in the parentheses should be
 separated by a comma and space with no trailing comma. No spaces around the
-parentheses or semi-colon:
+parentheses or semicolon:
 
 ```rust
 pub struct Foo(String, u8);
@@ -230,7 +236,7 @@ impl Bar
 
 `extern crate foo;`
 
-Use spaces around keywords, no spaces around the semi-colon.
+Use spaces around keywords, no spaces around the semicolon.
 
 
 ### Modules
@@ -245,7 +251,7 @@ mod foo;
 ```
 
 Use spaces around keywords and before the opening brace, no spaces around the
-semi-colon.
+semicolon.
 
 ### macro\_rules!
 
@@ -478,8 +484,8 @@ foo::{
 A *group* of imports is a set of imports on the same or sequential lines. One or
 more blank lines or other items (e.g., a function) separate groups of imports.
 
-Within a group of imports, imports must be sorted ascii-betically. Groups of
-imports must not be merged or re-ordered.
+Within a group of imports, imports must be sorted ASCIIbetically (uppercase
+before lowercase). Groups of imports must not be merged or re-ordered.
 
 
 E.g., input:
@@ -505,13 +511,9 @@ use b;
 Because of `macro_use`, attributes must also start a new group and prevent
 re-ordering.
 
-Note that tools which only have access to syntax (such as Rustfmt) cannot tell
-which imports are from an external crate or the std lib, etc.
-
-
 #### Ordering list import
 
-Names in a list import must be sorted ascii-betically, but with `self` and
+Names in a list import must be sorted ASCIIbetically, but with `self` and
 `super` first, and groups and glob imports last. This applies recursively. For
 example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g.,
 `use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`.
diff --git a/src/doc/style-guide/src/principles.md b/src/doc/style-guide/src/principles.md
index 2d203f264e6..d548693e39e 100644
--- a/src/doc/style-guide/src/principles.md
+++ b/src/doc/style-guide/src/principles.md
@@ -1,7 +1,7 @@
 # Guiding principles and rationale
 
-When deciding on style guidelines, the style team tried to be guided by the
-following principles (in rough priority order):
+When deciding on style guidelines, the style team follows these guiding
+principles (in rough priority order):
 
 * readability
     - scan-ability
@@ -19,35 +19,11 @@ following principles (in rough priority order):
 * specifics
     - compatibility with version control practices - preserving diffs,
       merge-friendliness, etc.
-    - preventing right-ward drift
+    - preventing rightward drift
     - minimising vertical space
 
 * application
     - ease of manual application
-    - ease of implementation (in Rustfmt, and in other tools/editors/code generators)
+    - ease of implementation (in `rustfmt`, and in other tools/editors/code generators)
     - internal consistency
     - simplicity of formatting rules
-
-
-## Overarching guidelines
-
-Prefer block indent over visual indent. E.g.,
-
-```rust
-// Block indent
-a_function_call(
-    foo,
-    bar,
-);
-
-// Visual indent
-a_function_call(foo,
-                bar);
-```
-
-This makes for smaller diffs (e.g., if `a_function_call` is renamed in the above
-example) and less rightward drift.
-
-Lists should have a trailing comma when followed by a newline, see the block
-indent example above. This choice makes moving code (e.g., by copy and paste)
-easier and makes smaller diffs.
diff --git a/src/doc/style-guide/src/statements.md b/src/doc/style-guide/src/statements.md
index 671e6d31a57..62a5a032f07 100644
--- a/src/doc/style-guide/src/statements.md
+++ b/src/doc/style-guide/src/statements.md
@@ -1,7 +1,9 @@
+## Statements
+
 ### Let statements
 
 There should be spaces after the `:` and on both sides of the `=` (if they are
-present). No space before the semi-colon.
+present). No space before the semicolon.
 
 ```rust
 // A comment.
@@ -194,7 +196,7 @@ used to determine whether a let-else statement is *short*.
 ### Macros in statement position
 
 A macro use in statement position should use parentheses or square brackets as
-delimiters and should be terminated with a semi-colon. There should be no spaces
+delimiters and should be terminated with a semicolon. There should be no spaces
 between the name, `!`, the delimiters, or the `;`.
 
 ```rust
@@ -205,13 +207,13 @@ a_macro!(...);
 
 ### Expressions in statement position
 
-There should be no space between the expression and the semi-colon.
+There should be no space between the expression and the semicolon.
 
 ```
 <expr>;
 ```
 
-All expressions in statement position should be terminated with a semi-colon,
+All expressions in statement position should be terminated with a semicolon,
 unless they end with a block or are used as the value for a block.
 
 E.g.,
@@ -229,7 +231,7 @@ loop {
 }
 ```
 
-Use a semi-colon where an expression has void type, even if it could be
+Use a semicolon where an expression has void type, even if it could be
 propagated. E.g.,
 
 ```rust
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index f26d74629dd..b710311c858 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -347,13 +347,19 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
             }
         } else {
             let mut br_with_padding = String::with_capacity(6 * indent + 28);
-            br_with_padding.push_str("\n");
+            br_with_padding.push('\n');
 
-            let padding_amount =
-                if ending == Ending::Newline { indent + 4 } else { indent + "fn where ".len() };
+            let where_indent = 3;
+            let padding_amount = if ending == Ending::Newline {
+                indent + 4
+            } else if indent == 0 {
+                4
+            } else {
+                indent + where_indent + "where ".len()
+            };
 
             for _ in 0..padding_amount {
-                br_with_padding.push_str(" ");
+                br_with_padding.push(' ');
             }
             let where_preds = where_preds.to_string().replace('\n', &br_with_padding);
 
@@ -370,7 +376,8 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
                     let where_preds = where_preds.replacen(&br_with_padding, " ", 1);
 
                     let mut clause = br_with_padding;
-                    clause.truncate(clause.len() - "where ".len());
+                    // +1 is for `\n`.
+                    clause.truncate(indent + 1 + where_indent);
 
                     write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
                     clause
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index f15c9bacec0..f923f905451 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -860,8 +860,8 @@ fn assoc_method(
     w.reserve(header_len + "<a href=\"\" class=\"fn\">{".len() + "</a>".len());
     write!(
         w,
-        "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a{href} class=\"fn\">{name}</a>\
-         {generics}{decl}{notable_traits}{where_clause}",
+        "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn \
+         <a{href} class=\"fn\">{name}</a>{generics}{decl}{notable_traits}{where_clause}",
         indent = indent_str,
         vis = vis,
         constness = constness,
diff --git a/tests/rustdoc/where.SWhere_Echo_impl.html b/tests/rustdoc/where.SWhere_Echo_impl.html
new file mode 100644
index 00000000000..7517eb090f4
--- /dev/null
+++ b/tests/rustdoc/where.SWhere_Echo_impl.html
@@ -0,0 +1,2 @@
+<h3 class="code-header">impl&lt;D&gt; <a class="struct" href="struct.Delta.html" title="struct foo::Delta">Delta</a>&lt;D&gt;<span class="where fmt-newline">where
+    D: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></h3>
\ No newline at end of file
diff --git a/tests/rustdoc/where.SWhere_Simd_item-decl.html b/tests/rustdoc/where.SWhere_Simd_item-decl.html
index ef4294c8f76..3e72ba2b74f 100644
--- a/tests/rustdoc/where.SWhere_Simd_item-decl.html
+++ b/tests/rustdoc/where.SWhere_Simd_item-decl.html
@@ -1,3 +1,3 @@
 <pre class="rust item-decl"><code>pub struct Simd&lt;T&gt;(_)
 <span class="where">where
-         T: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code></pre>
\ No newline at end of file
+    T: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code></pre>
diff --git a/tests/rustdoc/where.alpha_trait_decl.html b/tests/rustdoc/where.alpha_trait_decl.html
new file mode 100644
index 00000000000..a7700055c9a
--- /dev/null
+++ b/tests/rustdoc/where.alpha_trait_decl.html
@@ -0,0 +1,3 @@
+<code>pub struct Alpha&lt;A&gt;(_)
+<span class="where">where
+    A: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code>
\ No newline at end of file
diff --git a/tests/rustdoc/where.bravo_trait_decl.html b/tests/rustdoc/where.bravo_trait_decl.html
new file mode 100644
index 00000000000..00524201a8a
--- /dev/null
+++ b/tests/rustdoc/where.bravo_trait_decl.html
@@ -0,0 +1,5 @@
+<code>pub trait Bravo&lt;B&gt;<span class="where fmt-newline">where
+    B: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span>{
+    // Required method
+    fn <a href="#tymethod.get" class="fn">get</a>(&amp;self, B: B);
+}</code>
\ No newline at end of file
diff --git a/tests/rustdoc/where.charlie_fn_decl.html b/tests/rustdoc/where.charlie_fn_decl.html
new file mode 100644
index 00000000000..8e3bc8b01ec
--- /dev/null
+++ b/tests/rustdoc/where.charlie_fn_decl.html
@@ -0,0 +1,2 @@
+<code>pub fn charlie&lt;C&gt;()<span class="where fmt-newline">where
+    C: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a>,</span></code>
\ No newline at end of file
diff --git a/tests/rustdoc/where.golf_type_alias_decl.html b/tests/rustdoc/where.golf_type_alias_decl.html
new file mode 100644
index 00000000000..8da5402f900
--- /dev/null
+++ b/tests/rustdoc/where.golf_type_alias_decl.html
@@ -0,0 +1,2 @@
+<code>pub type Golf&lt;T&gt;<span class="where fmt-newline">where
+    T: <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a>,</span> = <a class="primitive" href="{{channel}}/std/primitive.tuple.html">(T, T)</a>;</code>
\ No newline at end of file
diff --git a/tests/rustdoc/where.rs b/tests/rustdoc/where.rs
index 8b8a126e89d..2aa9c8b5461 100644
--- a/tests/rustdoc/where.rs
+++ b/tests/rustdoc/where.rs
@@ -5,16 +5,20 @@ use std::io::Lines;
 pub trait MyTrait { fn dummy(&self) { } }
 
 // @has foo/struct.Alpha.html '//pre' "pub struct Alpha<A>(_) where A: MyTrait"
+// @snapshot alpha_trait_decl - '//*[@class="rust item-decl"]/code'
 pub struct Alpha<A>(A) where A: MyTrait;
 // @has foo/trait.Bravo.html '//pre' "pub trait Bravo<B>where B: MyTrait"
+// @snapshot bravo_trait_decl - '//*[@class="rust item-decl"]/code'
 pub trait Bravo<B> where B: MyTrait { fn get(&self, B: B); }
 // @has foo/fn.charlie.html '//pre' "pub fn charlie<C>()where C: MyTrait"
+// @snapshot charlie_fn_decl - '//*[@class="rust item-decl"]/code'
 pub fn charlie<C>() where C: MyTrait {}
 
 pub struct Delta<D>(D);
 
 // @has foo/struct.Delta.html '//*[@class="impl"]//h3[@class="code-header"]' \
 //          "impl<D> Delta<D>where D: MyTrait"
+// @snapshot SWhere_Echo_impl - '//*[@id="impl-Delta%3CD%3E"]/h3[@class="code-header"]'
 impl<D> Delta<D> where D: MyTrait {
     pub fn delta() {}
 }
@@ -65,4 +69,5 @@ impl<F> MyTrait for Foxtrot<F>where F: MyTrait {}
 
 // @has foo/type.Golf.html '//pre[@class="rust item-decl"]' \
 //          "type Golf<T>where T: Clone, = (T, T)"
+// @snapshot golf_type_alias_decl - '//*[@class="rust item-decl"]/code'
 pub type Golf<T> where T: Clone = (T, T);
diff --git a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs
new file mode 100644
index 00000000000..d8034d57e8d
--- /dev/null
+++ b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.rs
@@ -0,0 +1,40 @@
+use std::ops::Deref;
+use std::rc::Rc;
+
+struct Value<T>(T);
+
+pub trait Wrap<T> {
+    fn wrap() -> Self;
+}
+
+impl<R, A1, A2> Wrap<fn(A1, A2) -> R> for Value<fn(A1, A2) -> R> {
+    fn wrap() -> Self {
+        todo!()
+    }
+}
+
+impl<F, R, A1, A2> Wrap<F> for Value<Rc<dyn Fn(A1, A2) -> R>> {
+    fn wrap() -> Self {
+        todo!()
+    }
+}
+
+impl<F> Deref for Value<Rc<F>> {
+    type Target = F;
+
+    fn deref(&self) -> &Self::Target {
+        &*self.0
+    }
+}
+
+fn main() {
+    let var_fn = Value::wrap();
+    //~^ ERROR type annotations needed for `Value<Rc<_>>`
+
+    // The combination of `Value: Wrap` obligation plus the autoderef steps
+    // (caused by the `Deref` impl above) actually means that the self type
+    // of the method fn below is constrained to be `Value<Rc<dyn Fn(?0, ?1) -> ?2>>`.
+    // However, that's only known to us on the error path -- we still need
+    // to emit an ambiguity error, though.
+    let _ = var_fn.clone();
+}
diff --git a/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr
new file mode 100644
index 00000000000..06a7e90858c
--- /dev/null
+++ b/tests/ui/autoref-autoderef/deref-ambiguity-becomes-nonambiguous.stderr
@@ -0,0 +1,17 @@
+error[E0282]: type annotations needed for `Value<Rc<_>>`
+  --> $DIR/deref-ambiguity-becomes-nonambiguous.rs:31:9
+   |
+LL |     let var_fn = Value::wrap();
+   |         ^^^^^^
+...
+LL |     let _ = var_fn.clone();
+   |                    ----- type must be known at this point
+   |
+help: consider giving `var_fn` an explicit type, where the placeholders `_` are specified
+   |
+LL |     let var_fn: Value<Rc<_>> = Value::wrap();
+   |               ++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/error-codes/E0283.stderr b/tests/ui/error-codes/E0283.stderr
index 90316c6e981..89e634a7064 100644
--- a/tests/ui/error-codes/E0283.stderr
+++ b/tests/ui/error-codes/E0283.stderr
@@ -9,8 +9,8 @@ LL |     let cont: u32 = Generator::create();
    |
 help: use a fully-qualified path to a specific available implementation (2 found)
    |
-LL |     let cont: u32 = <Impl as Generator>::create();
-   |                     ++++++++          +
+LL |     let cont: u32 = </* self type */ as Generator>::create();
+   |                     +++++++++++++++++++          +
 
 error[E0283]: type annotations needed
   --> $DIR/E0283.rs:35:24
diff --git a/tests/ui/error-codes/E0790.stderr b/tests/ui/error-codes/E0790.stderr
index fc025a3fca2..7248766285d 100644
--- a/tests/ui/error-codes/E0790.stderr
+++ b/tests/ui/error-codes/E0790.stderr
@@ -65,8 +65,8 @@ LL |     MyTrait2::my_fn();
    |
 help: use a fully-qualified path to a specific available implementation (2 found)
    |
-LL |     <Impl1 as MyTrait2>::my_fn();
-   |     +++++++++         +
+LL |     </* self type */ as MyTrait2>::my_fn();
+   |     +++++++++++++++++++         +
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/use/use-keyword.rs b/tests/ui/use/use-keyword.rs
index c30c2e06c45..840cddcb907 100644
--- a/tests/ui/use/use-keyword.rs
+++ b/tests/ui/use/use-keyword.rs
@@ -1,4 +1,4 @@
-// Check that imports with nakes super and self don't fail during parsing
+// Check that imports with naked super and self don't fail during parsing
 // FIXME: this shouldn't fail during name resolution either
 
 mod a {