about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-12-02 23:00:48 +0000
committerbors <bors@rust-lang.org>2022-12-02 23:00:48 +0000
commite526d123aa4703aa7b85c5b8e70c20b5ee0deade (patch)
treead0429b5719974ff56f53bad7067cd3d827b9bc6
parent32e613bbaafee1bcabba48a2257b838f8d1c03d3 (diff)
parent8e0d83a70c3b4a6dc98aab8f174d2bd74bfc7c67 (diff)
Auto merge of #105187 - matthiaskrgr:rollup-nxyxpko, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #105026 (v8a as default aarch64 target)
 - #105033 (sparc-struct-abi: work around new tail-call optimization)
 - #105144 (Document normalization methods `At::{normalize,query_normalize}`)
 - #105155 (rustdoc: clean up help and settings button CSS)
 - #105162 (Properly synthesize `FnSig` value during cycle)
 - #105163 (Check lifetime param count in `collect_trait_impl_trait_tys`)
 - #105185 (Move `normalize_fn_sig` to `TypeErrCtxt`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_method.rs39
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/inherited.rs29
-rw-r--r--compiler/rustc_infer/src/infer/at.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs33
-rw-r--r--compiler/rustc_middle/src/values.rs20
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs40
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs7
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css29
-rw-r--r--src/test/assembly/asm/aarch64-el2vmsa.rs37
-rw-r--r--src/test/assembly/sparc-struct-abi.rs5
-rw-r--r--src/test/ui/async-await/in-trait/lifetime-mismatch.rs20
-rw-r--r--src/test/ui/async-await/in-trait/lifetime-mismatch.stderr21
-rw-r--r--src/test/ui/query-system/fn-sig-cycle-arity.rs8
-rw-r--r--src/test/ui/query-system/fn-sig-cycle-arity.stderr9
19 files changed, 198 insertions, 151 deletions
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index c9f5dd0f2c6..2fa602520dc 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -494,6 +494,11 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
         .flatten();
     features.extend(feats);
 
+    // FIXME: Move v8a to target definition list when earliest supported LLVM is 14.
+    if get_version() >= (14, 0, 0) && sess.target.arch == "aarch64" {
+        features.push("+v8a".into());
+    }
+
     if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
         sess.emit_err(TargetFeatureDisableOrEnable {
             features: f,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs
index ba58672e759..82a77416a19 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_method.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs
@@ -173,13 +173,11 @@ fn compare_predicate_entailment<'tcx>(
         impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
     debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
 
-    let impl_m_generics = tcx.generics_of(impl_m.def_id);
-    let trait_m_generics = tcx.generics_of(trait_m.def_id);
     let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
     let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
 
     // Check region bounds.
-    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, &trait_m_generics, &impl_m_generics)?;
+    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?;
 
     // Create obligations for each predicate declared by the impl
     // definition in the context of the trait's parameter
@@ -338,6 +336,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
     // First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
     compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
     compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
+    check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
 
     let trait_to_impl_substs = impl_trait_ref.substs;
 
@@ -722,12 +721,14 @@ fn check_region_bounds_on_impl_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m: &ty::AssocItem,
     trait_m: &ty::AssocItem,
-    trait_generics: &ty::Generics,
-    impl_generics: &ty::Generics,
+    delay: bool,
 ) -> Result<(), ErrorGuaranteed> {
-    let trait_params = trait_generics.own_counts().lifetimes;
+    let impl_generics = tcx.generics_of(impl_m.def_id);
     let impl_params = impl_generics.own_counts().lifetimes;
 
+    let trait_generics = tcx.generics_of(trait_m.def_id);
+    let trait_params = trait_generics.own_counts().lifetimes;
+
     debug!(
         "check_region_bounds_on_impl_item: \
             trait_generics={:?} \
@@ -761,12 +762,16 @@ fn check_region_bounds_on_impl_item<'tcx>(
             None
         };
 
-        let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
-            span,
-            item_kind: assoc_item_kind_str(impl_m),
-            ident: impl_m.ident(tcx),
-            generics_span,
-        });
+        let reported = tcx
+            .sess
+            .create_err(LifetimesOrBoundsMismatchOnTrait {
+                span,
+                item_kind: assoc_item_kind_str(impl_m),
+                ident: impl_m.ident(tcx),
+                generics_span,
+            })
+            .emit_unless(delay);
+
         return Err(reported);
     }
 
@@ -1504,18 +1509,10 @@ fn compare_type_predicate_entailment<'tcx>(
     let trait_to_impl_substs =
         impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
 
-    let impl_ty_generics = tcx.generics_of(impl_ty.def_id);
-    let trait_ty_generics = tcx.generics_of(trait_ty.def_id);
     let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
     let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
 
-    check_region_bounds_on_impl_item(
-        tcx,
-        impl_ty,
-        trait_ty,
-        &trait_ty_generics,
-        &impl_ty_generics,
-    )?;
+    check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
 
     let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index ea141e815bf..1e9b5752130 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -22,7 +22,7 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::symbol::Ident;
 use rustc_span::{self, Span};
-use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
+use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
 
 use std::cell::{Cell, RefCell};
 use std::ops::Deref;
@@ -162,6 +162,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             infcx: &self.infcx,
             typeck_results: Some(self.typeck_results.borrow()),
             fallback_has_occurred: self.fallback_has_occurred.get(),
+            normalize_fn_sig: Box::new(|fn_sig| {
+                if fn_sig.has_escaping_bound_vars() {
+                    return fn_sig;
+                }
+                self.probe(|_| {
+                    let ocx = ObligationCtxt::new_in_snapshot(self);
+                    let normalized_fn_sig =
+                        ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig);
+                    if ocx.select_all_or_error().is_empty() {
+                        let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig);
+                        if !normalized_fn_sig.needs_infer() {
+                            return normalized_fn_sig;
+                        }
+                    }
+                    fn_sig
+                })
+            }),
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs
index 869ad07c00d..b33e7b8d68c 100644
--- a/compiler/rustc_hir_typeck/src/inherited.rs
+++ b/compiler/rustc_hir_typeck/src/inherited.rs
@@ -1,7 +1,6 @@
 use super::callee::DeferredCallResolution;
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::HirIdMap;
@@ -11,9 +10,7 @@ use rustc_middle::ty::visit::TypeVisitable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefIdMap;
 use rustc_span::{self, Span};
-use rustc_trait_selection::traits::{
-    self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
-};
+use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
 
 use std::cell::RefCell;
 use std::ops::Deref;
@@ -92,29 +89,7 @@ impl<'tcx> Inherited<'tcx> {
             infcx: tcx
                 .infer_ctxt()
                 .ignoring_regions()
-                .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
-                .with_normalize_fn_sig_for_diagnostic(Lrc::new(move |infcx, fn_sig| {
-                    if fn_sig.has_escaping_bound_vars() {
-                        return fn_sig;
-                    }
-                    infcx.probe(|_| {
-                        let ocx = ObligationCtxt::new_in_snapshot(infcx);
-                        let normalized_fn_sig = ocx.normalize(
-                            &ObligationCause::dummy(),
-                            // FIXME(compiler-errors): This is probably not the right param-env...
-                            infcx.tcx.param_env(def_id),
-                            fn_sig,
-                        );
-                        if ocx.select_all_or_error().is_empty() {
-                            let normalized_fn_sig =
-                                infcx.resolve_vars_if_possible(normalized_fn_sig);
-                            if !normalized_fn_sig.needs_infer() {
-                                return normalized_fn_sig;
-                            }
-                        }
-                        fn_sig
-                    })
-                })),
+                .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)),
             def_id,
             typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
         }
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 2483ab724a4..4429e4f4362 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -77,10 +77,6 @@ impl<'tcx> InferCtxt<'tcx> {
             err_count_on_creation: self.err_count_on_creation,
             in_snapshot: self.in_snapshot.clone(),
             universe: self.universe.clone(),
-            normalize_fn_sig_for_diagnostic: self
-                .normalize_fn_sig_for_diagnostic
-                .as_ref()
-                .map(|f| f.clone()),
             intercrate: self.intercrate,
         }
     }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index e2be8fb12d0..6bd1df97c16 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -95,6 +95,7 @@ pub mod nice_region_error;
 pub struct TypeErrCtxt<'a, 'tcx> {
     pub infcx: &'a InferCtxt<'tcx>,
     pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
+    pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
     pub fallback_has_occurred: bool,
 }
 
@@ -1007,22 +1008,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         }
     }
 
-    fn normalize_fn_sig_for_diagnostic(&self, sig: ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> {
-        if let Some(normalize) = &self.normalize_fn_sig_for_diagnostic {
-            normalize(self, sig)
-        } else {
-            sig
-        }
-    }
-
     /// Given two `fn` signatures highlight only sub-parts that are different.
     fn cmp_fn_sig(
         &self,
         sig1: &ty::PolyFnSig<'tcx>,
         sig2: &ty::PolyFnSig<'tcx>,
     ) -> (DiagnosticStyledString, DiagnosticStyledString) {
-        let sig1 = &self.normalize_fn_sig_for_diagnostic(*sig1);
-        let sig2 = &self.normalize_fn_sig_for_diagnostic(*sig2);
+        let sig1 = &(self.normalize_fn_sig)(*sig1);
+        let sig2 = &(self.normalize_fn_sig)(*sig2);
 
         let get_lifetimes = |sig| {
             use rustc_hir::def::Namespace;
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2bcb47cc383..2ce7cd8beba 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -80,7 +80,6 @@ pub struct InferOk<'tcx, T> {
 }
 pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
 
-pub type Bound<T> = Option<T>;
 pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
 pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
 
@@ -334,9 +333,6 @@ pub struct InferCtxt<'tcx> {
     /// bound.
     universe: Cell<ty::UniverseIndex>,
 
-    normalize_fn_sig_for_diagnostic:
-        Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
-
     /// During coherence we have to assume that other crates may add
     /// additional impls which we currently don't know about.
     ///
@@ -573,8 +569,6 @@ pub struct InferCtxtBuilder<'tcx> {
     considering_regions: bool,
     /// Whether we are in coherence mode.
     intercrate: bool,
-    normalize_fn_sig_for_diagnostic:
-        Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
 }
 
 pub trait TyCtxtInferExt<'tcx> {
@@ -587,7 +581,6 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
             tcx: self,
             defining_use_anchor: DefiningAnchor::Error,
             considering_regions: true,
-            normalize_fn_sig_for_diagnostic: None,
             intercrate: false,
         }
     }
@@ -615,14 +608,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
         self
     }
 
-    pub fn with_normalize_fn_sig_for_diagnostic(
-        mut self,
-        fun: Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
-    ) -> Self {
-        self.normalize_fn_sig_for_diagnostic = Some(fun);
-        self
-    }
-
     /// Given a canonical value `C` as a starting point, create an
     /// inference context that contains each of the bound values
     /// within instantiated as a fresh variable. The `f` closure is
@@ -644,13 +629,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     }
 
     pub fn build(&mut self) -> InferCtxt<'tcx> {
-        let InferCtxtBuilder {
-            tcx,
-            defining_use_anchor,
-            considering_regions,
-            ref normalize_fn_sig_for_diagnostic,
-            intercrate,
-        } = *self;
+        let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
         InferCtxt {
             tcx,
             defining_use_anchor,
@@ -666,9 +645,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             in_snapshot: Cell::new(false),
             skip_leak_check: Cell::new(false),
             universe: Cell::new(ty::UniverseIndex::ROOT),
-            normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
-                .as_ref()
-                .map(|f| f.clone()),
             intercrate,
         }
     }
@@ -709,7 +685,12 @@ impl<'tcx> InferCtxt<'tcx> {
     /// Creates a `TypeErrCtxt` for emitting various inference errors.
     /// During typeck, use `FnCtxt::err_ctxt` instead.
     pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
-        TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false }
+        TypeErrCtxt {
+            infcx: self,
+            typeck_results: None,
+            fallback_has_occurred: false,
+            normalize_fn_sig: Box::new(|fn_sig| fn_sig),
+        }
     }
 
     pub fn is_in_snapshot(&self) -> bool {
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index f4562cdfb88..70b98e59a8b 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -32,13 +32,23 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
 }
 
 impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo]) -> Self {
+    fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo]) -> Self {
         let err = tcx.ty_error();
-        // FIXME(compiler-errors): It would be nice if we could get the
-        // query key, so we could at least generate a fn signature that
-        // has the right arity.
+
+        let arity = if let Some(frame) = stack.get(0)
+            && frame.query.name == "fn_sig"
+            && let Some(def_id) = frame.query.def_id
+            && let Some(node) = tcx.hir().get_if_local(def_id)
+            && let Some(sig) = node.fn_sig()
+        {
+            sig.decl.inputs.len() + sig.decl.implicit_self.has_implicit_self() as usize
+        } else {
+            tcx.sess.abort_if_errors();
+            unreachable!()
+        };
+
         let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
-            [].into_iter(),
+            std::iter::repeat(err).take(arity),
             err,
             false,
             rustc_hir::Unsafety::Normal,
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 99724fb28db..899e30275a0 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -11,8 +11,8 @@ use crate::traits::select::IntercrateAmbiguityCause;
 use crate::traits::util::impl_subject_and_oblig;
 use crate::traits::SkipLeakCheck;
 use crate::traits::{
-    self, Normalized, Obligation, ObligationCause, ObligationCtxt, PredicateObligation,
-    PredicateObligations, SelectionContext,
+    self, Obligation, ObligationCause, ObligationCtxt, PredicateObligation, PredicateObligations,
+    SelectionContext,
 };
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::Diagnostic;
@@ -30,6 +30,8 @@ use std::fmt::Debug;
 use std::iter;
 use std::ops::ControlFlow;
 
+use super::NormalizeExt;
+
 /// Whether we do the orphan check relative to this crate or
 /// to some remote crate.
 #[derive(Copy, Clone, Debug)]
@@ -128,8 +130,8 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
         predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
     };
 
-    let Normalized { value: mut header, obligations } =
-        traits::normalize(selcx, param_env, ObligationCause::dummy(), header);
+    let InferOk { value: mut header, obligations } =
+        selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(header);
 
     header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
     header
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 371367f0deb..c6818a4e57d 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -56,7 +56,6 @@ pub use self::object_safety::astconv_object_safety_violations;
 pub use self::object_safety::is_vtable_safe_method;
 pub use self::object_safety::MethodViolationCode;
 pub use self::object_safety::ObjectSafetyViolation;
-pub(crate) use self::project::{normalize, normalize_to};
 pub use self::project::{normalize_projection_type, NormalizeExt};
 pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
 pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 113803cd179..051660be9c4 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -50,6 +50,10 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>
 pub(super) struct InProgress;
 
 pub trait NormalizeExt<'tcx> {
+    /// Normalize a value using the `AssocTypeNormalizer`.
+    ///
+    /// This normalization should be used when the type contains inference variables or the
+    /// projection may be fallible.
     fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
 }
 
@@ -57,7 +61,7 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
     fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
         let mut selcx = SelectionContext::new(self.infcx);
         let Normalized { value, obligations } =
-            normalize(&mut selcx, self.param_env, self.cause.clone(), value);
+            normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
         InferOk { value, obligations }
     }
 }
@@ -303,37 +307,6 @@ fn project_and_unify_type<'cx, 'tcx>(
     }
 }
 
-/// Normalizes any associated type projections in `value`, replacing
-/// them with a fully resolved type where possible. The return value
-/// combines the normalized result and any additional obligations that
-/// were incurred as result.
-pub(crate) fn normalize<'a, 'b, 'tcx, T>(
-    selcx: &'a mut SelectionContext<'b, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    cause: ObligationCause<'tcx>,
-    value: T,
-) -> Normalized<'tcx, T>
-where
-    T: TypeFoldable<'tcx>,
-{
-    let mut obligations = Vec::new();
-    let value = normalize_to(selcx, param_env, cause, value, &mut obligations);
-    Normalized { value, obligations }
-}
-
-pub(crate) fn normalize_to<'a, 'b, 'tcx, T>(
-    selcx: &'a mut SelectionContext<'b, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    cause: ObligationCause<'tcx>,
-    value: T,
-    obligations: &mut Vec<PredicateObligation<'tcx>>,
-) -> T
-where
-    T: TypeFoldable<'tcx>,
-{
-    normalize_with_depth_to(selcx, param_env, cause, 0, value, obligations)
-}
-
 /// As `normalize`, but with a custom depth.
 pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
     selcx: &'a mut SelectionContext<'b, 'tcx>,
@@ -2324,10 +2297,11 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
         },
     ));
 
-    let ty = super::normalize_to(
+    let ty = normalize_with_depth_to(
         selcx,
         obligation.param_env,
         cause.clone(),
+        obligation.recursion_depth + 1,
         tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
             .map_bound(|tys| {
                 tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 1aed6630870..f899321fc01 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -23,6 +23,13 @@ use super::NoSolution;
 pub use rustc_middle::traits::query::NormalizationResult;
 
 pub trait QueryNormalizeExt<'tcx> {
+    /// Normalize a value using the `QueryNormalizer`.
+    ///
+    /// This normalization should *only* be used when the projection does not
+    /// have possible ambiguity or may not be well-formed.
+    ///
+    /// After codegen, when lifetimes do not matter, it is preferable to instead
+    /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
     fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
     where
         T: TypeFoldable<'tcx>;
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 6bff2cd2f1a..e9f2e025774 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -908,6 +908,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
 
 .popover {
 	position: absolute;
+	top: 100%;
 	right: 0;
 	z-index: 2;
 	display: block;
@@ -1357,22 +1358,24 @@ a.test-arrow:hover {
 }
 #settings-menu, #help-button {
 	margin-left: 4px;
-	outline: none;
+	display: flex;
 }
 
 #settings-menu > a, #help-button > a, #copy-path {
 	width: 33px;
-	line-height: 1.5;
 }
 
 #settings-menu > a, #help-button > a {
-	padding: 5px;
-	height: 100%;
-	display: block;
+	display: flex;
+	align-items: center;
+	justify-content: center;
 	background-color: var(--button-background-color);
 	border: 1px solid var(--border-color);
 	border-radius: 2px;
 	color: var(--settings-button-color);
+	/* Rare exception to specifying font sizes in rem. Since this is acting
+	   as an icon, it's okay to specify their sizes in pixels. */
+	font-size: 20px;
 }
 
 #settings-menu > a:hover, #settings-menu > a:focus,
@@ -1408,14 +1411,6 @@ a.test-arrow:hover {
 	animation: rotating 2s linear infinite;
 }
 
-#help-button > a {
-	text-align: center;
-	/* Rare exception to specifying font sizes in rem. Since this is acting
-	   as an icon, it's okay to specify their sizes in pixels. */
-	font-size: 20px;
-	padding-top: 2px;
-}
-
 kbd {
 	display: inline-block;
 	padding: 3px 5px;
@@ -1658,10 +1653,6 @@ in storage.js
 		content: "Since ";
 	}
 
-	#copy-path {
-		display: none;
-	}
-
 	/* Hide the logo and item name from the sidebar. Those are displayed
 	   in the mobile-topbar instead. */
 	.sidebar .sidebar-logo,
@@ -1795,8 +1786,8 @@ in storage.js
 		border-bottom: 1px solid;
 	}
 
-	/* We don't display the help button on mobile devices. */
-	#help-button {
+	/* We don't display these buttons on mobile devices. */
+	#copy-path, #help-button {
 		display: none;
 	}
 
diff --git a/src/test/assembly/asm/aarch64-el2vmsa.rs b/src/test/assembly/asm/aarch64-el2vmsa.rs
new file mode 100644
index 00000000000..1908ffb8ff3
--- /dev/null
+++ b/src/test/assembly/asm/aarch64-el2vmsa.rs
@@ -0,0 +1,37 @@
+// assembly-output: emit-asm
+// compile-flags: --target aarch64-unknown-linux-gnu
+// needs-llvm-components: aarch64
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![crate_type = "rlib"]
+#![no_core]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+
+// CHECK-LABEL: ttbr0_el2:
+#[no_mangle]
+pub fn ttbr0_el2() {
+    // CHECK: //APP
+    // CHECK-NEXT: msr TTBR0_EL2, x0
+    // CHECK-NEXT: //NO_APP
+    unsafe {
+        asm!("msr ttbr0_el2, x0");
+    }
+}
+
+// CHECK-LABEL: vttbr_el2:
+#[no_mangle]
+pub fn vttbr_el2() {
+    // CHECK: //APP
+    // CHECK-NEXT: msr VTTBR_EL2, x0
+    // CHECK-NEXT: //NO_APP
+    unsafe {
+        asm!("msr vttbr_el2, x0");
+    }
+}
diff --git a/src/test/assembly/sparc-struct-abi.rs b/src/test/assembly/sparc-struct-abi.rs
index 6a898b2974a..6309dd420ff 100644
--- a/src/test/assembly/sparc-struct-abi.rs
+++ b/src/test/assembly/sparc-struct-abi.rs
@@ -44,12 +44,16 @@ pub unsafe extern "C" fn callee(arg: Franta) {
     tst_use(arg.b);
     tst_use(arg.c);
     tst_use(arg.d);
+    tail_call_avoidance_fn();
 }
 
 extern "C" {
     fn opaque_callee(arg: Franta, intarg: i32);
     fn tst_use(arg: f32);
     fn clobber();
+    // This exists so that post-https://reviews.llvm.org/D138741 LLVM doesn't
+    // tail-call away some of our assertions.
+    fn tail_call_avoidance_fn();
 }
 
 #[no_mangle]
@@ -62,4 +66,5 @@ pub unsafe extern "C" fn caller() {
     // CHECK: call opaque_callee
     // CHECK: mov     3, %o2
     opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
+    tail_call_avoidance_fn();
 }
diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.rs b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs
new file mode 100644
index 00000000000..45ede193c0f
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.rs
@@ -0,0 +1,20 @@
+// edition:2021
+
+#![feature(async_fn_in_trait)]
+//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+
+trait MyTrait {
+    async fn foo<'a>(&self);
+    async fn bar(&self);
+}
+
+impl MyTrait for i32 {
+    async fn foo(&self) {}
+    //~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration
+
+    async fn bar(&self) {
+        self.foo();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
new file mode 100644
index 00000000000..d87adcc78b6
--- /dev/null
+++ b/src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
@@ -0,0 +1,21 @@
+warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/lifetime-mismatch.rs:3:12
+   |
+LL | #![feature(async_fn_in_trait)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
+  --> $DIR/lifetime-mismatch.rs:12:17
+   |
+LL |     async fn foo<'a>(&self);
+   |                 ---- lifetimes in impl do not match this method in trait
+...
+LL |     async fn foo(&self) {}
+   |                 ^ lifetimes do not match method in trait
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0195`.
diff --git a/src/test/ui/query-system/fn-sig-cycle-arity.rs b/src/test/ui/query-system/fn-sig-cycle-arity.rs
new file mode 100644
index 00000000000..7a9b8469c9e
--- /dev/null
+++ b/src/test/ui/query-system/fn-sig-cycle-arity.rs
@@ -0,0 +1,8 @@
+trait Dancer {
+    fn dance(&self) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+        self.dance()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/query-system/fn-sig-cycle-arity.stderr b/src/test/ui/query-system/fn-sig-cycle-arity.stderr
new file mode 100644
index 00000000000..67e0c254551
--- /dev/null
+++ b/src/test/ui/query-system/fn-sig-cycle-arity.stderr
@@ -0,0 +1,9 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/fn-sig-cycle-arity.rs:2:24
+   |
+LL |     fn dance(&self) -> _ {
+   |                        ^ not allowed in type signatures
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.