about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-22 08:07:46 +0000
committerbors <bors@rust-lang.org>2022-06-22 08:07:46 +0000
commit89a0783f1c8fef46b1c8de57dc611a1d753bf0d5 (patch)
treeb5bc0da449b017293c90ec93cd34fcf7cd5470b0
parent3d829a0922d865d7a77fb284424fd8ba6afaea3b (diff)
parentdb64923b800686132139168124891d58b66a2a98 (diff)
downloadrust-89a0783f1c8fef46b1c8de57dc611a1d753bf0d5.tar.gz
rust-89a0783f1c8fef46b1c8de57dc611a1d753bf0d5.zip
Auto merge of #98375 - JohnTitor:rollup-e5c6rgo, r=JohnTitor
Rollup of 10 pull requests

Successful merges:

 - #95446 (update CPU usage script)
 - #96768 (Use futex based thread parker on Fuchsia.)
 - #97454 (Add release notes for 1.62)
 - #97516 (clarify how Rust atomics correspond to C++ atomics)
 - #97818 (Point at return expression for RPIT-related error)
 - #97895 (Simplify `likely!` and `unlikely!` macro)
 - #98005 (Add some tests for impossible bounds)
 - #98226 (Document unstable `--extern` options)
 - #98356 (Add missing period)
 - #98363 (remove use of &Alloc in btree tests)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--README.md2
-rw-r--r--RELEASES.md125
-rw-r--r--compiler/rustc_data_structures/src/lib.rs21
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs3
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs10
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs2
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_typeck/src/check/check.rs5
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs10
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs32
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs4
-rw-r--r--library/alloc/src/collections/btree/node/tests.rs12
-rw-r--r--library/core/src/sync/atomic.rs7
-rw-r--r--library/std/src/sys/unix/futex.rs50
-rw-r--r--library/std/src/sys/unix/thread_parker.rs1
-rw-r--r--library/std/src/sys_common/thread_parker/mod.rs1
-rw-r--r--src/doc/unstable-book/src/compiler-flags/extern-options.md22
-rwxr-xr-xsrc/etc/cpu-usage-over-time-plot.sh20
-rw-r--r--src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr3
-rw-r--r--src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr9
-rw-r--r--src/test/ui/impl-trait/bound-normalization-fail.stderr6
-rw-r--r--src/test/ui/issues-71798.stderr3
-rw-r--r--src/test/ui/trait-bounds/issue-93008.rs17
-rw-r--r--src/test/ui/trait-bounds/issue-93008.stderr12
-rw-r--r--src/test/ui/trait-bounds/issue-94680.rs14
-rw-r--r--src/test/ui/trait-bounds/issue-94999.rs34
-rw-r--r--src/test/ui/trait-bounds/issue-95640.rs31
-rw-r--r--src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs43
-rw-r--r--src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr18
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr3
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr3
35 files changed, 489 insertions, 66 deletions
diff --git a/README.md b/README.md
index 78edac9d12c..26613314a15 100644
--- a/README.md
+++ b/README.md
@@ -83,7 +83,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
     If you plan to use `x.py install` to create an installation, it is recommended
     that you set the `prefix` value in the `[install]` section to a directory.
 
-    Create install directory if you are not installing in default directory
+    Create install directory if you are not installing in default directory.
 
 4. Build and install:
 
diff --git a/RELEASES.md b/RELEASES.md
index 0e118fb939f..3d88891ad21 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,128 @@
+Version 1.62.0 (2022-06-30)
+==========================
+
+Language
+--------
+
+- [Stabilize `#[derive(Default)]` on enums with a `#[default]` variant][94457]
+- [Stop validating some checks in dead code after functions with uninhabited return types][93313]
+- [Fix constants not getting dropped if part of a diverging expression][94775]
+- [Support unit struct/enum variant in destructuring assignment][95380]
+- [Remove mutable_borrow_reservation_conflict lint and allow the code pattern][96268]
+
+Compiler
+--------
+
+- [linker: Stop using whole-archive on dependencies of dylibs][96436]
+- [Make `unaligned_references` lint deny-by-default][95372]
+  This lint is also a future compatibility lint, and is expected to eventually
+  become a hard error.
+- [Only add codegen backend to dep info if -Zbinary-dep-depinfo is used][93969]
+- [Reject `#[thread_local]` attribute on non-static items][95006]
+- [Add tier 3 `aarch64-pc-windows-gnullvm` and `x86_64-pc-windows-gnullvm` targets\*][94872]
+- [Implement a lint to warn about unused macro rules][96150]
+- [Promote `x86_64-unknown-none` target to Tier 2\*][95705]
+
+\* Refer to Rust's [platform support page][platform-support-doc] for more
+   information on Rust's tiered platform support.
+
+Libraries
+---------
+
+- [Move `CStr` to libcore, and `CString` to liballoc][94079]
+- [Windows: Use a pipe relay for chaining pipes][95841]
+- [Replace Linux Mutex and Condvar with futex based ones.][95035]
+- [Replace RwLock by a futex based one on Linux][95801]
+- [std: directly use pthread in UNIX parker implementation][96393]
+
+Stabilized APIs
+---------------
+
+- [`bool::then_some`]
+- [`f32::total_cmp`]
+- [`f64::total_cmp`]
+- [`Stdin::lines`]
+- [`windows::CommandExt::raw_arg`]
+- [`impl<T: Default> Default for AssertUnwindSafe<T>`]
+- [`From<Rc<str>> for Rc<[u8]>`][rc-u8-from-str]
+- [`From<Arc<str>> for Arc<[u8]>`][arc-u8-from-str]
+- [`FusedIterator for EncodeWide`]
+- [RDM intrinsics on aarch64][stdarch/1285]
+
+Clippy
+------
+
+- [Create clippy lint against unexpectedly late drop for temporaries in match scrutinee expressions][94206]
+
+Cargo
+-----
+
+- Added the `cargo add` command for adding dependencies to `Cargo.toml` from
+  the command-line.
+  [docs](https://doc.rust-lang.org/nightly/cargo/commands/cargo-add.html)
+- Package ID specs now support `name@version` syntax in addition to the
+  previous `name:version` to align with the behavior in `cargo add` and other
+  tools. `cargo install` and `cargo yank` also now support this syntax so the
+  version does not need to passed as a separate flag.
+- The `git` and `registry` directories in Cargo's home directory (usually
+  `~/.cargo`) are now marked as cache directories so that they are not
+  included in backups or content indexing (on Windows).
+- Added automatic `@` argfile support, which will use "response files" if the
+  command-line to `rustc` exceeds the operating system's limit.
+
+Compatibility Notes
+-------------------
+
+- `cargo test` now passes `--target` to `rustdoc` if the specified target is
+  the same as the host target.
+  [#10594](https://github.com/rust-lang/cargo/pull/10594)
+- [rustdoc: Remove .woff font files][96279]
+- [Enforce Copy bounds for repeat elements while considering lifetimes][95819]
+
+Internal Changes
+----------------
+
+- [Unify ReentrantMutex implementations across all platforms][96042]
+
+These changes provide no direct user facing benefits, but represent significant
+improvements to the internals and overall performance of rustc
+and related tools.
+
+[93313]: https://github.com/rust-lang/rust/pull/93313/
+[93969]: https://github.com/rust-lang/rust/pull/93969/
+[94079]: https://github.com/rust-lang/rust/pull/94079/
+[94206]: https://github.com/rust-lang/rust/pull/94206/
+[94457]: https://github.com/rust-lang/rust/pull/94457/
+[94775]: https://github.com/rust-lang/rust/pull/94775/
+[94872]: https://github.com/rust-lang/rust/pull/94872/
+[95006]: https://github.com/rust-lang/rust/pull/95006/
+[95035]: https://github.com/rust-lang/rust/pull/95035/
+[95372]: https://github.com/rust-lang/rust/pull/95372/
+[95380]: https://github.com/rust-lang/rust/pull/95380/
+[95431]: https://github.com/rust-lang/rust/pull/95431/
+[95705]: https://github.com/rust-lang/rust/pull/95705/
+[95801]: https://github.com/rust-lang/rust/pull/95801/
+[95819]: https://github.com/rust-lang/rust/pull/95819/
+[95841]: https://github.com/rust-lang/rust/pull/95841/
+[96042]: https://github.com/rust-lang/rust/pull/96042/
+[96150]: https://github.com/rust-lang/rust/pull/96150/
+[96268]: https://github.com/rust-lang/rust/pull/96268/
+[96279]: https://github.com/rust-lang/rust/pull/96279/
+[96393]: https://github.com/rust-lang/rust/pull/96393/
+[96436]: https://github.com/rust-lang/rust/pull/96436/
+[96557]: https://github.com/rust-lang/rust/pull/96557/
+
+[`bool::then_some`]: https://doc.rust-lang.org/stable/std/primitive.bool.html#method.then_some
+[`f32::total_cmp`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.total_cmp
+[`f64::total_cmp`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.total_cmp
+[`Stdin::lines`]: https://doc.rust-lang.org/stable/std/io/struct.Stdin.html#method.lines
+[`impl<T: Default> Default for AssertUnwindSafe<T>`]: https://doc.rust-lang.org/stable/std/panic/struct.AssertUnwindSafe.html#impl-Default
+[rc-u8-from-str]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#impl-From%3CRc%3Cstr%3E%3E
+[arc-u8-from-str]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#impl-From%3CArc%3Cstr%3E%3E
+[stdarch/1285]: https://github.com/rust-lang/stdarch/pull/1285
+[`windows::CommandExt::raw_arg`]: https://doc.rust-lang.org/stable/std/os/windows/process/trait.CommandExt.html#tymethod.raw_arg
+[`FusedIterator for EncodeWide`]: https://doc.rust-lang.org/stable/std/os/windows/ffi/struct.EncodeWide.html#impl-FusedIterator
+
 Version 1.61.0 (2022-05-19)
 ==========================
 
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 0d072046d58..390a44d3f33 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -11,7 +11,6 @@
 #![feature(associated_type_bounds)]
 #![feature(auto_traits)]
 #![feature(control_flow_enum)]
-#![feature(core_intrinsics)]
 #![feature(extend_one)]
 #![feature(let_else)]
 #![feature(hash_raw_entry)]
@@ -44,26 +43,6 @@ pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
     f()
 }
 
-#[macro_export]
-macro_rules! likely {
-    ($e:expr) => {
-        match $e {
-            #[allow(unused_unsafe)]
-            e => unsafe { std::intrinsics::likely(e) },
-        }
-    };
-}
-
-#[macro_export]
-macro_rules! unlikely {
-    ($e:expr) => {
-        match $e {
-            #[allow(unused_unsafe)]
-            e => unsafe { std::intrinsics::unlikely(e) },
-        }
-    };
-}
-
 pub mod base_n;
 pub mod binary_search_util;
 pub mod captures;
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index a1f42d8d3c0..88ff33b4d09 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -195,6 +195,7 @@ impl SelfProfilerRef {
         F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>,
     {
         #[inline(never)]
+        #[cold]
         fn cold_call<F>(profiler_ref: &SelfProfilerRef, f: F) -> TimingGuard<'_>
         where
             F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>,
@@ -203,7 +204,7 @@ impl SelfProfilerRef {
             f(&**profiler)
         }
 
-        if unlikely!(self.event_filter_mask.contains(event_filter)) {
+        if self.event_filter_mask.contains(event_filter) {
             cold_call(self, f)
         } else {
             TimingGuard::none()
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 80f6abbab34..7684d861f3c 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -5,7 +5,7 @@ use hir::{HirId, OpaqueTyOrigin};
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::vec_map::VecMap;
 use rustc_hir as hir;
-use rustc_middle::traits::ObligationCause;
+use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::subst::{GenericArgKind, Subst};
 use rustc_middle::ty::{
@@ -46,6 +46,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         value: T,
         body_id: HirId,
         span: Span,
+        code: ObligationCauseCode<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> InferOk<'tcx, T> {
         if !value.has_opaque_types() {
@@ -68,10 +69,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     ) =>
                 {
                     let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
-                    let cause = ObligationCause::misc(span, body_id);
+                    let cause = ObligationCause::new(span, body_id, code.clone());
+                    // FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind
+                    // for opaque types, and then use that kind to fix the spans for type errors
+                    // that we see later on.
                     let ty_var = self.next_ty_var(TypeVariableOrigin {
                         kind: TypeVariableOriginKind::TypeInference,
-                        span: cause.span,
+                        span,
                     });
                     obligations.extend(
                         self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 912b09eeca8..5258d37a14c 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -387,6 +387,9 @@ pub enum ObligationCauseCode<'tcx> {
     /// Return type of this function
     ReturnType,
 
+    /// Opaque return type of this function
+    OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
+
     /// Block implicit return
     BlockTailExpression(hir::HirId),
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 9c1972e81e1..00403ff044c 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -804,7 +804,7 @@ pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
 
 impl<'tcx> TraitPredicate<'tcx> {
     pub fn remap_constness(&mut self, tcx: TyCtxt<'tcx>, param_env: &mut ParamEnv<'tcx>) {
-        if unlikely!(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
+        if std::intrinsics::unlikely(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
             // remap without changing constness of this predicate.
             // this is because `T: ~const Drop` has a different meaning to `T: Drop`
             // FIXME(fee1-dead): remove this logic after beta bump
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 5a32d7075db..341cf8f827b 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -750,7 +750,7 @@ impl<K: DepKind> DepGraph<K> {
             dep_node
         );
 
-        if unlikely!(!side_effects.is_empty()) {
+        if !side_effects.is_empty() {
             self.emit_side_effects(tcx, data, dep_node_index, side_effects);
         }
 
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index 3498df95196..3e4c7ad9f8f 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -316,7 +316,7 @@ where
     OnHit: FnOnce(&C::Stored) -> R,
 {
     cache.lookup(&key, |value, index| {
-        if unlikely!(tcx.profiler().enabled()) {
+        if std::intrinsics::unlikely(tcx.profiler().enabled()) {
             tcx.profiler().query_cache_hit(index.into());
         }
         tcx.dep_graph().read_index(index);
@@ -354,7 +354,7 @@ where
                 .lookup(&key, |value, index| (value.clone(), index))
                 .unwrap_or_else(|_| panic!("value must be in cache after waiting"));
 
-            if unlikely!(tcx.dep_context().profiler().enabled()) {
+            if std::intrinsics::unlikely(tcx.dep_context().profiler().enabled()) {
                 tcx.dep_context().profiler().query_cache_hit(index.into());
             }
             query_blocked_prof_timer.finish_with_query_invocation_id(index.into());
@@ -422,7 +422,7 @@ where
     let diagnostics = diagnostics.into_inner();
     let side_effects = QuerySideEffects { diagnostics };
 
-    if unlikely!(!side_effects.is_empty()) {
+    if std::intrinsics::unlikely(!side_effects.is_empty()) {
         if query.anon {
             tcx.store_side_effects_for_anon_node(dep_node_index, side_effects);
         } else {
@@ -466,7 +466,9 @@ where
         prof_timer.finish_with_query_invocation_id(dep_node_index.into());
 
         if let Some(result) = result {
-            if unlikely!(tcx.dep_context().sess().opts.debugging_opts.query_dep_graph) {
+            if std::intrinsics::unlikely(
+                tcx.dep_context().sess().opts.debugging_opts.query_dep_graph,
+            ) {
                 dep_graph.mark_debug_loaded_from_disk(*dep_node)
             }
 
@@ -483,8 +485,8 @@ where
             // currently afford to verify every hash. This subset should still
             // give us some coverage of potential bugs though.
             let try_verify = prev_fingerprint.as_value().1 % 32 == 0;
-            if unlikely!(
-                try_verify || tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich
+            if std::intrinsics::unlikely(
+                try_verify || tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich,
             ) {
                 incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
             }
@@ -723,7 +725,7 @@ where
     // Ensure that only one of them runs the query.
     let cache = Q::query_cache(tcx);
     let cached = cache.lookup(&key, |_, index| {
-        if unlikely!(tcx.dep_context().profiler().enabled()) {
+        if std::intrinsics::unlikely(tcx.dep_context().profiler().enabled()) {
             tcx.dep_context().profiler().query_cache_hit(index.into());
         }
     });
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index d8003efba87..0485cac9e9f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2661,6 +2661,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     err.help("add `#![feature(trivial_bounds)]` to the crate attributes to enable");
                 }
             }
+            ObligationCauseCode::OpaqueReturnType(expr_info) => {
+                if let Some((expr_ty, expr_span)) = expr_info {
+                    let expr_ty = self.resolve_vars_if_possible(expr_ty);
+                    err.span_label(
+                        expr_span,
+                        format!("return type was inferred to be `{expr_ty}` here"),
+                    );
+                }
+            }
         }
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index a72f90746ed..82c54291a5d 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -28,6 +28,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::resolve::OpportunisticRegionResolver;
+use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::traits::select::OverflowError;
 use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::subst::Subst;
@@ -261,6 +262,7 @@ fn project_and_unify_type<'cx, 'tcx>(
             actual,
             obligation.cause.body_id,
             obligation.cause.span,
+            ObligationCauseCode::MiscObligation,
             obligation.param_env,
         );
     obligations.extend(new);
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 0425e7b074f..45c011b78e3 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -101,8 +101,13 @@ pub(super) fn check_fn<'a, 'tcx>(
             declared_ret_ty,
             body.value.hir_id,
             DUMMY_SP,
+            traits::ObligationCauseCode::OpaqueReturnType(None),
             param_env,
         ));
+    // If we replaced declared_ret_ty with infer vars, then we must be infering
+    // an opaque type, so set a flag so we can improve diagnostics.
+    fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
+
     fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
     fcx.ret_type_span = Some(decl.output.span());
 
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 05b22e174b8..cce11305119 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -10,6 +10,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
+use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, Ty};
@@ -645,8 +646,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
-        let InferOk { value, obligations } =
-            self.replace_opaque_types_with_inference_vars(ty, body_id, span, self.param_env);
+        let InferOk { value, obligations } = self.replace_opaque_types_with_inference_vars(
+            ty,
+            body_id,
+            span,
+            ObligationCauseCode::MiscObligation,
+            self.param_env,
+        );
         self.register_predicates(obligations);
         value
     }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 37d12b4ed5d..77d6495f38c 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -39,6 +39,7 @@ use rustc_hir::{ExprKind, HirId, QPath};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::InferOk;
+use rustc_infer::traits::ObligationCause;
 use rustc_middle::middle::stability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
 use rustc_middle::ty::error::TypeError::FieldMisMatch;
@@ -839,6 +840,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return_expr,
             return_expr_ty,
         );
+
+        if self.return_type_has_opaque {
+            // Point any obligations that were registered due to opaque type
+            // inference at the return expression.
+            self.select_obligations_where_possible(false, |errors| {
+                self.point_at_return_for_opaque_ty_error(errors, span, return_expr_ty);
+            });
+        }
+    }
+
+    fn point_at_return_for_opaque_ty_error(
+        &self,
+        errors: &mut Vec<traits::FulfillmentError<'tcx>>,
+        span: Span,
+        return_expr_ty: Ty<'tcx>,
+    ) {
+        // Don't point at the whole block if it's empty
+        if span == self.tcx.hir().span(self.body_id) {
+            return;
+        }
+        for err in errors {
+            let cause = &mut err.obligation.cause;
+            if let ObligationCauseCode::OpaqueReturnType(None) = cause.code() {
+                let new_cause = ObligationCause::new(
+                    cause.span,
+                    cause.body_id,
+                    ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, span))),
+                );
+                *cause = new_cause;
+            }
+        }
     }
 
     pub(crate) fn check_lhs_assignable(
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index fa2416d56de..8b680a3d042 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
@@ -115,6 +115,9 @@ pub struct FnCtxt<'a, 'tcx> {
     /// either given explicitly or inferred from, say, an `Fn*` trait
     /// bound. Used for diagnostic purposes only.
     pub(super) return_type_pre_known: bool,
+
+    /// True if the return type has an Opaque type
+    pub(super) return_type_has_opaque: bool,
 }
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -141,6 +144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }),
             inh,
             return_type_pre_known: true,
+            return_type_has_opaque: false,
         }
     }
 
diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs
index c8634e6c06f..aadb0dc9c40 100644
--- a/library/alloc/src/collections/btree/node/tests.rs
+++ b/library/alloc/src/collections/btree/node/tests.rs
@@ -68,10 +68,10 @@ fn test_splitpoint() {
 
 #[test]
 fn test_partial_eq() {
-    let mut root1 = NodeRef::new_leaf(&Global);
+    let mut root1 = NodeRef::new_leaf(Global);
     root1.borrow_mut().push(1, ());
-    let mut root1 = NodeRef::new_internal(root1.forget_type(), &Global).forget_type();
-    let root2 = Root::new(&Global);
+    let mut root1 = NodeRef::new_internal(root1.forget_type(), Global).forget_type();
+    let root2 = Root::new(Global);
     root1.reborrow().assert_back_pointers();
     root2.reborrow().assert_back_pointers();
 
@@ -87,9 +87,9 @@ fn test_partial_eq() {
     assert!(top_edge_1 == top_edge_1);
     assert!(top_edge_1 != top_edge_2);
 
-    root1.pop_internal_level(&Global);
-    unsafe { root1.into_dying().deallocate_and_ascend(&Global) };
-    unsafe { root2.into_dying().deallocate_and_ascend(&Global) };
+    root1.pop_internal_level(Global);
+    unsafe { root1.into_dying().deallocate_and_ascend(Global) };
+    unsafe { root2.into_dying().deallocate_and_ascend(Global) };
 }
 
 #[test]
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index cedeb27d6d9..a66ecc35bbd 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -4,6 +4,12 @@
 //! threads, and are the building blocks of other concurrent
 //! types.
 //!
+//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`.
+//! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating
+//! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference
+//! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not*
+//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.)
+//!
 //! This module defines atomic versions of a select number of primitive
 //! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`],
 //! [`AtomicI8`], [`AtomicU16`], etc.
@@ -14,6 +20,7 @@
 //! the memory barrier for that operation. These orderings are the
 //! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2].
 //!
+//! [cpp]: https://en.cppreference.com/w/cpp/atomic
 //! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order
 //! [2]: ../../../nomicon/atomics.html
 //!
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs
index 8d05cb44b94..ab516a7f76d 100644
--- a/library/std/src/sys/unix/futex.rs
+++ b/library/std/src/sys/unix/futex.rs
@@ -5,6 +5,7 @@
     target_os = "freebsd",
     target_os = "openbsd",
     target_os = "dragonfly",
+    target_os = "fuchsia",
 ))]
 
 use crate::sync::atomic::AtomicU32;
@@ -237,3 +238,52 @@ pub fn futex_wake(futex: &AtomicU32) -> bool {
 pub fn futex_wake_all(futex: &AtomicU32) {
     unsafe { emscripten_futex_wake(futex, i32::MAX) };
 }
+
+#[cfg(target_os = "fuchsia")]
+mod zircon {
+    type zx_time_t = i64;
+    type zx_futex_t = crate::sync::atomic::AtomicU32;
+    type zx_handle_t = u32;
+    type zx_status_t = i32;
+
+    pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
+    pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
+    pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
+
+    extern "C" {
+        pub fn zx_futex_wait(
+            value_ptr: *const zx_futex_t,
+            current_value: zx_futex_t,
+            new_futex_owner: zx_handle_t,
+            deadline: zx_time_t,
+        ) -> zx_status_t;
+        pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
+        pub fn zx_clock_get_monotonic() -> zx_time_t;
+    }
+}
+
+#[cfg(target_os = "fuchsia")]
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
+    use crate::convert::TryFrom;
+
+    // Sleep forever if the timeout is longer than fits in a i64.
+    let deadline = timeout
+        .and_then(|d| {
+            i64::try_from(d.as_nanos())
+                .ok()?
+                .checked_add(unsafe { zircon::zx_clock_get_monotonic() })
+        })
+        .unwrap_or(zircon::ZX_TIME_INFINITE);
+
+    unsafe {
+        zircon::zx_futex_wait(futex, AtomicU32::new(expected), zircon::ZX_HANDLE_INVALID, deadline)
+            != zircon::ZX_ERR_TIMED_OUT
+    }
+}
+
+// Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
+#[cfg(target_os = "fuchsia")]
+pub fn futex_wake(futex: &AtomicU32) -> bool {
+    unsafe { zircon::zx_futex_wake(futex, 1) };
+    false
+}
diff --git a/library/std/src/sys/unix/thread_parker.rs b/library/std/src/sys/unix/thread_parker.rs
index 76278ae30f1..9f4d4f7e736 100644
--- a/library/std/src/sys/unix/thread_parker.rs
+++ b/library/std/src/sys/unix/thread_parker.rs
@@ -7,6 +7,7 @@
     target_os = "freebsd",
     target_os = "openbsd",
     target_os = "dragonfly",
+    target_os = "fuchsia",
 )))]
 
 use crate::cell::UnsafeCell;
diff --git a/library/std/src/sys_common/thread_parker/mod.rs b/library/std/src/sys_common/thread_parker/mod.rs
index c789a388e05..7e8bfb2565e 100644
--- a/library/std/src/sys_common/thread_parker/mod.rs
+++ b/library/std/src/sys_common/thread_parker/mod.rs
@@ -6,6 +6,7 @@ cfg_if::cfg_if! {
         target_os = "freebsd",
         target_os = "openbsd",
         target_os = "dragonfly",
+        target_os = "fuchsia",
     ))] {
         mod futex;
         pub use futex::Parker;
diff --git a/src/doc/unstable-book/src/compiler-flags/extern-options.md b/src/doc/unstable-book/src/compiler-flags/extern-options.md
new file mode 100644
index 00000000000..858eee5d2c2
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/extern-options.md
@@ -0,0 +1,22 @@
+# `--extern` Options
+
+The behavior of the `--extern` flag can be modified with `noprelude`, `priv` or `nounused` options.
+
+This is unstable feature, so you have to provide `-Zunstable-options` to enable it.
+
+## Examples
+
+Use your own build of the `core` crate.
+
+`rustc main.rs -Z unstable-options --extern noprelude:core=libcore.rlib`
+
+To use multiple options, separate them with a comma:
+
+`rustc main.rs -Z unstable-options --extern noprelude,priv,nounused:mydep=mydep.rlib`
+
+## Options
+
+* `noprelude`: Do not add the crate to the external prelude. If used, it will need to be imported using `extern crate`.
+  This is used by the [build-std project](https://github.com/rust-lang/wg-cargo-std-aware/) to simulate compatibility with sysroot-only crates.
+* `priv`: Mark the crate as a private dependency for the [`exported_private_dependencies`](../../rustc/lints/listing/warn-by-default.html#exported-private-dependencies) lint.
+* `nounused`: Suppress [`unused-crate-dependencies`](../../rustc/lints/listing/allowed-by-default.html#unused-crate-dependencies) warnings for the crate.
diff --git a/src/etc/cpu-usage-over-time-plot.sh b/src/etc/cpu-usage-over-time-plot.sh
index 0905789079a..1c342559194 100755
--- a/src/etc/cpu-usage-over-time-plot.sh
+++ b/src/etc/cpu-usage-over-time-plot.sh
@@ -7,13 +7,21 @@
 # commit SHA of the build you're interested in, and the second is the name of
 # the builder. For example:
 #
-#  ./src/etc/cpu-usage-over-time-plot.sh e699ea096fcc2fc9ce8e8bcf884e11496a31cc9f i686-mingw-1
+#  ./src/etc/cpu-usage-over-time-plot.sh 7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c x86_64-gnu
 #
 # That will generate `$builder.png` in the current directory which you can open
 # up to see a hopefully pretty graph.
 #
 # Improvements to this script are greatly appreciated!
 
+if [[ $# != 2 ]]; then
+    echo "expected 2 arguments, recieved $#"
+    echo "example usage: './src/etc/cpu-usage-over-time-plot.sh \
+7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c \
+x86_64-gnu'"
+    exit 1
+fi
+
 set -ex
 
 bucket=rust-lang-ci2
@@ -30,7 +38,7 @@ set ylabel "CPU Usage %"
 set xlabel "Time"
 set datafile sep ','
 set term png size 3000,1000
-set output "$builder.png"
+set output "$builder-$commit-cpu-usage-plot.png"
 set grid
 
 f(x) = mean_y
@@ -43,7 +51,9 @@ set ytics 10
 set boxwidth 0.5
 
 plot \\
-   mean_y with lines linetype 1 linecolor rgb "#ff0000" title "average", \\
-   "cpu-$builder.csv" using 1:(100-\$2) with points pointtype 7 pointsize 0.4 title "$builder", \\
-   "" using 1:(100-\$2) smooth bezier linewidth 3 title "bezier"
+    mean_y with lines linetype 1 linecolor rgb "#ff0000" title "average", "cpu-$builder.csv" \\
+    using 1:(100-\$2) with points pointtype 7 pointsize 0.4 title "$builder", "" \\
+    using 1:(100-\$2) smooth bezier linewidth 3 title "bezier"
 EOF
+
+rm "cpu-$builder.csv"
diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
index bd8c8a4414c..fbd76a64c1e 100644
--- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
+++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr
@@ -6,6 +6,9 @@ LL | fn bar() -> impl Bar {
 ...
 LL | fn baz() -> impl Bar<Item = i32> {
    |             ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
+LL |
+LL |     bar()
+   |     ----- return type was inferred to be `impl Bar` here
    |
    = note: expected associated type `<impl Bar as Foo>::Item`
                          found type `i32`
diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
index cbe4a4ac0d6..cbc7b93f3a9 100644
--- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
+++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
    |
 LL | fn rawr() -> impl Trait {
    |              ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>`
+LL |
+LL |     Uwu::<10, 12>
+   |     ------------- return type was inferred to be `Uwu<10_u32, 12_u32>` here
    |
    = help: the trait `Trait` is implemented for `Uwu<N>`
 
@@ -11,6 +14,9 @@ error[E0277]: the trait bound `u32: Traitor<N>` is not satisfied
    |
 LL | fn uwu<const N: u8>() -> impl Traitor<N> {
    |                          ^^^^^^^^^^^^^^^ the trait `Traitor<N>` is not implemented for `u32`
+LL |
+LL |     1_u32
+   |     ----- return type was inferred to be `u32` here
    |
    = help: the following other types implement trait `Traitor<N, M>`:
              <u32 as Traitor<N, 2_u8>>
@@ -21,6 +27,9 @@ error[E0277]: the trait bound `u64: Traitor` is not satisfied
    |
 LL | fn owo() -> impl Traitor {
    |             ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64`
+LL |
+LL |     1_u64
+   |     ----- return type was inferred to be `u64` here
    |
    = help: the following other types implement trait `Traitor<N, M>`:
              <u32 as Traitor<N, 2_u8>>
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index eac7e6b315e..bd8d3d3d24e 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -3,6 +3,9 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as imp
    |
 LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
+LL |
+LL |         Foo(())
+   |         ------- return type was inferred to be `Foo<()>` here
    |
 note: expected this to be `()`
   --> $DIR/bound-normalization-fail.rs:14:19
@@ -27,6 +30,9 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lif
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
+...
+LL |         Foo(())
+   |         ------- return type was inferred to be `Foo<()>` here
    |
 note: expected this to be `()`
   --> $DIR/bound-normalization-fail.rs:14:19
diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr
index ab72c3e41af..829d0a02ec9 100644
--- a/src/test/ui/issues-71798.stderr
+++ b/src/test/ui/issues-71798.stderr
@@ -9,6 +9,9 @@ error[E0277]: `u32` is not a future
    |
 LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not a future
+LL |
+LL |     *x
+   |     -- return type was inferred to be `u32` here
    |
    = help: the trait `Future` is not implemented for `u32`
    = note: u32 must be a future or must implement `IntoFuture` to be awaited
diff --git a/src/test/ui/trait-bounds/issue-93008.rs b/src/test/ui/trait-bounds/issue-93008.rs
index 1b010566cbc..f4d21a160b6 100644
--- a/src/test/ui/trait-bounds/issue-93008.rs
+++ b/src/test/ui/trait-bounds/issue-93008.rs
@@ -1,10 +1,15 @@
-// compile-flags: -Zmir-opt-level=4
+// build-pass
+// compile-flags: -Zmir-opt-level=3 --crate-type=lib
 
-pub fn bar<T>(s: &'static mut ())
+#![feature(trivial_bounds)]
+#![allow(trivial_bounds)]
+
+trait Foo {
+    fn test(self);
+}
+fn baz<T>()
 where
-    &'static mut (): Clone, //~ ERROR the trait bound
+    &'static str: Foo,
 {
-    <&'static mut () as Clone>::clone(&s);
+    "Foo".test()
 }
-
-fn main() {}
diff --git a/src/test/ui/trait-bounds/issue-93008.stderr b/src/test/ui/trait-bounds/issue-93008.stderr
deleted file mode 100644
index 10f80f8de0c..00000000000
--- a/src/test/ui/trait-bounds/issue-93008.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0277]: the trait bound `&'static mut (): Clone` is not satisfied
-  --> $DIR/issue-93008.rs:5:5
-   |
-LL |     &'static mut (): Clone,
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&'static mut ()`
-   |
-   = help: see issue #48214
-   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/trait-bounds/issue-94680.rs b/src/test/ui/trait-bounds/issue-94680.rs
new file mode 100644
index 00000000000..58e892079e6
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-94680.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+fn main() {
+    println!("{:?}", {
+        type T = ();
+
+        pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
+        where
+            for<'any> &'any mut T: Clone,
+        {
+            (it.clone(), it)
+        }
+    });
+}
diff --git a/src/test/ui/trait-bounds/issue-94999.rs b/src/test/ui/trait-bounds/issue-94999.rs
new file mode 100644
index 00000000000..e131902346f
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-94999.rs
@@ -0,0 +1,34 @@
+// check-pass
+
+trait Identity<Q> {
+    type T;
+}
+
+impl<Q, T> Identity<Q> for T {
+    type T = T;
+}
+
+trait Holds {
+    type Q;
+}
+
+struct S;
+struct X(S);
+
+struct XHelper;
+
+impl Holds for X {
+    type Q = XHelper;
+}
+
+impl<Q> Clone for X
+where
+    <S as Identity<Q>>::T: Clone,
+    X: Holds<Q = Q>,
+{
+    fn clone(&self) -> Self {
+        Self(self.0.clone())
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/issue-95640.rs b/src/test/ui/trait-bounds/issue-95640.rs
new file mode 100644
index 00000000000..e4e998b5d0b
--- /dev/null
+++ b/src/test/ui/trait-bounds/issue-95640.rs
@@ -0,0 +1,31 @@
+// build-pass
+// compile-flags:-Zmir-opt-level=3
+
+struct D;
+
+trait Tr {
+    type It;
+    fn foo(self) -> Option<Self::It>;
+}
+
+impl<'a> Tr for &'a D {
+    type It = ();
+    fn foo(self) -> Option<()> {
+        None
+    }
+}
+
+fn run<F>(f: F)
+where
+    for<'a> &'a D: Tr,
+    F: Fn(<&D as Tr>::It),
+{
+    let d = &D;
+    while let Some(i) = d.foo() {
+        f(i);
+    }
+}
+
+fn main() {
+    run(|_| {});
+}
diff --git a/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
new file mode 100644
index 00000000000..288b2098b4c
--- /dev/null
+++ b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.rs
@@ -0,0 +1,43 @@
+// known-bug
+// build-fail
+// failure-status: 101
+// compile-flags:--crate-type=lib -Zmir-opt-level=3
+// rustc-env:RUST_BACKTRACE=0
+
+// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
+// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "error: internal compiler error.*" -> "error: internal compiler error"
+// normalize-stderr-test "encountered.*with incompatible types:" "encountered ... with incompatible types:"
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "query stack during panic:\n" -> ""
+// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
+// normalize-stderr-test "end of query stack\n" -> ""
+// normalize-stderr-test "#.*\n" -> ""
+
+// This is a known bug that @compiler-errors tried to fix in #94238,
+// but the solution was probably not correct.
+
+pub trait Factory<T> {
+    type Item;
+}
+
+pub struct IntFactory;
+
+impl<T> Factory<T> for IntFactory {
+    type Item = usize;
+}
+
+pub fn foo<T>()
+where
+    IntFactory: Factory<T>,
+{
+    let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
+}
+
+#[inline]
+pub fn bar<T>() -> <IntFactory as Factory<T>>::Item {
+    0usize
+}
diff --git a/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr
new file mode 100644
index 00000000000..56cc5c93c96
--- /dev/null
+++ b/src/test/ui/trait-bounds/select-param-env-instead-of-blanket.stderr
@@ -0,0 +1,18 @@
+error: internal compiler error
+
+error: internal compiler error
+                                encountered ... with incompatible types:
+                                left-hand side has type: <IntFactory as Factory<T>>::Item
+                                right-hand side has type: usize
+  --> $DIR/select-param-env-instead-of-blanket.rs:42:5
+   |
+LL |     let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
+   |                                                   ---------- in this inlined function call
+...
+LL |     0usize
+   |     ^^^^^^
+   |
+   = note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:128:36
+
+thread 'rustc' panicked
+
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
index f98da9f7f92..62db019ed6a 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
    |
 LL | fn foo() -> impl Foo<FooX> {
    |             ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
+...
+LL |     ()
+   |     -- return type was inferred to be `()` here
    |
    = help: the trait `Foo<()>` is implemented for `()`
 
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
index 54f571ad3e3..f4d96038d91 100644
--- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
@@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
    |
 LL | fn foo() -> impl Foo<FooX> {
    |             ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
+LL |
+LL |     ()
+   |     -- return type was inferred to be `()` here
    |
    = help: the following other types implement trait `Foo<A>`:
              <() as Foo<()>>