From 73d655e9c2106566f328de28aeff6fd3a8ee8e21 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 16 Oct 2022 10:38:48 +0200
Subject: [PATCH 01/15] remove redundant Send impls for references

also move them next to the trait they are implementing
---
 library/core/src/marker.rs                      | 13 ++++++-------
 src/test/ui/async-await/async-fn-nonsend.stderr |  2 +-
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index d5ed52124e2ca..bb10caee6e2dd 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -44,6 +44,12 @@ impl<T: ?Sized> !Send for *const T {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> !Send for *mut T {}
 
+// Most instances arise automatically, but this instance is needed to link up `T: Sync` with
+// `&T: Send` (and it also removes the unsound default instance `T Send` -> `&T: Send` that would
+// otherwise exist).
+#[stable(feature = "rust1", since = "1.0.0")]
+unsafe impl<T: Sync + ?Sized> Send for &T {}
+
 /// Types with a constant size known at compile time.
 ///
 /// All type parameters have an implicit bound of `Sized`. The special syntax
@@ -680,13 +686,6 @@ pub struct PhantomData<T: ?Sized>;
 
 impls! { PhantomData }
 
-mod impls {
-    #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe impl<T: Sync + ?Sized> Send for &T {}
-    #[stable(feature = "rust1", since = "1.0.0")]
-    unsafe impl<T: Send + ?Sized> Send for &mut T {}
-}
-
 /// Compiler-internal trait used to indicate the type of enum discriminants.
 ///
 /// This trait is automatically implemented for every type and does not add any
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 40ad46b48620d..a7b872fe4444a 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -27,7 +27,7 @@ error: future cannot be sent between threads safely
 LL |     assert_send(non_sync_with_method_call());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
    |
-   = help: the trait `Send` is not implemented for `dyn std::fmt::Write`
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
 note: future is not `Send` as this value is used across an await
   --> $DIR/async-fn-nonsend.rs:46:14
    |

From 16104474ad9472481ac7e3da67a35e1d3ad0b2ad Mon Sep 17 00:00:00 2001
From: Pointerbender <pointerbender@gmail.com>
Date: Thu, 20 Oct 2022 08:37:47 +0200
Subject: [PATCH 02/15] clarify documentation about the memory layout of
 `UnsafeCell`

---
 library/core/src/cell.rs | 59 +++++++++++++++++++++++-----------------
 1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 3451a25504e34..12c6f21172596 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1825,35 +1825,44 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// Therefore this is not a valid conversion, despite `NonNull<u8>` and `UnsafeCell<NonNull<u8>>>`
 /// having the same memory layout. This is because `UnsafeCell` disables niche optimizations in
 /// order to avoid its interior mutability property from spreading from `T` into the `Outer` type,
-/// thus this can cause distortions in the type size in these cases. Furthermore, it is only valid
-/// to obtain a `*mut T` pointer to the contents of a _shared_ `UnsafeCell<T>` through [`.get()`]
-/// or [`.raw_get()`]. A `&mut T` reference can be obtained by either dereferencing this pointer or
-/// by calling [`.get_mut()`] on an _exclusive_ `UnsafeCell<T>`, e.g.:
+/// thus this can cause distortions in the type size in these cases.
+///
+/// Note that it is still only valid to obtain a `*mut T` pointer to the contents of a
+/// _shared_ `UnsafeCell<T>` through [`.get()`]  or [`.raw_get()`]. A `&mut T` reference
+/// can be obtained by either dereferencing this pointer or by calling [`.get_mut()`]
+/// on an _exclusive_ `UnsafeCell<T>`. Even though `T` and `UnsafeCell<T>` have the
+/// same memory layout, the following is not allowed and undefined behavior:
+///
+/// ```rust,no_run
+/// # use std::cell::UnsafeCell;
+/// unsafe fn not_allowed<T>(ptr: &UnsafeCell<T>) -> &mut T {
+///   let t = ptr as *const UnsafeCell<T> as *mut T;
+///   // This is undefined behavior, because the `*mut T` pointer
+///   // was not obtained through `.get()` nor `.raw_get()`:
+///   unsafe { &mut *t }
+/// }
+/// ```
+///
+/// Instead, do this:
 ///
 /// ```rust
-/// use std::cell::UnsafeCell;
+/// # use std::cell::UnsafeCell;
+/// // Safety: the caller must ensure that there are no references that
+/// // point to the *contents* of the `UnsafeCell`.
+/// unsafe fn get_mut<T>(ptr: &UnsafeCell<T>) -> &mut T {
+///   unsafe { &mut *ptr.get() }
+/// }
+/// ```
 ///
-/// let mut x: UnsafeCell<u32> = UnsafeCell::new(5);
-/// let shared: &UnsafeCell<u32> = &x;
-/// // using `.get()` is okay:
-/// unsafe {
-///     // SAFETY: there exist no other references to the contents of `x`
-///     let exclusive: &mut u32 = &mut *shared.get();
-/// };
-/// // using `.raw_get()` is also okay:
-/// unsafe {
-///     // SAFETY: there exist no other references to the contents of `x` in this scope
-///     let exclusive: &mut u32 = &mut *UnsafeCell::raw_get(shared as *const _);
-/// };
-/// // using `.get_mut()` is always safe:
-/// let exclusive: &mut u32 = x.get_mut();
+/// Coverting in the other direction from a `&mut T`
+/// to an `&UnsafeCell<T>` is allowed:
 ///
-/// // when we have exclusive access, we can convert it to a shared `&UnsafeCell`:
-/// unsafe {
-///     // SAFETY: `u32` has no niche, therefore it has the same layout as `UnsafeCell<u32>`
-///     let shared: &UnsafeCell<u32> = &*(exclusive as *mut _ as *const UnsafeCell<u32>);
-///     // SAFETY: there exist no other *active* references to the contents of `x` in this scope
-///     let exclusive: &mut u32 = &mut *shared.get();
+/// ```rust
+/// # use std::cell::UnsafeCell;
+/// fn get_shared<T>(ptr: &mut T) -> &UnsafeCell<T> {
+///   let t = ptr as *mut T as *const UnsafeCell<T>;
+///   // SAFETY: `T` and `UnsafeCell<T>` have the same memory layout
+///   unsafe { &*t }
 /// }
 /// ```
 ///

From def755edab084e971394e9d9ba929e205e9a1baa Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Sat, 22 Oct 2022 17:48:31 +0000
Subject: [PATCH 03/15] Clean middle RPITITs correctly in rustdoc

---
 src/librustdoc/clean/mod.rs                   | 122 ++++++++++--------
 src/test/rustdoc/async-trait.rs               |  16 +++
 src/test/rustdoc/auxiliary/async-trait-dep.rs |   9 ++
 3 files changed, 94 insertions(+), 53 deletions(-)
 create mode 100644 src/test/rustdoc/async-trait.rs
 create mode 100644 src/test/rustdoc/auxiliary/async-trait-dep.rs

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 13d63ffa0ee3c..6947e8e8e25aa 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -415,6 +415,16 @@ fn clean_projection<'tcx>(
     cx: &mut DocContext<'tcx>,
     def_id: Option<DefId>,
 ) -> Type {
+    if cx.tcx.def_kind(ty.item_def_id) == DefKind::ImplTraitPlaceholder {
+        let bounds = cx
+            .tcx
+            .explicit_item_bounds(ty.item_def_id)
+            .iter()
+            .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, ty.substs))
+            .collect::<Vec<_>>();
+        return clean_middle_opaque_bounds(cx, bounds);
+    }
+
     let trait_ = clean_trait_ref_with_bindings(cx, ty.trait_ref(cx.tcx), ThinVec::new());
     let self_type = clean_middle_ty(ty.self_ty(), cx, None);
     let self_def_id = if let Some(def_id) = def_id {
@@ -1715,59 +1725,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
                 .iter()
                 .map(|(bound, _)| EarlyBinder(*bound).subst(cx.tcx, substs))
                 .collect::<Vec<_>>();
-            let mut regions = vec![];
-            let mut has_sized = false;
-            let mut bounds = bounds
-                .iter()
-                .filter_map(|bound| {
-                    let bound_predicate = bound.kind();
-                    let trait_ref = match bound_predicate.skip_binder() {
-                        ty::PredicateKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref),
-                        ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
-                            if let Some(r) = clean_middle_region(reg) {
-                                regions.push(GenericBound::Outlives(r));
-                            }
-                            return None;
-                        }
-                        _ => return None,
-                    };
-
-                    if let Some(sized) = cx.tcx.lang_items().sized_trait() {
-                        if trait_ref.def_id() == sized {
-                            has_sized = true;
-                            return None;
-                        }
-                    }
-
-                    let bindings: ThinVec<_> = bounds
-                        .iter()
-                        .filter_map(|bound| {
-                            if let ty::PredicateKind::Projection(proj) = bound.kind().skip_binder()
-                            {
-                                if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
-                                    Some(TypeBinding {
-                                        assoc: projection_to_path_segment(proj.projection_ty, cx),
-                                        kind: TypeBindingKind::Equality {
-                                            term: clean_middle_term(proj.term, cx),
-                                        },
-                                    })
-                                } else {
-                                    None
-                                }
-                            } else {
-                                None
-                            }
-                        })
-                        .collect();
-
-                    Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings))
-                })
-                .collect::<Vec<_>>();
-            bounds.extend(regions);
-            if !has_sized && !bounds.is_empty() {
-                bounds.insert(0, GenericBound::maybe_sized(cx));
-            }
-            ImplTrait(bounds)
+            clean_middle_opaque_bounds(cx, bounds)
         }
 
         ty::Closure(..) => panic!("Closure"),
@@ -1780,6 +1738,64 @@ pub(crate) fn clean_middle_ty<'tcx>(
     }
 }
 
+fn clean_middle_opaque_bounds<'tcx>(
+    cx: &mut DocContext<'tcx>,
+    bounds: Vec<ty::Predicate<'tcx>>,
+) -> Type {
+    let mut regions = vec![];
+    let mut has_sized = false;
+    let mut bounds = bounds
+        .iter()
+        .filter_map(|bound| {
+            let bound_predicate = bound.kind();
+            let trait_ref = match bound_predicate.skip_binder() {
+                ty::PredicateKind::Trait(tr) => bound_predicate.rebind(tr.trait_ref),
+                ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_ty, reg)) => {
+                    if let Some(r) = clean_middle_region(reg) {
+                        regions.push(GenericBound::Outlives(r));
+                    }
+                    return None;
+                }
+                _ => return None,
+            };
+
+            if let Some(sized) = cx.tcx.lang_items().sized_trait() {
+                if trait_ref.def_id() == sized {
+                    has_sized = true;
+                    return None;
+                }
+            }
+
+            let bindings: ThinVec<_> = bounds
+                .iter()
+                .filter_map(|bound| {
+                    if let ty::PredicateKind::Projection(proj) = bound.kind().skip_binder() {
+                        if proj.projection_ty.trait_ref(cx.tcx) == trait_ref.skip_binder() {
+                            Some(TypeBinding {
+                                assoc: projection_to_path_segment(proj.projection_ty, cx),
+                                kind: TypeBindingKind::Equality {
+                                    term: clean_middle_term(proj.term, cx),
+                                },
+                            })
+                        } else {
+                            None
+                        }
+                    } else {
+                        None
+                    }
+                })
+                .collect();
+
+            Some(clean_poly_trait_ref_with_bindings(cx, trait_ref, bindings))
+        })
+        .collect::<Vec<_>>();
+    bounds.extend(regions);
+    if !has_sized && !bounds.is_empty() {
+        bounds.insert(0, GenericBound::maybe_sized(cx));
+    }
+    ImplTrait(bounds)
+}
+
 pub(crate) fn clean_field<'tcx>(field: &hir::FieldDef<'tcx>, cx: &mut DocContext<'tcx>) -> Item {
     let def_id = cx.tcx.hir().local_def_id(field.hir_id).to_def_id();
     clean_field_with_def_id(def_id, field.ident.name, clean_ty(field.ty, cx), cx)
diff --git a/src/test/rustdoc/async-trait.rs b/src/test/rustdoc/async-trait.rs
new file mode 100644
index 0000000000000..a473e467473eb
--- /dev/null
+++ b/src/test/rustdoc/async-trait.rs
@@ -0,0 +1,16 @@
+// aux-build:async-trait-dep.rs
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+extern crate async_trait_dep;
+
+pub struct Oink {}
+
+// @has 'async_trait/struct.Oink.html' '//h4[@class="code-header"]' "async fn woof()"
+impl async_trait_dep::Meow for Oink {
+    async fn woof() {
+        todo!()
+    }
+}
diff --git a/src/test/rustdoc/auxiliary/async-trait-dep.rs b/src/test/rustdoc/auxiliary/async-trait-dep.rs
new file mode 100644
index 0000000000000..10a55dd0260ef
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/async-trait-dep.rs
@@ -0,0 +1,9 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+#![allow(incomplete_features)]
+
+pub trait Meow {
+    /// Who's a good dog?
+    async fn woof();
+}

From 56735361536773aee70f44b76438d1a07b7062e3 Mon Sep 17 00:00:00 2001
From: Pointerbender <81013316+Pointerbender@users.noreply.github.com>
Date: Mon, 24 Oct 2022 04:27:37 +0200
Subject: [PATCH 04/15] fix typos

Co-authored-by: Ralf Jung <post@ralfj.de>
---
 library/core/src/cell.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 12c6f21172596..fe5dd7be8f6b4 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1827,8 +1827,8 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 /// order to avoid its interior mutability property from spreading from `T` into the `Outer` type,
 /// thus this can cause distortions in the type size in these cases.
 ///
-/// Note that it is still only valid to obtain a `*mut T` pointer to the contents of a
-/// _shared_ `UnsafeCell<T>` through [`.get()`]  or [`.raw_get()`]. A `&mut T` reference
+/// Note that the only valid way to obtain a `*mut T` pointer to the contents of a
+/// _shared_ `UnsafeCell<T>` is through [`.get()`]  or [`.raw_get()`]. A `&mut T` reference
 /// can be obtained by either dereferencing this pointer or by calling [`.get_mut()`]
 /// on an _exclusive_ `UnsafeCell<T>`. Even though `T` and `UnsafeCell<T>` have the
 /// same memory layout, the following is not allowed and undefined behavior:

From f9cace081d27469d4f8c4f50218cd5b7c0fbf419 Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Mon, 24 Oct 2022 17:46:23 -0700
Subject: [PATCH 05/15] rustdoc: parse self-closing tags and attributes in
 `invalid_html_tags`

Fixes #103460
---
 src/librustdoc/passes/html_tags.rs            | 55 ++++++++++++-
 .../invalid-html-self-closing-tag.rs          | 70 ++++++++++++++++
 .../invalid-html-self-closing-tag.stderr      | 80 +++++++++++++++++++
 3 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 src/test/rustdoc-ui/invalid-html-self-closing-tag.rs
 create mode 100644 src/test/rustdoc-ui/invalid-html-self-closing-tag.stderr

diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 67fc71665ccf7..a89ed7c7ed454 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -184,7 +184,60 @@ fn extract_html_tag(
                     }
                     drop_tag(tags, tag_name, r, f);
                 } else {
-                    tags.push((tag_name, r));
+                    let mut is_self_closing = false;
+                    let mut quote_pos = None;
+                    if c != '>' {
+                        let mut quote = None;
+                        let mut after_eq = false;
+                        for (i, c) in text[pos..].char_indices() {
+                            if !c.is_whitespace() {
+                                if let Some(q) = quote {
+                                    if c == q {
+                                        quote = None;
+                                        quote_pos = None;
+                                        after_eq = false;
+                                    }
+                                } else if c == '>' {
+                                    break;
+                                } else if c == '/' && !after_eq {
+                                    is_self_closing = true;
+                                } else {
+                                    if is_self_closing {
+                                        is_self_closing = false;
+                                    }
+                                    if (c == '"' || c == '\'') && after_eq {
+                                        quote = Some(c);
+                                        quote_pos = Some(pos + i);
+                                    } else if c == '=' {
+                                        after_eq = true;
+                                    }
+                                }
+                            } else if quote.is_none() {
+                                after_eq = false;
+                            }
+                        }
+                    }
+                    if let Some(quote_pos) = quote_pos {
+                        let qr = Range { start: quote_pos, end: quote_pos };
+                        f(
+                            &format!("unclosed quoted HTML attribute on tag `{}`", tag_name),
+                            &qr,
+                            false,
+                        );
+                    }
+                    if is_self_closing {
+                        // https://html.spec.whatwg.org/#parse-error-non-void-html-element-start-tag-with-trailing-solidus
+                        let valid = ALLOWED_UNCLOSED.contains(&&tag_name[..])
+                            || tags.iter().take(pos + 1).any(|(at, _)| {
+                                let at = at.to_lowercase();
+                                at == "svg" || at == "math"
+                            });
+                        if !valid {
+                            f(&format!("invalid self-closing HTML tag `{}`", tag_name), &r, false);
+                        }
+                    } else {
+                        tags.push((tag_name, r));
+                    }
                 }
             }
             break;
diff --git a/src/test/rustdoc-ui/invalid-html-self-closing-tag.rs b/src/test/rustdoc-ui/invalid-html-self-closing-tag.rs
new file mode 100644
index 0000000000000..d973a53cbc7ce
--- /dev/null
+++ b/src/test/rustdoc-ui/invalid-html-self-closing-tag.rs
@@ -0,0 +1,70 @@
+#![deny(rustdoc::invalid_html_tags)]
+
+/// <p/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct A;
+
+/// <p style/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct B;
+
+/// <p style=""/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct C;
+
+/// <p style="x"/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct D;
+
+/// <p style="x/></p>
+//~^ ERROR unclosed quoted HTML attribute
+pub struct E;
+
+/// <p style='x/></p>
+//~^ ERROR unclosed quoted HTML attribute
+pub struct F;
+
+/// <p style="x/"></p>
+pub struct G;
+
+/// <p style="x/"/>
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct H;
+
+/// <p / >
+//~^ ERROR invalid self-closing HTML tag `p`
+pub struct I;
+
+/// <br/>
+pub struct J;
+
+/// <a href=/></a>
+pub struct K;
+
+/// <a href=//></a>
+pub struct L;
+
+/// <a href="/"/>
+//~^ ERROR invalid self-closing HTML tag `a`
+pub struct M;
+
+/// <a href=x />
+//~^ ERROR invalid self-closing HTML tag `a`
+pub struct N;
+
+/// <a href= />
+//~^ ERROR invalid self-closing HTML tag `a`
+pub struct O;
+
+/// <a href=x/></a>
+pub struct P;
+
+/// <svg><rect width=1 height=1 /></svg>
+pub struct Q;
+
+/// <svg><rect width=1 height=/></svg>
+//~^ ERROR unclosed HTML tag `rect`
+pub struct R;
+
+/// <svg / q>
+pub struct S;
diff --git a/src/test/rustdoc-ui/invalid-html-self-closing-tag.stderr b/src/test/rustdoc-ui/invalid-html-self-closing-tag.stderr
new file mode 100644
index 0000000000000..e45edfb43ff8e
--- /dev/null
+++ b/src/test/rustdoc-ui/invalid-html-self-closing-tag.stderr
@@ -0,0 +1,80 @@
+error: invalid self-closing HTML tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:3:5
+   |
+LL | /// <p/>
+   |     ^^
+   |
+note: the lint level is defined here
+  --> $DIR/invalid-html-self-closing-tag.rs:1:9
+   |
+LL | #![deny(rustdoc::invalid_html_tags)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: invalid self-closing HTML tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:7:5
+   |
+LL | /// <p style/>
+   |     ^^
+
+error: invalid self-closing HTML tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:11:5
+   |
+LL | /// <p style=""/>
+   |     ^^
+
+error: invalid self-closing HTML tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:15:5
+   |
+LL | /// <p style="x"/>
+   |     ^^
+
+error: unclosed quoted HTML attribute on tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:19:14
+   |
+LL | /// <p style="x/></p>
+   |              ^
+
+error: unclosed quoted HTML attribute on tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:23:14
+   |
+LL | /// <p style='x/></p>
+   |              ^
+
+error: invalid self-closing HTML tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:30:5
+   |
+LL | /// <p style="x/"/>
+   |     ^^
+
+error: invalid self-closing HTML tag `p`
+  --> $DIR/invalid-html-self-closing-tag.rs:34:5
+   |
+LL | /// <p / >
+   |     ^^
+
+error: invalid self-closing HTML tag `a`
+  --> $DIR/invalid-html-self-closing-tag.rs:47:5
+   |
+LL | /// <a href="/"/>
+   |     ^^
+
+error: invalid self-closing HTML tag `a`
+  --> $DIR/invalid-html-self-closing-tag.rs:51:5
+   |
+LL | /// <a href=x />
+   |     ^^
+
+error: invalid self-closing HTML tag `a`
+  --> $DIR/invalid-html-self-closing-tag.rs:55:5
+   |
+LL | /// <a href= />
+   |     ^^
+
+error: unclosed HTML tag `rect`
+  --> $DIR/invalid-html-self-closing-tag.rs:65:10
+   |
+LL | /// <svg><rect width=1 height=/></svg>
+   |          ^^^^^
+
+error: aborting due to 12 previous errors
+

From 14caf7396d1875ff96268f48ea0d203fb989d77a Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Fri, 7 Oct 2022 09:29:51 +0000
Subject: [PATCH 06/15] Pull opaque type handling out of the type relating
 delegate

---
 .../src/type_check/relate_tys.rs              | 19 ++++---------------
 .../src/infer/canonical/query_response.rs     | 16 +++++-----------
 .../rustc_infer/src/infer/nll_relate/mod.rs   | 15 ++++++++++-----
 3 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index b53360ea61bbf..ca249938d0405 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -1,6 +1,6 @@
 use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate};
 use rustc_infer::infer::NllRegionVariableOrigin;
-use rustc_infer::traits::ObligationCause;
+use rustc_infer::traits::PredicateObligations;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::TypeRelation;
@@ -155,27 +155,16 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
         true
     }
 
-    fn register_opaque_type(
+    fn register_opaque_type_obligations(
         &mut self,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-        a_is_expected: bool,
+        obligations: PredicateObligations<'tcx>,
     ) -> Result<(), TypeError<'tcx>> {
-        let param_env = self.param_env();
-        let span = self.span();
-        let def_id = self.type_checker.body.source.def_id().expect_local();
-        let body_id = self.type_checker.tcx().hir().local_def_id_to_hir_id(def_id);
-        let cause = ObligationCause::misc(span, body_id);
         self.type_checker
             .fully_perform_op(
                 self.locations,
                 self.category,
                 InstantiateOpaqueType {
-                    obligations: self
-                        .type_checker
-                        .infcx
-                        .handle_opaque_type(a, b, a_is_expected, &cause, param_env)?
-                        .obligations,
+                    obligations,
                     // These fields are filled in during execution of the operation
                     base_universe: None,
                     region_constraints: None,
diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs
index 608b5cc8756a6..4d287988e3360 100644
--- a/compiler/rustc_infer/src/infer/canonical/query_response.rs
+++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs
@@ -16,8 +16,8 @@ use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelating
 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin};
 use crate::traits::query::{Fallible, NoSolution};
-use crate::traits::TraitEngine;
 use crate::traits::{Obligation, ObligationCause, PredicateObligation};
+use crate::traits::{PredicateObligations, TraitEngine};
 use rustc_data_structures::captures::Captures;
 use rustc_index::vec::Idx;
 use rustc_index::vec::IndexVec;
@@ -509,7 +509,7 @@ impl<'tcx> InferCtxt<'tcx> {
         for &(a, b) in &query_response.value.opaque_types {
             let a = substitute_value(self.tcx, &result_subst, a);
             let b = substitute_value(self.tcx, &result_subst, b);
-            obligations.extend(self.handle_opaque_type(a, b, true, cause, param_env)?.obligations);
+            obligations.extend(self.at(cause, param_env).eq(a, b)?.obligations);
         }
 
         Ok(InferOk { value: result_subst, obligations })
@@ -741,17 +741,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
         true
     }
 
-    fn register_opaque_type(
+    fn register_opaque_type_obligations(
         &mut self,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-        a_is_expected: bool,
+        obligations: PredicateObligations<'tcx>,
     ) -> Result<(), TypeError<'tcx>> {
-        self.obligations.extend(
-            self.infcx
-                .handle_opaque_type(a, b, a_is_expected, &self.cause, self.param_env)?
-                .obligations,
-        );
+        self.obligations.extend(obligations);
         Ok(())
     }
 }
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 7c186ae947065..529c72d266aee 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -25,7 +25,9 @@ use crate::infer::combine::ConstEquateRelation;
 use crate::infer::InferCtxt;
 use crate::infer::{ConstVarValue, ConstVariableValue};
 use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
+use crate::traits::PredicateObligation;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
@@ -91,11 +93,9 @@ pub trait TypeRelatingDelegate<'tcx> {
     );
 
     fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>);
-    fn register_opaque_type(
+    fn register_opaque_type_obligations(
         &mut self,
-        a: Ty<'tcx>,
-        b: Ty<'tcx>,
-        a_is_expected: bool,
+        obligations: Vec<PredicateObligation<'tcx>>,
     ) -> Result<(), TypeError<'tcx>>;
 
     /// Creates a new universe index. Used when instantiating placeholders.
@@ -414,7 +414,12 @@ where
             (_, &ty::Opaque(..)) => (generalize(a, true)?, b),
             _ => unreachable!(),
         };
-        self.delegate.register_opaque_type(a, b, true)?;
+        let cause = ObligationCause::dummy_with_span(self.delegate.span());
+        let obligations = self
+            .infcx
+            .handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
+            .obligations;
+        self.delegate.register_opaque_type_obligations(obligations)?;
         trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
         Ok(a)
     }

From 196a429a671209531422a3895140fc16745ac4ea Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Fri, 7 Oct 2022 09:33:22 +0000
Subject: [PATCH 07/15] Use the general type API instead of directly accessing
 register_hidden_type

---
 .../src/region_infer/opaque_types.rs               | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 11a57ef262174..465f353aaa37f 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -263,13 +263,11 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
 
         // Require that the hidden type actually fulfills all the bounds of the opaque type, even without
         // the bounds that the function supplies.
-        match infcx.register_hidden_type(
-            OpaqueTypeKey { def_id, substs: id_substs },
-            ObligationCause::misc(instantiated_ty.span, body_id),
-            param_env,
-            definition_ty,
-            origin,
-        ) {
+        let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs);
+        match infcx
+            .at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env)
+            .eq(opaque_ty, definition_ty)
+        {
             Ok(infer_ok) => {
                 for obligation in infer_ok.obligations {
                     fulfillment_cx.register_predicate_obligation(&infcx, obligation);
@@ -280,7 +278,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
                     .err_ctxt()
                     .report_mismatched_types(
                         &ObligationCause::misc(instantiated_ty.span, body_id),
-                        self.tcx.mk_opaque(def_id.to_def_id(), id_substs),
+                        opaque_ty,
                         definition_ty,
                         err,
                     )

From f3bd222ad9e30245aef89d41defd378eefed70f4 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Fri, 7 Oct 2022 09:56:42 +0000
Subject: [PATCH 08/15] Bubble the opaque type ordering int opaque type
 handling

---
 compiler/rustc_infer/src/infer/opaque_types.rs | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 0a4ecc4c033e1..a982f11f7187f 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -103,7 +103,7 @@ impl<'tcx> InferCtxt<'tcx> {
             return Ok(InferOk { value: (), obligations: vec![] });
         }
         let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
-        let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
+        let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() {
             ty::Opaque(def_id, substs) if def_id.is_local() => {
                 let def_id = def_id.expect_local();
                 let origin = match self.defining_use_anchor {
@@ -169,13 +169,14 @@ impl<'tcx> InferCtxt<'tcx> {
                     param_env,
                     b,
                     origin,
+                    a_is_expected,
                 ))
             }
             _ => None,
         };
-        if let Some(res) = process(a, b) {
+        if let Some(res) = process(a, b, true) {
             res
-        } else if let Some(res) = process(b, a) {
+        } else if let Some(res) = process(b, a, false) {
             res
         } else {
             let (a, b) = self.resolve_vars_if_possible((a, b));
@@ -514,13 +515,14 @@ impl UseKind {
 
 impl<'tcx> InferCtxt<'tcx> {
     #[instrument(skip(self), level = "debug")]
-    pub fn register_hidden_type(
+    fn register_hidden_type(
         &self,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         cause: ObligationCause<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         hidden_ty: Ty<'tcx>,
         origin: hir::OpaqueTyOrigin,
+        a_is_expected: bool,
     ) -> InferResult<'tcx, ()> {
         let tcx = self.tcx;
         let OpaqueTypeKey { def_id, substs } = opaque_type_key;
@@ -539,7 +541,8 @@ impl<'tcx> InferCtxt<'tcx> {
             origin,
         );
         if let Some(prev) = prev {
-            obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations;
+            obligations =
+                self.at(&cause, param_env).eq_exp(a_is_expected, prev, hidden_ty)?.obligations;
         }
 
         let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());

From 2283a5e65bf7efd63e9456f9fa336bfc69f7b277 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 25 Oct 2022 16:13:02 +0400
Subject: [PATCH 09/15] rustc_metadata: Add constructors to module children at
 encoding time

instead of decoding time.
---
 compiler/rustc_metadata/src/rmeta/decoder.rs | 79 +++++++++-----------
 compiler/rustc_metadata/src/rmeta/encoder.rs | 24 ++++--
 2 files changed, 53 insertions(+), 50 deletions(-)

diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 830417eea1a0a..691e3d0f8f902 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -773,7 +773,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
     }
 
     fn opt_item_name(self, item_index: DefIndex) -> Option<Symbol> {
-        self.def_key(item_index).disambiguated_data.data.get_opt_name()
+        let def_key = self.def_key(item_index);
+        def_key.disambiguated_data.data.get_opt_name().or_else(|| {
+            if def_key.disambiguated_data.data == DefPathData::Ctor {
+                let parent_index = def_key.parent.expect("no parent for a constructor");
+                self.def_key(parent_index).disambiguated_data.data.get_opt_name()
+            } else {
+                None
+            }
+        })
     }
 
     fn item_name(self, item_index: DefIndex) -> Symbol {
@@ -905,7 +913,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 .get(self, item_id)
                 .unwrap_or_else(LazyArray::empty)
                 .decode(self)
-                .map(|index| self.get_variant(&self.def_kind(index), index, did))
+                .filter_map(|index| {
+                    let kind = self.def_kind(index);
+                    match kind {
+                        DefKind::Ctor(..) => None,
+                        _ => Some(self.get_variant(&kind, index, did)),
+                    }
+                })
                 .collect()
         } else {
             std::iter::once(self.get_variant(&kind, item_id, did)).collect()
@@ -1029,50 +1043,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
                 callback(ModChild { ident, res, vis, span, macro_rules });
 
-                // For non-re-export structs and variants add their constructors to children.
-                // Re-export lists automatically contain constructors when necessary.
-                match kind {
-                    DefKind::Struct => {
-                        if let Some((ctor_def_id, ctor_kind)) =
-                            self.get_ctor_def_id_and_kind(child_index)
-                        {
-                            let ctor_res =
-                                Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
-                            let vis = self.get_visibility(ctor_def_id.index);
-                            callback(ModChild {
-                                ident,
-                                res: ctor_res,
-                                vis,
-                                span,
-                                macro_rules: false,
-                            });
-                        }
-                    }
-                    DefKind::Variant => {
-                        // Braced variants, unlike structs, generate unusable names in
-                        // value namespace, they are reserved for possible future use.
-                        // It's ok to use the variant's id as a ctor id since an
-                        // error will be reported on any use of such resolution anyway.
-                        let (ctor_def_id, ctor_kind) = self
-                            .get_ctor_def_id_and_kind(child_index)
-                            .unwrap_or((def_id, CtorKind::Fictive));
-                        let ctor_res =
-                            Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
-                        let mut vis = self.get_visibility(ctor_def_id.index);
-                        if ctor_def_id == def_id && vis.is_public() {
-                            // For non-exhaustive variants lower the constructor visibility to
-                            // within the crate. We only need this for fictive constructors,
-                            // for other constructors correct visibilities
-                            // were already encoded in metadata.
-                            let mut attrs = self.get_item_attrs(def_id.index, sess);
-                            if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
-                                let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
-                                vis = ty::Visibility::Restricted(crate_def_id);
-                            }
+                // For non-reexport variants add their fictive constructors to children.
+                // Braced variants, unlike structs, generate unusable names in value namespace,
+                // they are reserved for possible future use. It's ok to use the variant's id as
+                // a ctor id since an error will be reported on any use of such resolution anyway.
+                // Reexport lists automatically contain such constructors when necessary.
+                if kind == DefKind::Variant && self.get_ctor_def_id_and_kind(child_index).is_none()
+                {
+                    let ctor_res =
+                        Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), def_id);
+                    let mut vis = vis;
+                    if vis.is_public() {
+                        // For non-exhaustive variants lower the constructor visibility to
+                        // within the crate. We only need this for fictive constructors,
+                        // for other constructors correct visibilities
+                        // were already encoded in metadata.
+                        let mut attrs = self.get_item_attrs(def_id.index, sess);
+                        if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
+                            vis = ty::Visibility::Restricted(self.local_def_id(CRATE_DEF_INDEX));
                         }
-                        callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
                     }
-                    _ => {}
+                    callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
                 }
             }
         }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index c019211a948e3..61e84a5a01ddb 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1335,6 +1335,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         // Only encode named non-reexport children, reexports are encoded
                         // separately and unnamed items are not used by name resolution.
                         hir::ItemKind::ExternCrate(..) => continue,
+                        hir::ItemKind::Struct(ref vdata, _) => {
+                            yield item_id.def_id.def_id.local_def_index;
+                            // Encode constructors which take a separate slot in value namespace.
+                            if let Some(ctor_hir_id) = vdata.ctor_hir_id() {
+                                yield tcx.hir().local_def_id(ctor_hir_id).local_def_index;
+                            }
+                        }
                         _ if tcx.def_key(item_id.def_id.to_def_id()).get_opt_name().is_some() => {
                             yield item_id.def_id.def_id.local_def_index;
                         }
@@ -1646,12 +1653,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         };
         // FIXME(eddyb) there should be a nicer way to do this.
         match item.kind {
-            hir::ItemKind::Enum(..) => record_array!(self.tables.children[def_id] <-
-                self.tcx.adt_def(def_id).variants().iter().map(|v| {
-                    assert!(v.def_id.is_local());
-                    v.def_id.index
-                })
-            ),
+            hir::ItemKind::Enum(..) => {
+                record_array!(self.tables.children[def_id] <- iter::from_generator(||
+                    for variant in tcx.adt_def(def_id).variants() {
+                        yield variant.def_id.index;
+                        // Encode constructors which take a separate slot in value namespace.
+                        if let Some(ctor_def_id) = variant.ctor_def_id {
+                            yield ctor_def_id.index;
+                        }
+                    }
+                ))
+            }
             hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
                 record_array!(self.tables.children[def_id] <-
                     self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {

From ed142028641079918b95b539f0570e92469687fe Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Tue, 25 Oct 2022 21:24:01 +0200
Subject: [PATCH 10/15] Add flag to forbid recovery in the parser

---
 compiler/rustc_expand/src/mbe/macro_rules.rs |  1 +
 compiler/rustc_parse/src/parser/expr.rs      |  2 ++
 compiler/rustc_parse/src/parser/mod.rs       | 23 ++++++++++++++++++--
 3 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index 1e268542bcd91..f6fe38174f7c5 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -250,6 +250,7 @@ fn expand_macro<'cx>(
     // hacky, but speeds up the `html5ever` benchmark significantly. (Issue
     // 68836 suggests a more comprehensive but more complex change to deal with
     // this situation.)
+    // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
     let parser = parser_from_cx(sess, arg.clone());
 
     // Try each arm's matchers.
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ca216b1cd1008..a781748efc52a 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2112,6 +2112,8 @@ impl<'a> Parser<'a> {
             // HACK: This is needed so we can detect whether we're inside a macro,
             // where regular assumptions about what tokens can follow other tokens
             // don't necessarily apply.
+            && self.may_recover()
+            // FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
             && self.subparser_name.is_none()
         {
             // It is likely that the closure body is a block but where the
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 89c24920f857d..89f7ab930b1a4 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -115,6 +115,12 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath {
     };
 }
 
+#[derive(Clone, Copy)]
+pub enum Recovery {
+    Allowed,
+    Forbidden,
+}
+
 #[derive(Clone)]
 pub struct Parser<'a> {
     pub sess: &'a ParseSess,
@@ -152,12 +158,15 @@ pub struct Parser<'a> {
     /// This allows us to recover when the user forget to add braces around
     /// multiple statements in the closure body.
     pub current_closure: Option<ClosureSpans>,
+    /// Whether the parser is allowed to recover and parse invalid code successfully (and emit a diagnostic as a side effect).
+    /// This is disabled when parsing macro arguments, see #103534
+    pub recovery: Recovery,
 }
 
-// This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure
+// This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
 // it doesn't unintentionally get bigger.
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
-rustc_data_structures::static_assert_size!(Parser<'_>, 328);
+rustc_data_structures::static_assert_size!(Parser<'_>, 336);
 
 /// Stores span information about a closure.
 #[derive(Clone)]
@@ -483,6 +492,7 @@ impl<'a> Parser<'a> {
                 inner_attr_ranges: Default::default(),
             },
             current_closure: None,
+            recovery: Recovery::Allowed,
         };
 
         // Make parser point to the first token.
@@ -491,6 +501,15 @@ impl<'a> Parser<'a> {
         parser
     }
 
+    pub fn forbid_recovery(mut self) -> Self {
+        self.recovery = Recovery::Forbidden;
+        self
+    }
+
+    fn may_recover(&self) -> bool {
+        matches!(self.recovery, Recovery::Allowed)
+    }
+
     pub fn unexpected<T>(&mut self) -> PResult<'a, T> {
         match self.expect_one_of(&[], &[]) {
             Err(e) => Err(e),

From de5517c3ae3c9ec007b49958c56be67247fa2713 Mon Sep 17 00:00:00 2001
From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de>
Date: Wed, 19 Oct 2022 15:49:08 +0000
Subject: [PATCH 11/15] Remove unneeded sub-comparison

---
 compiler/rustc_infer/src/infer/sub.rs | 39 ++++++---------------------
 1 file changed, 8 insertions(+), 31 deletions(-)

diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index a4b55dfa691df..97354ba5d1bd1 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -2,9 +2,7 @@ use super::combine::{CombineFields, RelationDir};
 use super::SubregionOrigin;
 
 use crate::infer::combine::ConstEquateRelation;
-use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::traits::Obligation;
-use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::visit::TypeVisitable;
 use rustc_middle::ty::TyVar;
@@ -130,39 +128,18 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
             (&ty::Opaque(did, ..), _) | (_, &ty::Opaque(did, ..))
                 if self.fields.define_opaque_types && did.is_local() =>
             {
-                let mut generalize = |ty, ty_is_expected| {
-                    let var = infcx.next_ty_var_id_in_universe(
-                        TypeVariableOrigin {
-                            kind: TypeVariableOriginKind::MiscVariable,
-                            span: self.fields.trace.cause.span,
-                        },
-                        ty::UniverseIndex::ROOT,
-                    );
-                    self.fields.instantiate(ty, RelationDir::SubtypeOf, var, ty_is_expected)?;
-                    Ok(infcx.tcx.mk_ty_var(var))
-                };
-                let (a, b) = if self.a_is_expected { (a, b) } else { (b, a) };
-                let (ga, gb) = match (a.kind(), b.kind()) {
-                    (&ty::Opaque(..), _) => (a, generalize(b, true)?),
-                    (_, &ty::Opaque(..)) => (generalize(a, false)?, b),
-                    _ => unreachable!(),
-                };
                 self.fields.obligations.extend(
                     infcx
-                        .handle_opaque_type(ga, gb, true, &self.fields.trace.cause, self.param_env())
-                        // Don't leak any generalized type variables out of this
-                        // subtyping relation in the case of a type error.
-                        .map_err(|err| {
-                            let (ga, gb) = self.fields.infcx.resolve_vars_if_possible((ga, gb));
-                            if let TypeError::Sorts(sorts) = err && sorts.expected == ga && sorts.found == gb {
-                                TypeError::Sorts(ExpectedFound { expected: a, found: b })
-                            } else {
-                                err
-                            }
-                        })?
+                        .handle_opaque_type(
+                            a,
+                            b,
+                            self.a_is_expected,
+                            &self.fields.trace.cause,
+                            self.param_env(),
+                        )?
                         .obligations,
                 );
-                Ok(ga)
+                Ok(a)
             }
             // Optimization of GeneratorWitness relation since we know that all
             // free regions are replaced with bound regions during construction.

From 796114a5b0c66abbb2527257b8a38c4cda964a66 Mon Sep 17 00:00:00 2001
From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com>
Date: Wed, 26 Oct 2022 21:09:28 +0200
Subject: [PATCH 12/15] Add documentation

---
 compiler/rustc_parse/src/parser/mod.rs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 89f7ab930b1a4..4376e5832efbc 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -158,7 +158,7 @@ pub struct Parser<'a> {
     /// This allows us to recover when the user forget to add braces around
     /// multiple statements in the closure body.
     pub current_closure: Option<ClosureSpans>,
-    /// Whether the parser is allowed to recover and parse invalid code successfully (and emit a diagnostic as a side effect).
+    /// Whether the parser is allowed to do recovery.
     /// This is disabled when parsing macro arguments, see #103534
     pub recovery: Recovery,
 }
@@ -506,6 +506,13 @@ impl<'a> Parser<'a> {
         self
     }
 
+    /// Whether the parser is allowed to recover from broken code.
+    ///
+    /// If this returns false, recovering broken code into valid code (especially if this recovery does lookahead)
+    /// is not allowed. All recovery done by the parser must be gated behind this check.
+    ///
+    /// Technically, this only needs to restruct eager recovery by doing lookahead at more tokens.
+    /// But making the distinction is very subtle, and simply forbidding all recovery is a lot simpler to uphold.
     fn may_recover(&self) -> bool {
         matches!(self.recovery, Recovery::Allowed)
     }

From da407ed38f6bcb79683379d59d18e615d2b8dfaa Mon Sep 17 00:00:00 2001
From: nils <48135649+Nilstrieb@users.noreply.github.com>
Date: Wed, 26 Oct 2022 22:06:35 +0200
Subject: [PATCH 13/15] Fix typo

Co-authored-by: Esteban Kuber <estebank@users.noreply.github.com>
---
 compiler/rustc_parse/src/parser/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 4376e5832efbc..5fe29062b85b9 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -511,7 +511,7 @@ impl<'a> Parser<'a> {
     /// If this returns false, recovering broken code into valid code (especially if this recovery does lookahead)
     /// is not allowed. All recovery done by the parser must be gated behind this check.
     ///
-    /// Technically, this only needs to restruct eager recovery by doing lookahead at more tokens.
+    /// Technically, this only needs to restrict eager recovery by doing lookahead at more tokens.
     /// But making the distinction is very subtle, and simply forbidding all recovery is a lot simpler to uphold.
     fn may_recover(&self) -> bool {
         matches!(self.recovery, Recovery::Allowed)

From 4d4b567bcc64921921521a3076d8b4b94c96e441 Mon Sep 17 00:00:00 2001
From: Michael Howell <michael@notriddle.com>
Date: Wed, 26 Oct 2022 21:13:20 -0700
Subject: [PATCH 14/15] rustdoc: remove CSS workaround for Firefox 29
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

CSS variables, which rustdoc now relies on, are only supported in Firefox 31 and later: https://www.mozilla.org/en-US/firefox/31.0/releasenotes/

This means it’s fine to also rely on unprefixed box-sizing, which is supported in Firefox 29 and later: https://www.mozilla.org/en-US/firefox/29.0/releasenotes/
---
 src/librustdoc/html/static/css/rustdoc.css | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index b60c77195639f..9fb694124b702 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -857,9 +857,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 	   causes rounded corners and no border on iOS Safari. */
 	-webkit-appearance: none;
 	/* Override Normalize.css: we have margins and do
-	 not want to overflow - the `moz` attribute is necessary
-	 until Firefox 29, too early to drop at this point */
-	-moz-box-sizing: border-box !important;
+	 not want to overflow */
 	box-sizing: border-box !important;
 	outline: none;
 	border: 1px solid var(--border-color);

From 166d8b8c2b282ba0d0cf4da277cf8829d30df94b Mon Sep 17 00:00:00 2001
From: Pointerbender <pointerbender@gmail.com>
Date: Thu, 27 Oct 2022 06:32:36 +0200
Subject: [PATCH 15/15] add "Memory layout" subsection to documentation of
 `UnsafeCell` for additional clarity

---
 library/core/src/cell.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index fe5dd7be8f6b4..7bf32cb0d98f2 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -1816,6 +1816,8 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> {
 ///
 /// [`.get_mut()`]: `UnsafeCell::get_mut`
 ///
+/// # Memory layout
+///
 /// `UnsafeCell<T>` has the same in-memory representation as its inner type `T`. A consequence
 /// of this guarantee is that it is possible to convert between `T` and `UnsafeCell<T>`.
 /// Special care has to be taken when converting a nested `T` inside of an `Outer<T>` type