about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-02 04:30:51 +0000
committerbors <bors@rust-lang.org>2023-08-02 04:30:51 +0000
commit7a5d2d0138d4a3d7d97cad0ca72ab62e938e0b0b (patch)
tree662f74dd3bc2dec57c65dcdcabe8b716410eca3f
parent90bb4184f89a24d26787a9eada781bf3c4dd3dc6 (diff)
parent4876afba38cb645da498d35ad0a3be2452f6f6af (diff)
Auto merge of #114358 - matthiaskrgr:rollup-d810m9e, r=matthiaskrgr
Rollup of 6 pull requests

Successful merges:

 - #114178 (Account for macros when suggesting a new let binding)
 - #114199 (Don't unsize coerce infer vars in select in new solver)
 - #114301 (Don't check unnecessarily that impl trait is RPIT)
 - #114314 (Tweaks to `adt_sized_constraint`)
 - #114322 (Fix invalid slice coercion suggestion reported in turbofish)
 - #114340 ([rustc_attr][nit] Replace `filter` + `is_some` with `map_or`.)

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_attr/src/builtin.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs4
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs16
-rw-r--r--compiler/rustc_middle/src/ty/context.rs29
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs26
-rw-r--r--tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr6
-rw-r--r--tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs13
-rw-r--r--tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr29
-rw-r--r--tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs12
-rw-r--r--tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr23
-rw-r--r--tests/ui/inference/type-infer-generalize-ty-var.rs4
-rw-r--r--tests/ui/lifetimes/borrowck-let-suggestion.stderr6
-rw-r--r--tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr6
-rw-r--r--tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs17
25 files changed, 168 insertions, 69 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 6cce3a56f08..6ed5fc77d75 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -28,7 +28,7 @@ pub fn rust_version_symbol() -> Symbol {
 }
 
 pub fn is_builtin_attr(attr: &Attribute) -> bool {
-    attr.is_doc_comment() || attr.ident().filter(|ident| is_builtin_attr_name(ident.name)).is_some()
+    attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
 }
 
 enum AttrError {
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 03b90f4ab18..28c0a444fc8 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -2133,13 +2133,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         self.current -= 1;
                     }
                     fn visit_expr(&mut self, expr: &hir::Expr<'tcx>) {
-                        if self.span == expr.span {
+                        if self.span == expr.span.source_callsite() {
                             self.found = self.current;
                         }
                         walk_expr(self, expr);
                     }
                 }
                 let source_info = self.body.source_info(location);
+                let proper_span = proper_span.source_callsite();
                 if let Some(scope) = self.body.source_scopes.get(source_info.scope)
                     && let ClearCrossCrate::Set(scope_data) = &scope.local_data
                     && let Some(node) = self.infcx.tcx.hir().find(scope_data.lint_root)
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 3235a9ceba1..bc109e7ad51 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1462,7 +1462,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     let traits: Vec<_> =
                         self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
 
-                    // Don't print `TyErr` to the user.
+                    // Don't print `ty::Error` to the user.
                     self.report_ambiguous_associated_type(
                         span,
                         &[qself_ty.to_string()],
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index ad886ce82b1..6206ba508ae 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -555,8 +555,8 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
     for (region_a, region_a_idx) in &regions {
         // Ignore `'static` lifetimes for the purpose of this lint: it's
         // because we know it outlives everything and so doesn't give meaningful
-        // clues
-        if let ty::ReStatic = **region_a {
+        // clues. Also ignore `ReError`, to avoid knock-down errors.
+        if let ty::ReStatic | ty::ReError(_) = **region_a {
             continue;
         }
         // For each region argument (e.g., `'a` in our example), check for a
@@ -599,8 +599,9 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
         // on the GAT itself.
         for (region_b, region_b_idx) in &regions {
             // Again, skip `'static` because it outlives everything. Also, we trivially
-            // know that a region outlives itself.
-            if ty::ReStatic == **region_b || region_a == region_b {
+            // know that a region outlives itself. Also ignore `ReError`, to avoid
+            // knock-down errors.
+            if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b {
                 continue;
             }
             if region_known_to_outlive(
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 0624a4baf79..3e67afb1c3d 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -795,7 +795,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Converts the types that the user supplied, in case that doing
     /// so should yield an error, but returns back a signature where
-    /// all parameters are of type `TyErr`.
+    /// all parameters are of type `ty::Error`.
     fn error_sig_of_closure(
         &self,
         decl: &hir::FnDecl<'_>,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 5a78790ec6e..25077f9bb97 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2567,15 +2567,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     None,
                 );
                 if let Some(infer::RelateParamBound(_, t, _)) = origin {
-                    let return_impl_trait =
-                        self.tcx.return_type_impl_trait(generic_param_scope).is_some();
                     let t = self.resolve_vars_if_possible(t);
                     match t.kind() {
                         // We've got:
                         // fn get_later<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
                         // suggest:
                         // fn get_later<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
-                        ty::Closure(..) | ty::Alias(ty::Opaque, ..) if return_impl_trait => {
+                        ty::Closure(..) | ty::Alias(ty::Opaque, ..) => {
                             new_binding_suggestion(&mut err, type_param_span);
                         }
                         _ => {
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index be424424f3a..60d9d6578f5 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -942,6 +942,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
         generic_ty: Ty<'tcx>,
         min: ty::Region<'tcx>,
     ) -> bool {
+        if let ty::ReError(_) = *min {
+            return true;
+        }
+
         match bound {
             VerifyBound::IfEq(verify_if_eq_b) => {
                 let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b);
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 63df2830e0a..1189dcdfcbb 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -706,7 +706,7 @@ rustc_queries! {
         separate_provide_extern
     }
 
-    query adt_sized_constraint(key: DefId) -> &'tcx [Ty<'tcx>] {
+    query adt_sized_constraint(key: DefId) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
         desc { |tcx| "computing `Sized` constraints for `{}`", tcx.def_path_str(key) }
     }
 
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index e067d2a984f..6ba13a76563 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -562,18 +562,10 @@ impl<'tcx> AdtDef<'tcx> {
         tcx.adt_destructor(self.did())
     }
 
-    /// Returns a list of types such that `Self: Sized` if and only
-    /// if that type is `Sized`, or `TyErr` if this type is recursive.
-    ///
-    /// Oddly enough, checking that the sized-constraint is `Sized` is
-    /// actually more expressive than checking all members:
-    /// the `Sized` trait is inductive, so an associated type that references
-    /// `Self` would prevent its containing ADT from being `Sized`.
-    ///
-    /// Due to normalization being eager, this applies even if
-    /// the associated type is behind a pointer (e.g., issue #31299).
-    pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx [Ty<'tcx>]> {
-        ty::EarlyBinder::bind(tcx.adt_sized_constraint(self.did()))
+    /// Returns a list of types such that `Self: Sized` if and only if that
+    /// type is `Sized`, or `ty::Error` if this type has a recursive layout.
+    pub fn sized_constraint(self, tcx: TyCtxt<'tcx>) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
+        tcx.adt_sized_constraint(self.did())
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index aa1f8e48b1b..5eef3e45f32 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -50,9 +50,7 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{
-    Constness, ExprKind, HirId, ImplItemKind, ItemKind, Node, TraitCandidate, TraitItemKind,
-};
+use rustc_hir::{Constness, HirId, Node, TraitCandidate};
 use rustc_index::IndexVec;
 use rustc_macros::HashStable;
 use rustc_query_system::dep_graph::DepNodeIndex;
@@ -1077,31 +1075,6 @@ impl<'tcx> TyCtxt<'tcx> {
         return None;
     }
 
-    pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
-        // `type_of()` will fail on these (#55796, #86483), so only allow `fn`s or closures.
-        match self.hir().get_by_def_id(scope_def_id) {
-            Node::Item(&hir::Item { kind: ItemKind::Fn(..), .. }) => {}
-            Node::TraitItem(&hir::TraitItem { kind: TraitItemKind::Fn(..), .. }) => {}
-            Node::ImplItem(&hir::ImplItem { kind: ImplItemKind::Fn(..), .. }) => {}
-            Node::Expr(&hir::Expr { kind: ExprKind::Closure { .. }, .. }) => {}
-            _ => return None,
-        }
-
-        let ret_ty = self.type_of(scope_def_id).instantiate_identity();
-        match ret_ty.kind() {
-            ty::FnDef(_, _) => {
-                let sig = ret_ty.fn_sig(self);
-                let output = self.erase_late_bound_regions(sig.output());
-                output.is_impl_trait().then(|| {
-                    let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
-                    let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
-                    (output, fn_decl.output.span())
-                })
-            }
-            _ => None,
-        }
-    }
-
     /// Checks if the bound region is in Impl Item.
     pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
         let container_id = self.parent(suitable_region_binding_scope.to_def_id());
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index a2db35e069e..72ba4f59137 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -150,7 +150,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
 
         ty::Adt(def, args) => {
             let sized_crit = def.sized_constraint(ecx.tcx());
-            Ok(sized_crit.iter_instantiated_copied(ecx.tcx(), args).collect())
+            Ok(sized_crit.iter_instantiated(ecx.tcx(), args).collect())
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 1aef9a885bc..8a3c7b22e32 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -235,7 +235,10 @@ fn rematch_unsize<'tcx>(
         goal.param_env,
         &mut nested,
     );
+
     match (a_ty.kind(), b_ty.kind()) {
+        // Don't try to coerce `?0` to `dyn Trait`
+        (ty::Infer(ty::TyVar(_)), _) | (_, ty::Infer(ty::TyVar(_))) => Ok(None),
         // Stall any ambiguous upcasting goals, since we can't rematch those
         (ty::Dynamic(_, _, ty::Dyn), ty::Dynamic(_, _, ty::Dyn)) => match certainty {
             Certainty::Yes => Ok(Some(ImplSource::Builtin(source, nested))),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 14020c05251..95485850d0e 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -3030,8 +3030,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 self.report_similar_impl_candidates_for_root_obligation(&obligation, *trait_predicate, body_def_id, err);
             }
 
-            self.maybe_suggest_convert_to_slice(
+            self.suggest_convert_to_slice(
                 err,
+                obligation,
                 trait_ref,
                 impl_candidates.as_slice(),
                 span,
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 31f70bbd34d..46c31c77613 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -398,9 +398,10 @@ pub trait TypeErrCtxtExt<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
     ) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;
 
-    fn maybe_suggest_convert_to_slice(
+    fn suggest_convert_to_slice(
         &self,
         err: &mut Diagnostic,
+        obligation: &PredicateObligation<'tcx>,
         trait_ref: ty::PolyTraitRef<'tcx>,
         candidate_impls: &[ImplCandidate<'tcx>],
         span: Span,
@@ -3944,13 +3945,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     /// If the type that failed selection is an array or a reference to an array,
     /// but the trait is implemented for slices, suggest that the user converts
     /// the array into a slice.
-    fn maybe_suggest_convert_to_slice(
+    fn suggest_convert_to_slice(
         &self,
         err: &mut Diagnostic,
+        obligation: &PredicateObligation<'tcx>,
         trait_ref: ty::PolyTraitRef<'tcx>,
         candidate_impls: &[ImplCandidate<'tcx>],
         span: Span,
     ) {
+        // We can only suggest the slice coersion for function arguments since the suggestion
+        // would make no sense in turbofish or call
+        let ObligationCauseCode::FunctionArgumentObligation { .. } = obligation.cause.code() else {
+            return;
+        };
+
         // Three cases where we can make a suggestion:
         // 1. `[T; _]` (array of T)
         // 2. `&[T; _]` (reference to array of T)
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index c29696bc817..6080a440de6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2099,7 +2099,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 Where(
                     obligation
                         .predicate
-                        .rebind(sized_crit.iter_instantiated_copied(self.tcx(), args).collect()),
+                        .rebind(sized_crit.iter_instantiated(self.tcx(), args).collect()),
                 )
             }
 
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 791a1f4fa99..ba0258b63cb 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -42,7 +42,7 @@ fn sized_constraint_for_ty<'tcx>(
             let adt_tys = adt.sized_constraint(tcx);
             debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys);
             adt_tys
-                .iter_instantiated_copied(tcx, args)
+                .iter_instantiated(tcx, args)
                 .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty))
                 .collect()
         }
@@ -58,11 +58,18 @@ fn sized_constraint_for_ty<'tcx>(
             // we know that `T` is Sized and do not need to check
             // it on the impl.
 
-            let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] };
-            let sized_predicate =
-                ty::TraitRef::new(tcx, sized_trait, [ty]).without_const().to_predicate(tcx);
+            let Some(sized_trait_def_id) = tcx.lang_items().sized_trait() else { return vec![ty] };
             let predicates = tcx.predicates_of(adtdef.did()).predicates;
-            if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] }
+            if predicates.iter().any(|(p, _)| {
+                p.as_trait_clause().is_some_and(|trait_pred| {
+                    trait_pred.def_id() == sized_trait_def_id
+                        && trait_pred.self_ty().skip_binder() == ty
+                })
+            }) {
+                vec![]
+            } else {
+                vec![ty]
+            }
         }
 
         Placeholder(..) | Bound(..) | Infer(..) => {
@@ -92,10 +99,13 @@ fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness {
 ///     - a tuple of type parameters or projections, if there are multiple
 ///       such.
 ///     - an Error, if a type is infinitely sized
-fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
+fn adt_sized_constraint<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+) -> ty::EarlyBinder<&'tcx ty::List<Ty<'tcx>>> {
     if let Some(def_id) = def_id.as_local() {
         if matches!(tcx.representability(def_id), ty::Representability::Infinite) {
-            return tcx.mk_type_list(&[Ty::new_misc_error(tcx)]);
+            return ty::EarlyBinder::bind(tcx.mk_type_list(&[Ty::new_misc_error(tcx)]));
         }
     }
     let def = tcx.adt_def(def_id);
@@ -107,7 +117,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
 
     debug!("adt_sized_constraint: {:?} => {:?}", def, result);
 
-    result
+    ty::EarlyBinder::bind(result)
 }
 
 /// See `ParamEnv` struct definition for details.
diff --git a/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr b/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr
index 4eeec09b910..6e112e27030 100644
--- a/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr
+++ b/tests/ui/borrowck/borrowck-borrowed-uniq-rvalue-2.stderr
@@ -8,8 +8,12 @@ LL |     let x = defer(&vec!["Goodbye", "world!"]);
 LL |     x.x[0];
    |     ------ borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
    = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~     let binding = vec!["Goodbye", "world!"];
+LL ~     let x = defer(&binding);
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs
new file mode 100644
index 00000000000..c6ef8379f45
--- /dev/null
+++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.rs
@@ -0,0 +1,13 @@
+trait Test {}
+impl Test for &[u8] {}
+
+fn needs_test<T: Test>() -> T {
+    panic!()
+}
+
+fn main() {
+    needs_test::<[u8; 1]>();
+    //~^ ERROR the trait bound
+    let x: [u8; 1] = needs_test();
+    //~^ ERROR the trait bound
+}
diff --git a/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
new file mode 100644
index 00000000000..6752a484448
--- /dev/null
+++ b/tests/ui/dst/issue-90528-unsizing-not-suggestion-110063.stderr
@@ -0,0 +1,29 @@
+error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:9:18
+   |
+LL |     needs_test::<[u8; 1]>();
+   |                  ^^^^^^^ the trait `Test` is not implemented for `[u8; 1]`
+   |
+   = help: the trait `Test` is implemented for `&[u8]`
+note: required by a bound in `needs_test`
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:4:18
+   |
+LL | fn needs_test<T: Test>() -> T {
+   |                  ^^^^ required by this bound in `needs_test`
+
+error[E0277]: the trait bound `[u8; 1]: Test` is not satisfied
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:11:22
+   |
+LL |     let x: [u8; 1] = needs_test();
+   |                      ^^^^^^^^^^ the trait `Test` is not implemented for `[u8; 1]`
+   |
+   = help: the trait `Test` is implemented for `&[u8]`
+note: required by a bound in `needs_test`
+  --> $DIR/issue-90528-unsizing-not-suggestion-110063.rs:4:18
+   |
+LL | fn needs_test<T: Test>() -> T {
+   |                  ^^^^ required by this bound in `needs_test`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs
new file mode 100644
index 00000000000..abc845d3afa
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.rs
@@ -0,0 +1,12 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Iterable {
+    type Item<'a>
+    where
+        Self: 'a;
+
+    fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>;
+    //~^ ERROR use of undeclared lifetime name `'missing`
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr
new file mode 100644
index 00000000000..0d74c0b69ce
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/missing-lt-outlives-in-rpitit-114274.stderr
@@ -0,0 +1,23 @@
+error[E0261]: use of undeclared lifetime name `'missing`
+  --> $DIR/missing-lt-outlives-in-rpitit-114274.rs:8:55
+   |
+LL |     fn iter(&self) -> impl Iterator<Item = Self::Item<'missing>>;
+   |                                                       ^^^^^^^^ undeclared lifetime
+   |
+   = note: for more information on higher-ranked polymorphism, visit https://doc.rust-lang.org/nomicon/hrtb.html
+help: consider making the bound lifetime-generic with a new `'missing` lifetime
+   |
+LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>>;
+   |                            +++++++++++++
+help: consider introducing lifetime `'missing` here
+   |
+LL |     fn iter<'missing>(&self) -> impl Iterator<Item = Self::Item<'missing>>;
+   |            ++++++++++
+help: consider introducing lifetime `'missing` here
+   |
+LL | trait Iterable<'missing> {
+   |               ++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/inference/type-infer-generalize-ty-var.rs b/tests/ui/inference/type-infer-generalize-ty-var.rs
index a3d6916cbf7..8b4a8c32bb2 100644
--- a/tests/ui/inference/type-infer-generalize-ty-var.rs
+++ b/tests/ui/inference/type-infer-generalize-ty-var.rs
@@ -1,4 +1,6 @@
-// run-pass
+// check-pass
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
 
 #![allow(non_upper_case_globals)]
 #![allow(dead_code)]
diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.stderr b/tests/ui/lifetimes/borrowck-let-suggestion.stderr
index 38fd92d7619..da0078698ae 100644
--- a/tests/ui/lifetimes/borrowck-let-suggestion.stderr
+++ b/tests/ui/lifetimes/borrowck-let-suggestion.stderr
@@ -9,8 +9,12 @@ LL |
 LL |     x.use_mut();
    |     - borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
    = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~     let binding = vec![1];
+LL ~     let mut x = binding.iter();
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
index 4ecc6370d3c..9df7f0ffd0c 100644
--- a/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
+++ b/tests/ui/pin-macro/lifetime_errors_on_promotion_misusage.stderr
@@ -9,8 +9,12 @@ LL |
 LL |     stuff(phantom_pinned)
    |           -------------- borrow later used here
    |
-   = note: consider using a `let` binding to create a longer lived value
    = note: this error originates in the macro `pin` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider using a `let` binding to create a longer lived value
+   |
+LL ~     let binding = pin!(PhantomPinned);
+LL ~     let phantom_pinned = identity(binding);
+   |
 
 error[E0716]: temporary value dropped while borrowed
   --> $DIR/lifetime_errors_on_promotion_misusage.rs:18:30
diff --git a/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs b/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs
new file mode 100644
index 00000000000..c2ac80459ca
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-coerce-infer-to-dyn.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+use std::fmt::Display;
+use std::rc::Rc;
+
+fn mk<T: ?Sized>(t: Option<&T>) -> Rc<T> {
+    todo!()
+}
+
+fn main() {
+    let mut x = None;
+    let y = mk(x);
+    // Don't treat the line below as a unsize coercion `Rc<?0> ~> Rc<dyn Display>`
+    let z: Rc<dyn Display> = y;
+    x = Some(&1 as &dyn Display);
+}