about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs24
-rw-r--r--compiler/rustc_middle/src/thir.rs4
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs9
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs12
-rw-r--r--compiler/rustc_query_impl/src/lib.rs2
-rw-r--r--compiler/rustc_query_impl/src/plumbing.rs10
-rw-r--r--compiler/rustc_query_impl/src/util.rs18
-rw-r--r--compiler/rustc_query_system/src/query/job.rs15
-rw-r--r--compiler/rustc_query_system/src/query/mod.rs31
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs103
-rw-r--r--src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir5
-rw-r--r--src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir5
-rw-r--r--src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir5
-rw-r--r--src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir5
-rw-r--r--src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir3
-rw-r--r--src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir3
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir3
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir3
-rw-r--r--src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff4
-rw-r--r--src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff3
-rw-r--r--src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff6
-rw-r--r--src/test/ui/generic-associated-types/bugs/issue-88382.stderr8
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-60283.rs4
-rw-r--r--src/test/ui/higher-rank-trait-bounds/issue-60283.stderr42
27 files changed, 114 insertions, 221 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 5642d01de5d..2126487da02 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2533,7 +2533,7 @@ pub enum ConstantKind<'tcx> {
 
 impl<'tcx> Constant<'tcx> {
     pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
-        match self.literal.try_to_scalar() {
+        match self.literal.const_for_ty()?.val().try_to_scalar() {
             Some(Scalar::Ptr(ptr, _size)) => match tcx.global_alloc(ptr.provenance) {
                 GlobalAlloc::Static(def_id) => {
                     assert!(!tcx.is_thread_local_static(def_id));
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 12f9b9b97c0..935a9b8e95d 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -17,8 +17,9 @@ use rustc_middle::mir::interpret::{
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::MirSource;
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitor};
 use rustc_target::abi::Size;
+use std::ops::ControlFlow;
 
 const INDENT: &str = "    ";
 /// Alignment for lining up comments following MIR statements
@@ -663,7 +664,6 @@ pub fn write_allocations<'tcx>(
     fn alloc_ids_from_alloc(alloc: &Allocation) -> impl DoubleEndedIterator<Item = AllocId> + '_ {
         alloc.relocations().values().map(|id| *id)
     }
-
     fn alloc_ids_from_const(val: ConstValue<'_>) -> impl Iterator<Item = AllocId> + '_ {
         match val {
             ConstValue::Scalar(interpret::Scalar::Ptr(ptr, _size)) => {
@@ -677,29 +677,17 @@ pub fn write_allocations<'tcx>(
             }
         }
     }
-
     struct CollectAllocIds(BTreeSet<AllocId>);
-
-    impl<'tcx> Visitor<'tcx> for CollectAllocIds {
-        fn visit_const(&mut self, c: ty::Const<'tcx>, _loc: Location) {
+    impl<'tcx> TypeVisitor<'tcx> for CollectAllocIds {
+        fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
             if let ty::ConstKind::Value(val) = c.val() {
                 self.0.extend(alloc_ids_from_const(val));
             }
-        }
-
-        fn visit_constant(&mut self, c: &Constant<'tcx>, loc: Location) {
-            match c.literal {
-                ConstantKind::Ty(c) => self.visit_const(c, loc),
-                ConstantKind::Val(val, _) => {
-                    self.0.extend(alloc_ids_from_const(val));
-                }
-            }
+            c.super_visit_with(self)
         }
     }
-
     let mut visitor = CollectAllocIds(Default::default());
-    visitor.visit_body(body);
-
+    body.visit_with(&mut visitor);
     // `seen` contains all seen allocations, including the ones we have *not* printed yet.
     // The protocol is to first `insert` into `seen`, and only if that returns `true`
     // then push to `todo`.
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 04bc0c8b521..40dce281c82 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -17,7 +17,6 @@ use rustc_index::newtype_index;
 use rustc_index::vec::IndexVec;
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::middle::region;
-use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::mir::{
     BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp, UserTypeProjection,
 };
@@ -420,8 +419,7 @@ pub enum ExprKind<'tcx> {
     /// This is only distinguished from `Literal` so that we can register some
     /// info for diagnostics.
     StaticRef {
-        alloc_id: AllocId,
-        ty: Ty<'tcx>,
+        literal: Const<'tcx>,
         def_id: DefId,
     },
     /// Inline assembly, i.e. `asm!()`.
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index b3e2cb132a2..95489ac3ab2 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -123,7 +123,7 @@ pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Exp
         }
         Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
         Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
-        StaticRef { .. } => {}
+        StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
         InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
             for op in &**operands {
                 use InlineAsmOperand::*;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 0c0b0f2bd05..79ac09d523d 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -1,7 +1,6 @@
 //! See docs in build/expr/mod.rs
 
 use crate::build::Builder;
-use rustc_middle::mir::interpret::{ConstValue, Scalar};
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
 use rustc_middle::ty::CanonicalUserTypeAnnotation;
@@ -27,12 +26,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 assert_eq!(literal.ty(), ty);
                 Constant { span, user_ty, literal: literal.into() }
             }
-            ExprKind::StaticRef { alloc_id, ty, .. } => {
-                let const_val =
-                    ConstValue::Scalar(Scalar::from_pointer(alloc_id.into(), &this.tcx));
-                let literal = ConstantKind::Val(const_val, ty);
-
-                Constant { span, user_ty: None, literal }
+            ExprKind::StaticRef { literal, .. } => {
+                Constant { span, user_ty: None, literal: literal.into() }
             }
             ExprKind::ConstBlock { value } => {
                 Constant { span: span, user_ty: None, literal: value.into() }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 5a7e1d88dd0..651edc827c3 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -8,6 +8,7 @@ use rustc_middle::hir::place::Place as HirPlace;
 use rustc_middle::hir::place::PlaceBase as HirPlaceBase;
 use rustc_middle::hir::place::ProjectionKind as HirProjectionKind;
 use rustc_middle::middle::region;
+use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::{BinOp, BorrowKind, Field, UnOp};
 use rustc_middle::thir::*;
 use rustc_middle::ty::adjustment::{
@@ -940,8 +941,15 @@ impl<'tcx> Cx<'tcx> {
                 let kind = if self.tcx.is_thread_local_static(id) {
                     ExprKind::ThreadLocalRef(id)
                 } else {
-                    let alloc_id = self.tcx.create_static_alloc(id);
-                    ExprKind::StaticRef { alloc_id, ty, def_id: id }
+                    let ptr = self.tcx.create_static_alloc(id);
+                    ExprKind::StaticRef {
+                        literal: ty::Const::from_scalar(
+                            self.tcx,
+                            Scalar::from_pointer(ptr.into(), &self.tcx),
+                            ty,
+                        ),
+                        def_id: id,
+                    }
                 };
                 ExprKind::Deref {
                     arg: self.thir.exprs.push(Expr { ty, temp_lifetime, span: expr.span, kind }),
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 55e95e1a592..832540a85e7 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -44,8 +44,6 @@ pub use on_disk_cache::OnDiskCache;
 mod profiling_support;
 pub use self::profiling_support::alloc_self_profile_query_strings;
 
-mod util;
-
 fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String {
     if def_id.is_top_level_module() {
         "top-level module".to_string()
diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs
index 683d56d5d0f..073ddf01afb 100644
--- a/compiler/rustc_query_impl/src/plumbing.rs
+++ b/compiler/rustc_query_impl/src/plumbing.rs
@@ -290,13 +290,11 @@ macro_rules! define_queries {
                 } else {
                     Some(key.default_span(*tcx))
                 };
-                let def_id = key.key_as_def_id();
-                let def_kind = def_id
+                // Use `tcx.hir().opt_def_kind()` to reduce the chance of
+                // accidentally triggering an infinite query loop.
+                let def_kind = key.key_as_def_id()
                     .and_then(|def_id| def_id.as_local())
-                    // Use `tcx.hir().opt_def_kind()` to reduce the chance of
-                    // accidentally triggering an infinite query loop.
-                    .and_then(|def_id| tcx.hir().opt_def_kind(def_id))
-                    .map(|def_kind| $crate::util::def_kind_to_simple_def_kind(def_kind));
+                    .and_then(|def_id| tcx.hir().opt_def_kind(def_id));
                 let hash = || {
                     let mut hcx = tcx.create_stable_hashing_context();
                     let mut hasher = StableHasher::new();
diff --git a/compiler/rustc_query_impl/src/util.rs b/compiler/rustc_query_impl/src/util.rs
deleted file mode 100644
index 517c107b5d9..00000000000
--- a/compiler/rustc_query_impl/src/util.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use rustc_hir::def::DefKind;
-use rustc_query_system::query::SimpleDefKind;
-
-/// Convert a [`DefKind`] to a [`SimpleDefKind`].
-///
-/// *See [`SimpleDefKind`]'s docs for more information.*
-pub(crate) fn def_kind_to_simple_def_kind(def_kind: DefKind) -> SimpleDefKind {
-    match def_kind {
-        DefKind::Struct => SimpleDefKind::Struct,
-        DefKind::Enum => SimpleDefKind::Enum,
-        DefKind::Union => SimpleDefKind::Union,
-        DefKind::Trait => SimpleDefKind::Trait,
-        DefKind::TyAlias => SimpleDefKind::TyAlias,
-        DefKind::TraitAlias => SimpleDefKind::TraitAlias,
-
-        _ => SimpleDefKind::Other,
-    }
-}
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index adf878a7f04..4588403925e 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -1,6 +1,7 @@
 use crate::dep_graph::DepContext;
 use crate::query::plumbing::CycleError;
-use crate::query::{QueryContext, QueryStackFrame, SimpleDefKind};
+use crate::query::{QueryContext, QueryStackFrame};
+use rustc_hir::def::DefKind;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, Handler, Level};
@@ -556,15 +557,13 @@ pub(crate) fn report_cycle<'a>(
     }
 
     if stack.iter().all(|entry| {
-        entry.query.def_kind.map_or(false, |def_kind| {
-            matches!(def_kind, SimpleDefKind::TyAlias | SimpleDefKind::TraitAlias)
-        })
+        entry
+            .query
+            .def_kind
+            .map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias | DefKind::TraitAlias))
     }) {
         if stack.iter().all(|entry| {
-            entry
-                .query
-                .def_kind
-                .map_or(false, |def_kind| matches!(def_kind, SimpleDefKind::TyAlias))
+            entry.query.def_kind.map_or(false, |def_kind| matches!(def_kind, DefKind::TyAlias))
         }) {
             err.note("type aliases cannot be recursive");
             err.help("consider using a struct, enum, or union instead to break the cycle");
diff --git a/compiler/rustc_query_system/src/query/mod.rs b/compiler/rustc_query_system/src/query/mod.rs
index 361ae3c4352..de64ebb6203 100644
--- a/compiler/rustc_query_system/src/query/mod.rs
+++ b/compiler/rustc_query_system/src/query/mod.rs
@@ -19,6 +19,7 @@ use crate::dep_graph::{DepNodeIndex, HasDepContext, SerializedDepNodeIndex};
 use rustc_data_structures::sync::Lock;
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_errors::Diagnostic;
+use rustc_hir::def::DefKind;
 use rustc_span::Span;
 
 /// Description of a frame in the query stack.
@@ -29,46 +30,20 @@ pub struct QueryStackFrame {
     pub name: &'static str,
     pub description: String,
     span: Option<Span>,
-    /// The `DefKind` this query frame is associated with, if applicable.
-    ///
-    /// We can't use `rustc_hir::def::DefKind` because `rustc_hir` is not
-    /// available in `rustc_query_system`. Instead, we have a simplified
-    /// custom version of it, called [`SimpleDefKind`].
-    def_kind: Option<SimpleDefKind>,
+    def_kind: Option<DefKind>,
     /// This hash is used to deterministically pick
     /// a query to remove cycles in the parallel compiler.
     #[cfg(parallel_compiler)]
     hash: u64,
 }
 
-/// A simplified version of `rustc_hir::def::DefKind`.
-///
-/// It was added to help improve cycle errors caused by recursive type aliases.
-/// As of August 2021, `rustc_query_system` cannot depend on `rustc_hir`
-/// because it would create a dependency cycle. So, instead, a simplified
-/// version of `DefKind` was added to `rustc_query_system`.
-///
-/// `DefKind`s are converted to `SimpleDefKind`s in `rustc_query_impl`.
-#[derive(Debug, Copy, Clone)]
-pub enum SimpleDefKind {
-    Struct,
-    Enum,
-    Union,
-    Trait,
-    TyAlias,
-    TraitAlias,
-
-    // FIXME: add more from `rustc_hir::def::DefKind` and then remove `Other`
-    Other,
-}
-
 impl QueryStackFrame {
     #[inline]
     pub fn new(
         name: &'static str,
         description: String,
         span: Option<Span>,
-        def_kind: Option<SimpleDefKind>,
+        def_kind: Option<DefKind>,
         _hash: impl FnOnce() -> u64,
     ) -> Self {
         Self {
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index da9b50ba2e6..56d7f301b85 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -553,23 +553,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         )
         .map_bound(|(trait_ref, _)| trait_ref);
 
-        let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
-            normalize_with_depth(
-                self,
-                obligation.param_env,
-                obligation.cause.clone(),
-                obligation.recursion_depth + 1,
-                trait_ref,
-            )
-        });
-
-        obligations.extend(self.confirm_poly_trait_refs(
-            obligation.cause.clone(),
-            obligation.param_env,
-            obligation.predicate.to_poly_trait_ref(),
-            trait_ref,
-        )?);
-        Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested: obligations })
+        let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
+        Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
     }
 
     fn confirm_trait_alias_candidate(
@@ -616,26 +601,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
 
         let trait_ref = self.generator_trait_ref_unnormalized(obligation, substs);
-        let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
-            normalize_with_depth(
-                self,
-                obligation.param_env,
-                obligation.cause.clone(),
-                obligation.recursion_depth + 1,
-                trait_ref,
-            )
-        });
 
-        debug!(?trait_ref, ?obligations, "generator candidate obligations");
-
-        obligations.extend(self.confirm_poly_trait_refs(
-            obligation.cause.clone(),
-            obligation.param_env,
-            obligation.predicate.to_poly_trait_ref(),
-            trait_ref,
-        )?);
+        let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
+        debug!(?trait_ref, ?nested, "generator candidate obligations");
 
-        Ok(ImplSourceGeneratorData { generator_def_id, substs, nested: obligations })
+        Ok(ImplSourceGeneratorData { generator_def_id, substs, nested })
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -657,44 +627,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => bug!("closure candidate for non-closure {:?}", obligation),
         };
 
-        let obligation_predicate = obligation.predicate;
-        let Normalized { value: obligation_predicate, mut obligations } =
-            ensure_sufficient_stack(|| {
-                normalize_with_depth(
-                    self,
-                    obligation.param_env,
-                    obligation.cause.clone(),
-                    obligation.recursion_depth + 1,
-                    obligation_predicate,
-                )
-            });
-
         let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
-        let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
-            ensure_sufficient_stack(|| {
-                normalize_with_depth(
-                    self,
-                    obligation.param_env,
-                    obligation.cause.clone(),
-                    obligation.recursion_depth + 1,
-                    trait_ref,
-                )
-            });
+        let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
 
-        debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
-
-        obligations.extend(trait_ref_obligations);
-        obligations.extend(self.confirm_poly_trait_refs(
-            obligation.cause.clone(),
-            obligation.param_env,
-            obligation_predicate.to_poly_trait_ref(),
-            trait_ref,
-        )?);
+        debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
 
         // FIXME: Chalk
 
         if !self.tcx().sess.opts.debugging_opts.chalk {
-            obligations.push(Obligation::new(
+            nested.push(Obligation::new(
                 obligation.cause.clone(),
                 obligation.param_env,
                 ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
@@ -702,7 +643,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ));
         }
 
-        Ok(ImplSourceClosureData { closure_def_id, substs, nested: obligations })
+        Ok(ImplSourceClosureData { closure_def_id, substs, nested })
     }
 
     /// In the case of closure types and fn pointers,
@@ -733,15 +674,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     #[instrument(skip(self), level = "trace")]
     fn confirm_poly_trait_refs(
         &mut self,
-        obligation_cause: ObligationCause<'tcx>,
-        obligation_param_env: ty::ParamEnv<'tcx>,
-        obligation_trait_ref: ty::PolyTraitRef<'tcx>,
+        obligation: &TraitObligation<'tcx>,
         expected_trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
+        let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
+        // Normalize the obligation and expected trait refs together, because why not
+        let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
+            ensure_sufficient_stack(|| {
+                self.infcx.commit_unconditionally(|_| {
+                    normalize_with_depth(
+                        self,
+                        obligation.param_env,
+                        obligation.cause.clone(),
+                        obligation.recursion_depth + 1,
+                        (obligation_trait_ref, expected_trait_ref),
+                    )
+                })
+            });
+
         self.infcx
-            .at(&obligation_cause, obligation_param_env)
+            .at(&obligation.cause, obligation.param_env)
             .sup(obligation_trait_ref, expected_trait_ref)
-            .map(|InferOk { obligations, .. }| obligations)
+            .map(|InferOk { mut obligations, .. }| {
+                obligations.extend(nested);
+                obligations
+            })
             .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
     }
 
diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir
index f8a8afa92e0..8e02dca4fb8 100644
--- a/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir
+++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.32bit.mir
@@ -9,9 +9,12 @@ fn main() -> () {
         StorageLive(_1);                 // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         StorageLive(_2);                 // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         _2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
+                                         // ty::Const
+                                         // + ty: &&[(std::option::Option<i32>, &[&str])]
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const_allocation.rs:8:5: 8:8
-                                         // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
+                                         // + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
         _1 = (*_2);                      // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         StorageDead(_2);                 // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
         StorageDead(_1);                 // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
diff --git a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir
index 1f1d857425e..88cdbda2fae 100644
--- a/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir
+++ b/src/test/mir-opt/const_allocation.main.ConstProp.after.64bit.mir
@@ -9,9 +9,12 @@ fn main() -> () {
         StorageLive(_1);                 // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         StorageLive(_2);                 // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         _2 = const {alloc1: &&[(Option<i32>, &[&str])]}; // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
+                                         // ty::Const
+                                         // + ty: &&[(std::option::Option<i32>, &[&str])]
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const_allocation.rs:8:5: 8:8
-                                         // + literal: Const { ty: &&[(Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
+                                         // + literal: Const { ty: &&[(std::option::Option<i32>, &[&str])], val: Value(Scalar(alloc1)) }
         _1 = (*_2);                      // scope 0 at $DIR/const_allocation.rs:8:5: 8:8
         StorageDead(_2);                 // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
         StorageDead(_1);                 // scope 0 at $DIR/const_allocation.rs:8:8: 8:9
diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir
index 8b5ad40c9f9..059b721f5bb 100644
--- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir
+++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.32bit.mir
@@ -9,9 +9,12 @@ fn main() -> () {
         StorageLive(_1);                 // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         StorageLive(_2);                 // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         _2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
+                                         // ty::Const
+                                         // + ty: &&[(std::option::Option<i32>, &[&u8])]
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const_allocation2.rs:5:5: 5:8
-                                         // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
+                                         // + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
         _1 = (*_2);                      // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         StorageDead(_2);                 // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
         StorageDead(_1);                 // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
diff --git a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir
index ef651f01c9b..d6a97917d62 100644
--- a/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir
+++ b/src/test/mir-opt/const_allocation2.main.ConstProp.after.64bit.mir
@@ -9,9 +9,12 @@ fn main() -> () {
         StorageLive(_1);                 // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         StorageLive(_2);                 // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         _2 = const {alloc1: &&[(Option<i32>, &[&u8])]}; // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
+                                         // ty::Const
+                                         // + ty: &&[(std::option::Option<i32>, &[&u8])]
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const_allocation2.rs:5:5: 5:8
-                                         // + literal: Const { ty: &&[(Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
+                                         // + literal: Const { ty: &&[(std::option::Option<i32>, &[&u8])], val: Value(Scalar(alloc1)) }
         _1 = (*_2);                      // scope 0 at $DIR/const_allocation2.rs:5:5: 5:8
         StorageDead(_2);                 // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
         StorageDead(_1);                 // scope 0 at $DIR/const_allocation2.rs:5:8: 5:9
diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir
index 991cf40d1b7..32000340dce 100644
--- a/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir
+++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.32bit.mir
@@ -9,6 +9,9 @@ fn main() -> () {
         StorageLive(_1);                 // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
         StorageLive(_2);                 // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
         _2 = const {alloc1: &&Packed};   // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
+                                         // ty::Const
+                                         // + ty: &&Packed
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const_allocation3.rs:5:5: 5:8
                                          // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) }
diff --git a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir
index fb481697aa8..cac882333ae 100644
--- a/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir
+++ b/src/test/mir-opt/const_allocation3.main.ConstProp.after.64bit.mir
@@ -9,6 +9,9 @@ fn main() -> () {
         StorageLive(_1);                 // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
         StorageLive(_2);                 // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
         _2 = const {alloc1: &&Packed};   // scope 0 at $DIR/const_allocation3.rs:5:5: 5:8
+                                         // ty::Const
+                                         // + ty: &&Packed
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const_allocation3.rs:5:5: 5:8
                                          // + literal: Const { ty: &&Packed, val: Value(Scalar(alloc1)) }
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
index 666b805e822..bec0fa9c049 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR-promoted[0].SimplifyCfg-elaborate-drops.after.mir
@@ -8,6 +8,9 @@ promoted[0] in BAR: &[&i32; 1] = {
 
     bb0: {
         _3 = const {alloc1: &i32};       // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
+                                         // ty::Const
+                                         // + ty: &i32
+                                         // + val: Value(Scalar(alloc1))
                                          // mir::Constant
                                          // + span: $DIR/const-promotion-extern-static.rs:9:33: 9:34
                                          // + literal: Const { ty: &i32, val: Value(Scalar(alloc1)) }
diff --git a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
index ad83e9c276e..b480b257825 100644
--- a/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.BAR.PromoteTemps.diff
@@ -18,7 +18,9 @@
 -         StorageLive(_5);                 // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
 -         _5 = const {alloc1: &i32};       // scope 0 at $DIR/const-promotion-extern-static.rs:9:33: 9:34
 +         _6 = const BAR::promoted[0];     // scope 0 at $DIR/const-promotion-extern-static.rs:9:31: 9:44
-+                                          // ty::Const
+                                           // ty::Const
+-                                          // + ty: &i32
+-                                          // + val: Value(Scalar(alloc1))
 +                                          // + ty: &[&i32; 1]
 +                                          // + val: Unevaluated(BAR, [], Some(promoted[0]))
                                            // mir::Constant
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
index 785c8386e88..c01b31525b6 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir
@@ -8,6 +8,9 @@ promoted[0] in FOO: &[&i32; 1] = {
 
     bb0: {
         _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
+                                         // ty::Const
+                                         // + ty: *const i32
+                                         // + val: Value(Scalar(alloc3))
                                          // mir::Constant
                                          // + span: $DIR/const-promotion-extern-static.rs:13:42: 13:43
                                          // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) }
diff --git a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index a9cf3ca9767..ed48f5dc9dc 100644
--- a/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/src/test/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -20,7 +20,9 @@
 -         StorageLive(_5);                 // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
 -         _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const-promotion-extern-static.rs:13:42: 13:43
 +         _6 = const FOO::promoted[0];     // scope 0 at $DIR/const-promotion-extern-static.rs:13:31: 13:55
-+                                          // ty::Const
+                                           // ty::Const
+-                                          // + ty: *const i32
+-                                          // + val: Value(Scalar(alloc3))
 +                                          // + ty: &[&i32; 1]
 +                                          // + val: Unevaluated(FOO, [], Some(promoted[0]))
                                            // mir::Constant
diff --git a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
index 1fd92ddd461..afc62178463 100644
--- a/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/mutable_variable_no_prop.main.ConstProp.diff
@@ -24,6 +24,9 @@
           StorageLive(_3);                 // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
           StorageLive(_4);                 // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
           _4 = const {alloc1: *mut u32};   // scope 2 at $DIR/mutable_variable_no_prop.rs:9:13: 9:19
+                                           // ty::Const
+                                           // + ty: *mut u32
+                                           // + val: Value(Scalar(alloc1))
                                            // mir::Constant
                                            // + span: $DIR/mutable_variable_no_prop.rs:9:13: 9:19
                                            // + literal: Const { ty: *mut u32, val: Value(Scalar(alloc1)) }
diff --git a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
index 15b3e076642..13ef30d89a0 100644
--- a/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/read_immutable_static.main.ConstProp.diff
@@ -17,6 +17,9 @@
           StorageLive(_2);                 // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
           StorageLive(_3);                 // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
           _3 = const {alloc1: &u8};        // scope 0 at $DIR/read_immutable_static.rs:7:13: 7:16
+                                           // ty::Const
+                                           // + ty: &u8
+                                           // + val: Value(Scalar(alloc1))
                                            // mir::Constant
                                            // + span: $DIR/read_immutable_static.rs:7:13: 7:16
                                            // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
@@ -25,6 +28,9 @@
           StorageLive(_4);                 // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
           StorageLive(_5);                 // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
           _5 = const {alloc1: &u8};        // scope 0 at $DIR/read_immutable_static.rs:7:19: 7:22
+                                           // ty::Const
+                                           // + ty: &u8
+                                           // + val: Value(Scalar(alloc1))
                                            // mir::Constant
                                            // + span: $DIR/read_immutable_static.rs:7:19: 7:22
                                            // + literal: Const { ty: &u8, val: Value(Scalar(alloc1)) }
diff --git a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
index d06c3ec8de7..ce196dcbd86 100644
--- a/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
+++ b/src/test/ui/generic-associated-types/bugs/issue-88382.stderr
@@ -2,18 +2,18 @@ error[E0631]: type mismatch in function arguments
   --> $DIR/issue-88382.rs:28:40
    |
 LL |     do_something(SomeImplementation(), test);
-   |     ------------                       ^^^^ expected signature of `for<'a> fn(&mut <SomeImplementation as Iterable>::Iterator<'a>) -> _`
+   |     ------------                       ^^^^ expected signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
    |     |
    |     required by a bound introduced by this call
 ...
 LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
-   | ------------------------------------------------- found signature of `for<'r> fn(&'r mut std::iter::Empty<usize>) -> _`
+   | ------------------------------------------------- found signature of `for<'r, 'a> fn(&'r mut <_ as Iterable>::Iterator<'a>) -> _`
    |
 note: required by a bound in `do_something`
-  --> $DIR/issue-88382.rs:22:56
+  --> $DIR/issue-88382.rs:22:48
    |
 LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
-   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
+   |                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-60283.rs b/src/test/ui/higher-rank-trait-bounds/issue-60283.rs
index c63b1544a53..05315b3f9f5 100644
--- a/src/test/ui/higher-rank-trait-bounds/issue-60283.rs
+++ b/src/test/ui/higher-rank-trait-bounds/issue-60283.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 pub trait Trait<'a> {
     type Item;
 }
@@ -15,6 +17,4 @@ where
 
 fn main() {
     foo((), drop)
-    //~^ ERROR type mismatch in function arguments
-    //~| ERROR size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
 }
diff --git a/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr b/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr
deleted file mode 100644
index 34893cd8f19..00000000000
--- a/src/test/ui/higher-rank-trait-bounds/issue-60283.stderr
+++ /dev/null
@@ -1,42 +0,0 @@
-error[E0631]: type mismatch in function arguments
-  --> $DIR/issue-60283.rs:17:13
-   |
-LL |     foo((), drop)
-   |     ---     ^^^^
-   |     |       |
-   |     |       expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |     |       found signature of `fn(()) -> _`
-   |     required by a bound introduced by this call
-   |
-note: required by a bound in `foo`
-  --> $DIR/issue-60283.rs:12:16
-   |
-LL | pub fn foo<T, F>(_: T, _: F)
-   |        --- required by a bound in this
-...
-LL |     F: for<'a> FnMut(<T as Trait<'a>>::Item),
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
-
-error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
-  --> $DIR/issue-60283.rs:17:13
-   |
-LL |     foo((), drop)
-   |     ---     ^^^^ doesn't have a size known at compile-time
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sized` is not implemented for `<() as Trait<'_>>::Item`
-note: required by a bound in `std::mem::drop`
-  --> $SRC_DIR/core/src/mem/mod.rs:LL:COL
-   |
-LL | pub fn drop<T>(_x: T) {}
-   |             ^ required by this bound in `std::mem::drop`
-help: consider further restricting the associated type
-   |
-LL | fn main() where <() as Trait<'_>>::Item: Sized {
-   |           ++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0277, E0631.
-For more information about an error, try `rustc --explain E0277`.