about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs39
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs2
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs2
-rw-r--r--compiler/rustc_serialize/src/opaque.rs36
-rw-r--r--compiler/rustc_serialize/src/serialize.rs16
-rw-r--r--compiler/rustc_serialize/tests/opaque.rs32
-rw-r--r--compiler/rustc_span/src/edit_distance.rs32
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs49
-rw-r--r--library/alloc/src/string.rs10
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css14
-rw-r--r--src/librustdoc/html/templates/source.html6
-rw-r--r--src/tools/compiletest/src/header.rs10
-rw-r--r--src/tools/compiletest/src/runtest.rs4
-rw-r--r--tests/ui/argument-suggestions/issue-109425.fixed20
-rw-r--r--tests/ui/argument-suggestions/issue-109425.rs20
-rw-r--r--tests/ui/argument-suggestions/issue-109425.stderr98
-rw-r--r--tests/ui/recursion/issue-95134.rs2
-rw-r--r--tests/ui/suggestions/issue-109291.rs4
-rw-r--r--tests/ui/suggestions/issue-109291.stderr12
-rw-r--r--tests/ui/suggestions/issue-109396.stderr2
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr18
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs26
23 files changed, 348 insertions, 108 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 61338ac613a..b02eae19fce 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -31,7 +31,7 @@ use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, IsSuggestable, Ty};
 use rustc_session::Session;
 use rustc_span::symbol::{kw, Ident};
-use rustc_span::{self, sym, Span};
+use rustc_span::{self, sym, BytePos, Span};
 use rustc_trait_selection::traits::{self, ObligationCauseCode, SelectionContext};
 
 use std::iter;
@@ -894,8 +894,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let mut errors = errors.into_iter().peekable();
+        let mut only_extras_so_far = errors
+            .peek()
+            .map_or(false, |first| matches!(first, Error::Extra(arg_idx) if arg_idx.index() == 0));
         let mut suggestions = vec![];
         while let Some(error) = errors.next() {
+            only_extras_so_far &= matches!(error, Error::Extra(_));
+
             match error {
                 Error::Invalid(provided_idx, expected_idx, compatibility) => {
                     let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
@@ -941,10 +946,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if arg_idx.index() > 0
                         && let Some((_, prev)) = provided_arg_tys
                             .get(ProvidedIdx::from_usize(arg_idx.index() - 1)
-                    ) {
-                        // Include previous comma
-                        span = prev.shrink_to_hi().to(span);
-                    }
+                        ) {
+                            // Include previous comma
+                            span = prev.shrink_to_hi().to(span);
+                        }
+
+                        // Is last argument for deletion in a row starting from the 0-th argument?
+                        // Then delete the next comma, so we are not left with `f(, ...)`
+                        //
+                        //     fn f() {}
+                        //   - f(0, 1,)
+                        //   + f()
+                        if only_extras_so_far
+                            && errors
+                                .peek()
+                                .map_or(true, |next_error| !matches!(next_error, Error::Extra(_)))
+                        {
+                            let next = provided_arg_tys
+                                .get(arg_idx + 1)
+                                .map(|&(_, sp)| sp)
+                                .unwrap_or_else(|| {
+                                    // Subtract one to move before `)`
+                                    call_expr.span.with_lo(call_expr.span.hi() - BytePos(1))
+                                });
+
+                            // Include next comma
+                            span = span.until(next);
+                        }
+
                         suggestions.push((span, String::new()));
 
                         suggestion_text = match suggestion_text {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 0e8155afcb4..faf0592138b 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -112,8 +112,6 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
         emit_i8(i8);
 
         emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
         emit_char(char);
         emit_str(&str);
         emit_raw_bytes(&[u8]);
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 3ce80e06ad9..8ef4a46a733 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -511,8 +511,6 @@ macro_rules! implement_ty_decoder {
                     read_isize -> isize;
 
                     read_bool -> bool;
-                    read_f64 -> f64;
-                    read_f32 -> f32;
                     read_char -> char;
                     read_str -> &str;
                 }
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index eec9dac7b9b..30477c7bd44 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -1046,8 +1046,6 @@ impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
         emit_i8(i8);
 
         emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
         emit_char(char);
         emit_str(&str);
         emit_raw_bytes(&[u8]);
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 0e0ebc79eb2..53e5c896736 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -123,18 +123,6 @@ impl Encoder for MemEncoder {
     }
 
     #[inline]
-    fn emit_f64(&mut self, v: f64) {
-        let as_u64: u64 = v.to_bits();
-        self.emit_u64(as_u64);
-    }
-
-    #[inline]
-    fn emit_f32(&mut self, v: f32) {
-        let as_u32: u32 = v.to_bits();
-        self.emit_u32(as_u32);
-    }
-
-    #[inline]
     fn emit_char(&mut self, v: char) {
         self.emit_u32(v as u32);
     }
@@ -501,18 +489,6 @@ impl Encoder for FileEncoder {
     }
 
     #[inline]
-    fn emit_f64(&mut self, v: f64) {
-        let as_u64: u64 = v.to_bits();
-        self.emit_u64(as_u64);
-    }
-
-    #[inline]
-    fn emit_f32(&mut self, v: f32) {
-        let as_u32: u32 = v.to_bits();
-        self.emit_u32(as_u32);
-    }
-
-    #[inline]
     fn emit_char(&mut self, v: char) {
         self.emit_u32(v as u32);
     }
@@ -643,18 +619,6 @@ impl<'a> Decoder for MemDecoder<'a> {
     }
 
     #[inline]
-    fn read_f64(&mut self) -> f64 {
-        let bits = self.read_u64();
-        f64::from_bits(bits)
-    }
-
-    #[inline]
-    fn read_f32(&mut self) -> f32 {
-        let bits = self.read_u32();
-        f32::from_bits(bits)
-    }
-
-    #[inline]
     fn read_char(&mut self) -> char {
         let bits = self.read_u32();
         std::char::from_u32(bits).unwrap()
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 567fe06109b..527abc23727 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -22,6 +22,11 @@ use std::sync::Arc;
 /// be processed or ignored, whichever is appropriate. Then they should provide
 /// a `finish` method that finishes up encoding. If the encoder is fallible,
 /// `finish` should return a `Result` that indicates success or failure.
+///
+/// This current does not support `f32` nor `f64`, as they're not needed in any
+/// serialized data structures. That could be changed, but consider whether it
+/// really makes sense to store floating-point values at all.
+/// (If you need it, revert <https://github.com/rust-lang/rust/pull/109984>.)
 pub trait Encoder {
     // Primitive types:
     fn emit_usize(&mut self, v: usize);
@@ -37,8 +42,6 @@ pub trait Encoder {
     fn emit_i16(&mut self, v: i16);
     fn emit_i8(&mut self, v: i8);
     fn emit_bool(&mut self, v: bool);
-    fn emit_f64(&mut self, v: f64);
-    fn emit_f32(&mut self, v: f32);
     fn emit_char(&mut self, v: char);
     fn emit_str(&mut self, v: &str);
     fn emit_raw_bytes(&mut self, s: &[u8]);
@@ -58,6 +61,11 @@ pub trait Encoder {
 // top-level invocation would also just panic on failure. Switching to
 // infallibility made things faster and lots of code a little simpler and more
 // concise.
+///
+/// This current does not support `f32` nor `f64`, as they're not needed in any
+/// serialized data structures. That could be changed, but consider whether it
+/// really makes sense to store floating-point values at all.
+/// (If you need it, revert <https://github.com/rust-lang/rust/pull/109984>.)
 pub trait Decoder {
     // Primitive types:
     fn read_usize(&mut self) -> usize;
@@ -73,8 +81,6 @@ pub trait Decoder {
     fn read_i16(&mut self) -> i16;
     fn read_i8(&mut self) -> i8;
     fn read_bool(&mut self) -> bool;
-    fn read_f64(&mut self) -> f64;
-    fn read_f32(&mut self) -> f32;
     fn read_char(&mut self) -> char;
     fn read_str(&mut self) -> &str;
     fn read_raw_bytes(&mut self, len: usize) -> &[u8];
@@ -143,8 +149,6 @@ direct_serialize_impls! {
     i64 emit_i64 read_i64,
     i128 emit_i128 read_i128,
 
-    f32 emit_f32 read_f32,
-    f64 emit_f64 read_f64,
     bool emit_bool read_bool,
     char emit_char read_char
 }
diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs
index 3a695d0714e..5e7dd18aa84 100644
--- a/compiler/rustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/tests/opaque.rs
@@ -22,8 +22,6 @@ struct Struct {
 
     l: char,
     m: String,
-    n: f32,
-    o: f64,
     p: bool,
     q: Option<u32>,
 }
@@ -120,24 +118,6 @@ fn test_bool() {
 }
 
 #[test]
-fn test_f32() {
-    let mut vec = vec![];
-    for i in -100..100 {
-        vec.push((i as f32) / 3.0);
-    }
-    check_round_trip(vec);
-}
-
-#[test]
-fn test_f64() {
-    let mut vec = vec![];
-    for i in -100..100 {
-        vec.push((i as f64) / 3.0);
-    }
-    check_round_trip(vec);
-}
-
-#[test]
 fn test_char() {
     let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
     check_round_trip(vec);
@@ -200,8 +180,6 @@ fn test_struct() {
 
         l: 'x',
         m: "abc".to_string(),
-        n: 20.5,
-        o: 21.5,
         p: false,
         q: None,
     }]);
@@ -222,8 +200,6 @@ fn test_struct() {
 
         l: 'y',
         m: "def".to_string(),
-        n: -20.5,
-        o: -21.5,
         p: true,
         q: Some(1234567),
     }]);
@@ -232,7 +208,7 @@ fn test_struct() {
 #[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
 enum Enum {
     Variant1,
-    Variant2(usize, f32),
+    Variant2(usize, u32),
     Variant3 { a: i32, b: char, c: bool },
 }
 
@@ -240,7 +216,7 @@ enum Enum {
 fn test_enum() {
     check_round_trip(vec![
         Enum::Variant1,
-        Enum::Variant2(1, 2.5),
+        Enum::Variant2(1, 25),
         Enum::Variant3 { a: 3, b: 'b', c: false },
         Enum::Variant3 { a: -4, b: 'f', c: true },
     ]);
@@ -269,8 +245,8 @@ fn test_hash_map() {
 
 #[test]
 fn test_tuples() {
-    check_round_trip(vec![('x', (), false, 0.5f32)]);
-    check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
+    check_round_trip(vec![('x', (), false, 5u32)]);
+    check_round_trip(vec![(9i8, 10u16, 15i64)]);
     check_round_trip(vec![(-12i16, 11u8, 12usize)]);
     check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
     check_round_trip(vec![(String::new(), "some string".to_string())]);
diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 89f0386e3e9..9fe9e3a7a5f 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -174,10 +174,10 @@ pub fn find_best_match_for_name(
 fn find_best_match_for_name_impl(
     use_substring_score: bool,
     candidates: &[Symbol],
-    lookup: Symbol,
+    lookup_symbol: Symbol,
     dist: Option<usize>,
 ) -> Option<Symbol> {
-    let lookup = lookup.as_str();
+    let lookup = lookup_symbol.as_str();
     let lookup_uppercase = lookup.to_uppercase();
 
     // Priority of matches:
@@ -190,6 +190,8 @@ fn find_best_match_for_name_impl(
 
     let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
     let mut best = None;
+    // store the candidates with the same distance, only for `use_substring_score` current.
+    let mut next_candidates = vec![];
     for c in candidates {
         match if use_substring_score {
             edit_distance_with_substrings(lookup, c.as_str(), dist)
@@ -198,12 +200,36 @@ fn find_best_match_for_name_impl(
         } {
             Some(0) => return Some(*c),
             Some(d) => {
-                dist = d - 1;
+                if use_substring_score {
+                    if d < dist {
+                        dist = d;
+                        next_candidates.clear();
+                    } else {
+                        // `d == dist` here, we need to store the candidates with the same distance
+                        // so we won't decrease the distance in the next loop.
+                    }
+                    next_candidates.push(*c);
+                } else {
+                    dist = d - 1;
+                }
                 best = Some(*c);
             }
             None => {}
         }
     }
+
+    // We have a tie among several candidates, try to select the best among them ignoring substrings.
+    // For example, the candidates list `force_capture`, `capture`, and user inputed `forced_capture`,
+    // we select `force_capture` with a extra round of edit distance calculation.
+    if next_candidates.len() > 1 {
+        debug_assert!(use_substring_score);
+        best = find_best_match_for_name_impl(
+            false,
+            &next_candidates,
+            lookup_symbol,
+            Some(lookup.len()),
+        );
+    }
     if best.is_some() {
         return best;
     }
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
index fcb965dd725..4a3b7e42bac 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs
@@ -1,7 +1,9 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{def_id::DefId, Movability, Mutability};
 use rustc_infer::traits::query::NoSolution;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable};
+use rustc_middle::ty::{
+    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
+};
 
 use crate::solve::EvalCtxt;
 
@@ -60,7 +62,16 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
 
         ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
 
-        ty::GeneratorWitnessMIR(..) => todo!(),
+        ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx
+            .tcx()
+            .generator_hidden_types(def_id)
+            .map(|bty| {
+                ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
+                    tcx,
+                    bty.subst(tcx, substs),
+                ))
+            })
+            .collect()),
 
         // For `PhantomData<T>`, we pass `T`.
         ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]),
@@ -76,6 +87,29 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
     }
 }
 
+fn replace_erased_lifetimes_with_bound_vars<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: Ty<'tcx>,
+) -> ty::Binder<'tcx, Ty<'tcx>> {
+    debug_assert!(!ty.has_late_bound_regions());
+    let mut counter = 0;
+    let ty = tcx.fold_regions(ty, |mut r, current_depth| {
+        if let ty::ReErased = r.kind() {
+            let br = ty::BoundRegion {
+                var: ty::BoundVar::from_u32(counter),
+                kind: ty::BrAnon(counter, None),
+            };
+            counter += 1;
+            r = tcx.mk_re_late_bound(current_depth, br);
+        }
+        r
+    });
+    let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
+        (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))),
+    );
+    ty::Binder::bind_with_vars(ty, bound_vars)
+}
+
 pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
@@ -178,7 +212,16 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
 
         ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
 
-        ty::GeneratorWitnessMIR(..) => todo!(),
+        ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx
+            .tcx()
+            .generator_hidden_types(def_id)
+            .map(|bty| {
+                ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
+                    ecx.tcx(),
+                    bty.subst(ecx.tcx(), substs),
+                ))
+            })
+            .collect()),
     }
 }
 
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index c7e7ed3e95e..c1cd3c74ab6 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -359,7 +359,7 @@ use crate::vec::Vec;
 /// [Deref]: core::ops::Deref "ops::Deref"
 /// [`Deref`]: core::ops::Deref "ops::Deref"
 /// [`as_str()`]: String::as_str
-#[derive(PartialOrd, Eq, Ord)]
+#[derive(PartialEq, PartialOrd, Eq, Ord)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), lang = "String")]
 pub struct String {
@@ -2207,14 +2207,6 @@ impl<'a, 'b> Pattern<'a> for &'b String {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl PartialEq for String {
-    #[inline]
-    fn eq(&self, other: &String) -> bool {
-        PartialEq::eq(&self[..], &other[..])
-    }
-}
-
 macro_rules! impl_eq {
     ($lhs:ty, $rhs: ty) => {
         #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index e86eaa65b75..9df19352567 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -352,7 +352,7 @@ pre.item-decl {
 .source .content pre {
 	padding: 20px;
 }
-.rustdoc.source .example-wrap > pre.src-line-numbers  {
+.rustdoc.source .example-wrap pre.src-line-numbers  {
 	padding: 20px 0 20px 4px;
 }
 
@@ -537,17 +537,17 @@ ul.block, .block li {
 	margin-bottom: 0px;
 }
 
-.rustdoc .example-wrap > pre {
+.rustdoc .example-wrap pre {
 	margin: 0;
 	flex-grow: 1;
 }
 
-.rustdoc:not(.source) .example-wrap > pre {
+.rustdoc:not(.source) .example-wrap pre {
 	overflow: auto hidden;
 }
 
-.rustdoc .example-wrap > pre.example-line-numbers,
-.rustdoc .example-wrap > pre.src-line-numbers {
+.rustdoc .example-wrap pre.example-line-numbers,
+.rustdoc .example-wrap pre.src-line-numbers {
 	flex-grow: 0;
 	min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */
 	overflow: initial;
@@ -558,7 +558,7 @@ ul.block, .block li {
 	color: var(--src-line-numbers-span-color);
 }
 
-.rustdoc .example-wrap > pre.src-line-numbers {
+.rustdoc .example-wrap pre.src-line-numbers {
 	padding: 14px 0;
 }
 .src-line-numbers a, .src-line-numbers span {
@@ -706,7 +706,7 @@ h2.small-section-header > .anchor {
 }
 
 .main-heading a:hover,
-.example-wrap > .rust a:hover,
+.example-wrap .rust a:hover,
 .all-items a:hover,
 .docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,
 .docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,
diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html
index a224ff12f44..42d01277db2 100644
--- a/src/librustdoc/html/templates/source.html
+++ b/src/librustdoc/html/templates/source.html
@@ -1,5 +1,7 @@
 <div class="example-wrap"> {# #}
-    <pre class="src-line-numbers">
+    {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
+       Do not show "1 2 3 4 5 ..." in web search results. #}
+    <div data-nosnippet><pre class="src-line-numbers">
         {% for line in lines.clone() %}
             {% if embedded %}
                 <span>{{line|safe}}</span>
@@ -7,7 +9,7 @@
                 <a href="#{{line|safe}}" id="{{line|safe}}">{{line|safe}}</a>
             {%~ endif %}
         {% endfor %}
-    </pre> {# #}
+    </pre></div> {# #}
     <pre class="rust"> {# #}
         <code>
             {% if needs_expansion %}
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 50b99b80572..735351fbf60 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -144,6 +144,8 @@ pub struct TestProps {
     pub normalize_stdout: Vec<(String, String)>,
     pub normalize_stderr: Vec<(String, String)>,
     pub failure_status: i32,
+    // For UI tests, allows compiler to exit with arbitrary failure status
+    pub dont_check_failure_status: bool,
     // Whether or not `rustfix` should apply the `CodeSuggestion`s of this test and compile the
     // resulting Rust code.
     pub run_rustfix: bool,
@@ -186,6 +188,7 @@ mod directives {
     pub const CHECK_TEST_LINE_NUMBERS_MATCH: &'static str = "check-test-line-numbers-match";
     pub const IGNORE_PASS: &'static str = "ignore-pass";
     pub const FAILURE_STATUS: &'static str = "failure-status";
+    pub const DONT_CHECK_FAILURE_STATUS: &'static str = "dont-check-failure-status";
     pub const RUN_RUSTFIX: &'static str = "run-rustfix";
     pub const RUSTFIX_ONLY_MACHINE_APPLICABLE: &'static str = "rustfix-only-machine-applicable";
     pub const ASSEMBLY_OUTPUT: &'static str = "assembly-output";
@@ -233,6 +236,7 @@ impl TestProps {
             normalize_stdout: vec![],
             normalize_stderr: vec![],
             failure_status: -1,
+            dont_check_failure_status: false,
             run_rustfix: false,
             rustfix_only_machine_applicable: false,
             assembly_output: None,
@@ -395,6 +399,12 @@ impl TestProps {
                     self.failure_status = code;
                 }
 
+                config.set_name_directive(
+                    ln,
+                    DONT_CHECK_FAILURE_STATUS,
+                    &mut self.dont_check_failure_status,
+                );
+
                 config.set_name_directive(ln, RUN_RUSTFIX, &mut self.run_rustfix);
                 config.set_name_directive(
                     ln,
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 794c845458b..a35284f05b5 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -310,7 +310,9 @@ impl<'test> TestCx<'test> {
                 );
             }
 
-            self.check_correct_failure_status(proc_res);
+            if !self.props.dont_check_failure_status {
+                self.check_correct_failure_status(proc_res);
+            }
         }
     }
 
diff --git a/tests/ui/argument-suggestions/issue-109425.fixed b/tests/ui/argument-suggestions/issue-109425.fixed
new file mode 100644
index 00000000000..143ddf99586
--- /dev/null
+++ b/tests/ui/argument-suggestions/issue-109425.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+
+fn f() {}
+fn i(_: u32) {}
+fn is(_: u32, _: &str) {}
+fn s(_: &str) {}
+
+fn main() {
+    // code             expected suggestion
+    f();        // f()
+    //~^ error: this function takes 0 arguments but 2 arguments were supplied
+    i(0,);     // i(0,)
+    //~^ error: this function takes 1 argument but 3 arguments were supplied
+    i(0);      // i(0)
+    //~^ error: this function takes 1 argument but 3 arguments were supplied
+    is(0, ""); // is(0, "")
+    //~^ error: this function takes 2 arguments but 4 arguments were supplied
+    s("");     // s("")
+    //~^ error: this function takes 1 argument but 3 arguments were supplied
+}
diff --git a/tests/ui/argument-suggestions/issue-109425.rs b/tests/ui/argument-suggestions/issue-109425.rs
new file mode 100644
index 00000000000..a845c419555
--- /dev/null
+++ b/tests/ui/argument-suggestions/issue-109425.rs
@@ -0,0 +1,20 @@
+// run-rustfix
+
+fn f() {}
+fn i(_: u32) {}
+fn is(_: u32, _: &str) {}
+fn s(_: &str) {}
+
+fn main() {
+    // code             expected suggestion
+    f(0, 1,);        // f()
+    //~^ error: this function takes 0 arguments but 2 arguments were supplied
+    i(0, 1, 2,);     // i(0,)
+    //~^ error: this function takes 1 argument but 3 arguments were supplied
+    i(0, 1, 2);      // i(0)
+    //~^ error: this function takes 1 argument but 3 arguments were supplied
+    is(0, 1, 2, ""); // is(0, "")
+    //~^ error: this function takes 2 arguments but 4 arguments were supplied
+    s(0, 1, "");     // s("")
+    //~^ error: this function takes 1 argument but 3 arguments were supplied
+}
diff --git a/tests/ui/argument-suggestions/issue-109425.stderr b/tests/ui/argument-suggestions/issue-109425.stderr
new file mode 100644
index 00000000000..1514f1cb487
--- /dev/null
+++ b/tests/ui/argument-suggestions/issue-109425.stderr
@@ -0,0 +1,98 @@
+error[E0061]: this function takes 0 arguments but 2 arguments were supplied
+  --> $DIR/issue-109425.rs:10:5
+   |
+LL |     f(0, 1,);        // f()
+   |     ^ -  - unexpected argument of type `{integer}`
+   |       |
+   |       unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:3:4
+   |
+LL | fn f() {}
+   |    ^
+help: remove the extra arguments
+   |
+LL -     f(0, 1,);        // f()
+LL +     f();        // f()
+   |
+
+error[E0061]: this function takes 1 argument but 3 arguments were supplied
+  --> $DIR/issue-109425.rs:12:5
+   |
+LL |     i(0, 1, 2,);     // i(0,)
+   |     ^    -  - unexpected argument of type `{integer}`
+   |          |
+   |          unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:4:4
+   |
+LL | fn i(_: u32) {}
+   |    ^ ------
+help: remove the extra arguments
+   |
+LL -     i(0, 1, 2,);     // i(0,)
+LL +     i(0,);     // i(0,)
+   |
+
+error[E0061]: this function takes 1 argument but 3 arguments were supplied
+  --> $DIR/issue-109425.rs:14:5
+   |
+LL |     i(0, 1, 2);      // i(0)
+   |     ^    -  - unexpected argument of type `{integer}`
+   |          |
+   |          unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:4:4
+   |
+LL | fn i(_: u32) {}
+   |    ^ ------
+help: remove the extra arguments
+   |
+LL -     i(0, 1, 2);      // i(0)
+LL +     i(0);      // i(0)
+   |
+
+error[E0061]: this function takes 2 arguments but 4 arguments were supplied
+  --> $DIR/issue-109425.rs:16:5
+   |
+LL |     is(0, 1, 2, ""); // is(0, "")
+   |     ^^    -  - unexpected argument of type `{integer}`
+   |           |
+   |           unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:5:4
+   |
+LL | fn is(_: u32, _: &str) {}
+   |    ^^ ------  -------
+help: remove the extra arguments
+   |
+LL -     is(0, 1, 2, ""); // is(0, "")
+LL +     is(0, ""); // is(0, "")
+   |
+
+error[E0061]: this function takes 1 argument but 3 arguments were supplied
+  --> $DIR/issue-109425.rs:18:5
+   |
+LL |     s(0, 1, "");     // s("")
+   |     ^ -  - unexpected argument of type `{integer}`
+   |       |
+   |       unexpected argument of type `{integer}`
+   |
+note: function defined here
+  --> $DIR/issue-109425.rs:6:4
+   |
+LL | fn s(_: &str) {}
+   |    ^ -------
+help: remove the extra arguments
+   |
+LL -     s(0, 1, "");     // s("")
+LL +     s("");     // s("")
+   |
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0061`.
diff --git a/tests/ui/recursion/issue-95134.rs b/tests/ui/recursion/issue-95134.rs
index fdc4d536981..2f1cffa2fa9 100644
--- a/tests/ui/recursion/issue-95134.rs
+++ b/tests/ui/recursion/issue-95134.rs
@@ -1,7 +1,7 @@
 // build-fail
 // known-bug: #95134
 // compile-flags: -Copt-level=0
-// failure-status: 101
+// dont-check-failure-status
 // dont-check-compiler-stderr
 
 pub fn encode_num<Writer: ExampleWriter>(n: u32, mut writer: Writer) -> Result<(), Writer::Error> {
diff --git a/tests/ui/suggestions/issue-109291.rs b/tests/ui/suggestions/issue-109291.rs
new file mode 100644
index 00000000000..1947b16a32e
--- /dev/null
+++ b/tests/ui/suggestions/issue-109291.rs
@@ -0,0 +1,4 @@
+fn main() {
+    println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture());
+    //~^ ERROR no function or associated item name
+}
diff --git a/tests/ui/suggestions/issue-109291.stderr b/tests/ui/suggestions/issue-109291.stderr
new file mode 100644
index 00000000000..4ef5948d9bf
--- /dev/null
+++ b/tests/ui/suggestions/issue-109291.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no function or associated item named `forced_capture` found for struct `Backtrace` in the current scope
+  --> $DIR/issue-109291.rs:2:65
+   |
+LL |     println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture());
+   |                                                                 ^^^^^^^^^^^^^^
+   |                                                                 |
+   |                                                                 function or associated item not found in `Backtrace`
+   |                                                                 help: there is an associated function with a similar name: `force_capture`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/suggestions/issue-109396.stderr b/tests/ui/suggestions/issue-109396.stderr
index eca160e2fab..d4956872a39 100644
--- a/tests/ui/suggestions/issue-109396.stderr
+++ b/tests/ui/suggestions/issue-109396.stderr
@@ -25,7 +25,7 @@ note: function defined here
 help: remove the extra arguments
    |
 LL -             file.as_raw_fd(),
-LL +             ,
+LL +             );
    |
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
new file mode 100644
index 00000000000..6a926534e07
--- /dev/null
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
@@ -0,0 +1,18 @@
+error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
+  --> $DIR/auto-with-drop_tracking_mir.rs:24:13
+   |
+LL |     is_send(foo());
+   |     ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
+   |
+   = help: the trait `Send` is not implemented for `impl Future<Output = ()>`
+note: required by a bound in `is_send`
+  --> $DIR/auto-with-drop_tracking_mir.rs:23:24
+   |
+LL |     fn is_send(_: impl Send) {}
+   |                        ^^^^ required by this bound in `is_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
new file mode 100644
index 00000000000..a5db7c4636b
--- /dev/null
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
@@ -0,0 +1,26 @@
+// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir
+// edition: 2021
+// revisions: pass fail
+//[pass] check-pass
+
+#![feature(negative_impls)]
+
+struct NotSync;
+impl !Sync for NotSync {}
+
+async fn foo() {
+    #[cfg(pass)]
+    let x = &();
+    #[cfg(fail)]
+    let x = &NotSync;
+    bar().await;
+    drop(x);
+}
+
+async fn bar() {}
+
+fn main() {
+    fn is_send(_: impl Send) {}
+    is_send(foo());
+    //[fail]~^ ERROR `impl Future<Output = ()>` cannot be sent between threads safely
+}