about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/type_check/liveness/trace.rs8
-rw-r--r--compiler/rustc_lint/messages.ftl4
-rw-r--r--compiler/rustc_lint/src/autorefs.rs42
-rw-r--r--compiler/rustc_lint/src/lints.rs29
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs38
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs5
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs38
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs28
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs7
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs8
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs7
-rw-r--r--library/alloc/src/raw_vec/mod.rs2
-rw-r--r--library/alloc/src/vec/mod.rs6
-rw-r--r--library/core/src/pin.rs10
-rw-r--r--library/std/src/sys/fs/unix.rs3
-rw-r--r--library/std/src/sys/pal/unix/thread.rs12
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs45
-rw-r--r--src/bootstrap/src/core/download.rs6
-rw-r--r--src/bootstrap/src/lib.rs5
-rw-r--r--tests/ui/drop/dropck-normalize-errors.rs31
-rw-r--r--tests/ui/drop/dropck-normalize-errors.stderr76
-rw-r--r--tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs6
-rw-r--r--tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs33
-rw-r--r--tests/ui/lint/implicit_autorefs.fixed6
-rw-r--r--tests/ui/lint/implicit_autorefs.rs6
-rw-r--r--tests/ui/lint/implicit_autorefs.stderr208
29 files changed, 536 insertions, 146 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
index 7718644b9a9..512288a0f7d 100644
--- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
+++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs
@@ -621,13 +621,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
                         &ocx, op, span,
                     ) {
                         Ok(_) => ocx.select_all_or_error(),
-                        Err(e) => {
-                            if e.is_empty() {
-                                ocx.select_all_or_error()
-                            } else {
-                                e
-                            }
-                        }
+                        Err(e) => e,
                     };
 
                     // Could have no errors if a type lowering error, say, caused the query
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 99b42ee5480..08180bf8f8b 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -362,6 +362,10 @@ lint_impl_trait_redundant_captures = all possible in-scope parameters are alread
 
 lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
     .note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
+    .raw_ptr = this raw pointer has type `{$raw_ptr_ty}`
+    .autoref = autoref is being applied to this expression, resulting in: `{$autoref_ty}`
+    .overloaded_deref = references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
+    .method_def = method calls to `{$method_name}` require a reference
     .suggestion = try using a raw pointer method instead; or if this reference is intentional, make it explicit
 
 lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs
index 91d58d92466..5de2cbf9939 100644
--- a/compiler/rustc_lint/src/autorefs.rs
+++ b/compiler/rustc_lint/src/autorefs.rs
@@ -4,7 +4,10 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, OverloadedDer
 use rustc_session::{declare_lint, declare_lint_pass};
 use rustc_span::sym;
 
-use crate::lints::{ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsSuggestion};
+use crate::lints::{
+    ImplicitUnsafeAutorefsDiag, ImplicitUnsafeAutorefsMethodNote, ImplicitUnsafeAutorefsOrigin,
+    ImplicitUnsafeAutorefsSuggestion,
+};
 use crate::{LateContext, LateLintPass, LintContext};
 
 declare_lint! {
@@ -92,25 +95,37 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitAutorefs {
             && let adjustments = peel_derefs_adjustments(&**adjustments)
             // 3. An automatically inserted reference (might come from a deref).
             && let [adjustment] = adjustments
-            && let Some(borrow_mutbl) = has_implicit_borrow(adjustment)
+            && let Some((borrow_mutbl, through_overloaded_deref)) = has_implicit_borrow(adjustment)
             && let ExprKind::Unary(UnOp::Deref, dereferenced) =
                 // 2. Any number of place projections.
                 peel_place_mappers(inner).kind
             // 1. Deref of a raw pointer.
             && typeck.expr_ty(dereferenced).is_raw_ptr()
-            // PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
-            && match expr.kind {
-                ExprKind::MethodCall(..) => matches!(
-                    cx.typeck_results().type_dependent_def_id(expr.hir_id),
-                    Some(def_id) if cx.tcx.has_attr(def_id, sym::rustc_no_implicit_autorefs)
-                ),
-                _ => true,
+            && let method_did = match expr.kind {
+                // PERF: 5. b. A method call annotated with `#[rustc_no_implicit_refs]`
+                ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id),
+                _ => None,
             }
+            && method_did.map(|did| cx.tcx.has_attr(did, sym::rustc_no_implicit_autorefs)).unwrap_or(true)
         {
             cx.emit_span_lint(
                 DANGEROUS_IMPLICIT_AUTOREFS,
                 expr.span.source_callsite(),
                 ImplicitUnsafeAutorefsDiag {
+                    raw_ptr_span: dereferenced.span,
+                    raw_ptr_ty: typeck.expr_ty(dereferenced),
+                    origin: if through_overloaded_deref {
+                        ImplicitUnsafeAutorefsOrigin::OverloadedDeref
+                    } else {
+                        ImplicitUnsafeAutorefsOrigin::Autoref {
+                            autoref_span: inner.span,
+                            autoref_ty: typeck.expr_ty_adjusted(inner),
+                        }
+                    },
+                    method: method_did.map(|did| ImplicitUnsafeAutorefsMethodNote {
+                        def_span: cx.tcx.def_span(did),
+                        method_name: cx.tcx.item_name(did),
+                    }),
                     suggestion: ImplicitUnsafeAutorefsSuggestion {
                         mutbl: borrow_mutbl.ref_prefix_str(),
                         deref: if is_coming_from_deref { "*" } else { "" },
@@ -146,11 +161,12 @@ fn peel_derefs_adjustments<'a>(mut adjs: &'a [Adjustment<'a>]) -> &'a [Adjustmen
 
 /// Test if some adjustment has some implicit borrow.
 ///
-/// Returns `Some(mutability)` if the argument adjustment has implicit borrow in it.
-fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<Mutability> {
+/// Returns `Some((mutability, was_an_overloaded_deref))` if the argument adjustment is
+/// an implicit borrow (or has an implicit borrow via an overloaded deref).
+fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<(Mutability, bool)> {
     match kind {
-        &Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some(mutbl),
-        &Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some(mutbl.into()),
+        &Adjust::Deref(Some(OverloadedDeref { mutbl, .. })) => Some((mutbl, true)),
+        &Adjust::Borrow(AutoBorrow::Ref(mutbl)) => Some((mutbl.into(), false)),
         Adjust::NeverToAny
         | Adjust::Pointer(..)
         | Adjust::ReborrowPin(..)
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 487184b836a..7268a7f704f 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -59,12 +59,39 @@ pub(crate) enum ShadowedIntoIterDiagSub {
 #[derive(LintDiagnostic)]
 #[diag(lint_implicit_unsafe_autorefs)]
 #[note]
-pub(crate) struct ImplicitUnsafeAutorefsDiag {
+pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> {
+    #[label(lint_raw_ptr)]
+    pub raw_ptr_span: Span,
+    pub raw_ptr_ty: Ty<'a>,
+    #[subdiagnostic]
+    pub origin: ImplicitUnsafeAutorefsOrigin<'a>,
+    #[subdiagnostic]
+    pub method: Option<ImplicitUnsafeAutorefsMethodNote>,
     #[subdiagnostic]
     pub suggestion: ImplicitUnsafeAutorefsSuggestion,
 }
 
 #[derive(Subdiagnostic)]
+pub(crate) enum ImplicitUnsafeAutorefsOrigin<'a> {
+    #[note(lint_autoref)]
+    Autoref {
+        #[primary_span]
+        autoref_span: Span,
+        autoref_ty: Ty<'a>,
+    },
+    #[note(lint_overloaded_deref)]
+    OverloadedDeref,
+}
+
+#[derive(Subdiagnostic)]
+#[note(lint_method_def)]
+pub(crate) struct ImplicitUnsafeAutorefsMethodNote {
+    #[primary_span]
+    pub def_span: Span,
+    pub method_name: Symbol,
+}
+
+#[derive(Subdiagnostic)]
 #[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
 pub(crate) struct ImplicitUnsafeAutorefsSuggestion {
     pub mutbl: &'static str,
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index 345a272895d..542e212e1bf 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -2,6 +2,7 @@
 
 pub(super) mod structural_traits;
 
+use std::cell::Cell;
 use std::ops::ControlFlow;
 
 use derive_where::derive_where;
@@ -117,24 +118,24 @@ where
     ) -> Result<Candidate<I>, NoSolution> {
         Self::fast_reject_assumption(ecx, goal, assumption)?;
 
-        ecx.probe(|candidate: &Result<Candidate<I>, NoSolution>| match candidate {
-            Ok(candidate) => inspect::ProbeKind::TraitCandidate {
-                source: candidate.source,
-                result: Ok(candidate.result),
-            },
-            Err(NoSolution) => inspect::ProbeKind::TraitCandidate {
-                source: CandidateSource::ParamEnv(ParamEnvSource::Global),
-                result: Err(NoSolution),
-            },
+        // Dealing with `ParamEnv` candidates is a bit of a mess as we need to lazily
+        // check whether the candidate is global while considering normalization.
+        //
+        // We need to write into `source` inside of `match_assumption`, but need to access it
+        // in `probe` even if the candidate does not apply before we get there. We handle this
+        // by using a `Cell` here. We only ever write into it inside of `match_assumption`.
+        let source = Cell::new(CandidateSource::ParamEnv(ParamEnvSource::Global));
+        ecx.probe(|result: &QueryResult<I>| inspect::ProbeKind::TraitCandidate {
+            source: source.get(),
+            result: *result,
         })
         .enter(|ecx| {
-            Self::match_assumption(ecx, goal, assumption)?;
-            let source = ecx.characterize_param_env_assumption(goal.param_env, assumption)?;
-            Ok(Candidate {
-                source,
-                result: ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)?,
+            Self::match_assumption(ecx, goal, assumption, |ecx| {
+                source.set(ecx.characterize_param_env_assumption(goal.param_env, assumption)?);
+                ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             })
         })
+        .map(|result| Candidate { source: source.get(), result })
     }
 
     /// Try equating an assumption predicate against a goal's predicate. If it
@@ -150,10 +151,8 @@ where
     ) -> Result<Candidate<I>, NoSolution> {
         Self::fast_reject_assumption(ecx, goal, assumption)?;
 
-        ecx.probe_trait_candidate(source).enter(|ecx| {
-            Self::match_assumption(ecx, goal, assumption)?;
-            then(ecx)
-        })
+        ecx.probe_trait_candidate(source)
+            .enter(|ecx| Self::match_assumption(ecx, goal, assumption, then))
     }
 
     /// Try to reject the assumption based off of simple heuristics, such as [`ty::ClauseKind`]
@@ -169,7 +168,8 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
         assumption: I::Clause,
-    ) -> Result<(), NoSolution>;
+        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+    ) -> QueryResult<I>;
 
     fn consider_impl_candidate(
         ecx: &mut EvalCtxt<'_, D>,
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 84a83d79cf0..8413c2abbb9 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -61,13 +61,14 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
         assumption: I::Clause,
-    ) -> Result<(), NoSolution> {
+        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+    ) -> QueryResult<I> {
         let host_clause = assumption.as_host_effect_clause().unwrap();
 
         let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
         ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
 
-        Ok(())
+        then(ecx)
     }
 
     /// Register additional assumptions for aliases corresponding to `~const` item bounds.
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index b90e34e7810..2fddc0044cb 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -129,7 +129,40 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
         assumption: I::Clause,
-    ) -> Result<(), NoSolution> {
+        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+    ) -> QueryResult<I> {
+        let cx = ecx.cx();
+        // FIXME(generic_associated_types): Addresses aggressive inference in #92917.
+        //
+        // If this type is a GAT with currently unconstrained arguments, we do not
+        // want to normalize it via a candidate which only applies for a specific
+        // instantiation. We could otherwise keep the GAT as rigid and succeed this way.
+        // See tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs.
+        //
+        // This only avoids normalization if the GAT arguments are fully unconstrained.
+        // This is quite arbitrary but fixing it causes some ambiguity, see #125196.
+        match goal.predicate.alias.kind(cx) {
+            ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
+                for arg in goal.predicate.alias.own_args(cx).iter() {
+                    let Some(term) = arg.as_term() else {
+                        continue;
+                    };
+                    let term = ecx.structurally_normalize_term(goal.param_env, term)?;
+                    if term.is_infer() {
+                        return ecx.evaluate_added_goals_and_make_canonical_response(
+                            Certainty::AMBIGUOUS,
+                        );
+                    }
+                }
+            }
+            ty::AliasTermKind::OpaqueTy
+            | ty::AliasTermKind::InherentTy
+            | ty::AliasTermKind::InherentConst
+            | ty::AliasTermKind::FreeTy
+            | ty::AliasTermKind::FreeConst
+            | ty::AliasTermKind::UnevaluatedConst => {}
+        }
+
         let projection_pred = assumption.as_projection_clause().unwrap();
 
         let assumption_projection_pred = ecx.instantiate_binder_with_infer(projection_pred);
@@ -139,7 +172,6 @@ where
 
         // Add GAT where clauses from the trait's definition
         // FIXME: We don't need these, since these are the type's own WF obligations.
-        let cx = ecx.cx();
         ecx.add_goals(
             GoalSource::AliasWellFormed,
             cx.own_predicates_of(goal.predicate.def_id())
@@ -147,7 +179,7 @@ where
                 .map(|pred| goal.with(cx, pred)),
         );
 
-        Ok(())
+        then(ecx)
     }
 
     fn consider_additional_alias_assumptions(
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index e3addf8bf93..966d5422fbb 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -17,7 +17,7 @@ use crate::solve::assembly::{self, AllowInferenceConstraints, AssembleCandidates
 use crate::solve::inspect::ProbeKind;
 use crate::solve::{
     BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
-    NoSolution, ParamEnvSource,
+    NoSolution, ParamEnvSource, QueryResult,
 };
 
 impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
@@ -150,13 +150,14 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
         assumption: I::Clause,
-    ) -> Result<(), NoSolution> {
+        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
+    ) -> QueryResult<I> {
         let trait_clause = assumption.as_trait_clause().unwrap();
 
         let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
         ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
 
-        Ok(())
+        then(ecx)
     }
 
     fn consider_auto_trait_candidate(
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index f04a5feba30..38cfdcdc22d 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -196,11 +196,31 @@ where
                 debug!("dropck_outlives: ty from dtorck_types = {:?}", ty);
                 ty
             } else {
-                ocx.deeply_normalize(&cause, param_env, ty)?;
+                // Flush errors b/c `deeply_normalize` doesn't expect pending
+                // obligations, and we may have pending obligations from the
+                // branch above (from other types).
+                let errors = ocx.select_all_or_error();
+                if !errors.is_empty() {
+                    return Err(errors);
+                }
 
-                let errors = ocx.select_where_possible();
-                debug!("normalize errors: {ty} ~> {errors:#?}");
-                return Err(errors);
+                // When query normalization fails, we don't get back an interesting
+                // reason that we could use to report an error in borrowck. In order to turn
+                // this into a reportable error, we deeply normalize again. We don't expect
+                // this to succeed, so delay a bug if it does.
+                match ocx.deeply_normalize(&cause, param_env, ty) {
+                    Ok(_) => {
+                        tcx.dcx().span_delayed_bug(
+                            span,
+                            format!(
+                                "query normalize succeeded of {ty}, \
+                                but deep normalize failed",
+                            ),
+                        );
+                        ty
+                    }
+                    Err(errors) => return Err(errors),
+                }
             };
 
             match ty.kind() {
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 4ce37db4280..77c24adabe3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1760,12 +1760,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         if is_match {
             let generics = self.tcx().generics_of(obligation.predicate.def_id);
-            // FIXME(generic-associated-types): Addresses aggressive inference in #92917.
+            // FIXME(generic_associated_types): Addresses aggressive inference in #92917.
             // If this type is a GAT, and of the GAT args resolve to something new,
             // that means that we must have newly inferred something about the GAT.
             // We should give up in that case.
-            // FIXME(generic-associated-types): This only detects one layer of inference,
-            // which is probably not what we actually want, but fixing it causes some ambiguity:
+            //
+            // This only detects one layer of inference, which is probably not what we actually
+            // want, but fixing it causes some ambiguity:
             // <https://github.com/rust-lang/rust/issues/125196>.
             if !generics.is_own_empty()
                 && obligation.predicate.args[generics.parent_count..].iter().any(|&p| {
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index e6e6466766b..ee4a8096462 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -298,6 +298,14 @@ pub trait GenericArg<I: Interner<GenericArg = Self>>:
     + From<I::Region>
     + From<I::Const>
 {
+    fn as_term(&self) -> Option<I::Term> {
+        match self.kind() {
+            ty::GenericArgKind::Lifetime(_) => None,
+            ty::GenericArgKind::Type(ty) => Some(ty.into()),
+            ty::GenericArgKind::Const(ct) => Some(ct.into()),
+        }
+    }
+
     fn as_type(&self) -> Option<I::Ty> {
         if let ty::GenericArgKind::Type(ty) = self.kind() { Some(ty) } else { None }
     }
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index b59495b93c8..f02d9c988c8 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -682,6 +682,13 @@ impl<I: Interner> AliasTerm<I> {
     pub fn trait_ref(self, interner: I) -> TraitRef<I> {
         self.trait_ref_and_own_args(interner).0
     }
+
+    /// Extract the own args from this projection.
+    /// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
+    /// then this function would return the slice `['a]` as the own args.
+    pub fn own_args(self, interner: I) -> I::GenericArgsSlice {
+        self.trait_ref_and_own_args(interner).1
+    }
 }
 
 /// The following methods work only with inherent associated term projections.
diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs
index a989e5b55b3..3e006a2d1bd 100644
--- a/library/alloc/src/raw_vec/mod.rs
+++ b/library/alloc/src/raw_vec/mod.rs
@@ -287,7 +287,7 @@ impl<T, A: Allocator> RawVec<T, A> {
     }
 
     #[inline]
-    pub(crate) fn non_null(&self) -> NonNull<T> {
+    pub(crate) const fn non_null(&self) -> NonNull<T> {
         self.inner.non_null()
     }
 
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index a97912304c8..59879f23d78 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1816,10 +1816,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_ptr`]: Vec::as_ptr
     /// [`as_non_null`]: Vec::as_non_null
     #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
+    #[rustc_const_unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
     #[inline]
-    pub fn as_non_null(&mut self) -> NonNull<T> {
-        // SAFETY: A `Vec` always has a non-null pointer.
-        unsafe { NonNull::new_unchecked(self.as_mut_ptr()) }
+    pub const fn as_non_null(&mut self) -> NonNull<T> {
+        self.buf.non_null()
     }
 
     /// Returns a reference to the underlying allocator.
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index ecfa723722d..257424b355f 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -12,11 +12,11 @@
 //! "pinned," in that it has been permanently (until the end of its lifespan) attached to its
 //! location in memory, as though pinned to a pinboard. Pinning a value is an incredibly useful
 //! building block for [`unsafe`] code to be able to reason about whether a raw pointer to the
-//! pinned value is still valid. [As we'll see later][drop-guarantee], this is necessarily from the
-//! time the value is first pinned until the end of its lifespan. This concept of "pinning" is
-//! necessary to implement safe interfaces on top of things like self-referential types and
-//! intrusive data structures which cannot currently be modeled in fully safe Rust using only
-//! borrow-checked [references][reference].
+//! pinned value is still valid. [As we'll see later][drop-guarantee], once a value is pinned,
+//! it is necessarily valid at its memory location until the end of its lifespan. This concept
+//! of "pinning" is necessary to implement safe interfaces on top of things like self-referential
+//! types and intrusive data structures which cannot currently be modeled in fully safe Rust using
+//! only borrow-checked [references][reference].
 //!
 //! "Pinning" allows us to put a *value* which exists at some location in memory into a state where
 //! safe code cannot *move* that value to a different location in memory or otherwise invalidate it
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index 863358596c1..a3e520fdeef 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -1498,11 +1498,10 @@ impl File {
             None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
         };
         cfg_if::cfg_if! {
-            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "vxworks", target_os = "nuttx"))] {
+            if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx"))] {
                 // Redox doesn't appear to support `UTIME_OMIT`.
                 // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
                 // the same as for Redox.
-                // `futimens` and `UTIME_OMIT` are a work in progress for vxworks.
                 let _ = times;
                 Err(io::const_error!(
                     io::ErrorKind::Unsupported,
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index afda7c65e10..d8b189413f4 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -222,16 +222,8 @@ impl Thread {
 
     #[cfg(target_os = "vxworks")]
     pub fn set_name(name: &CStr) {
-        // FIXME(libc): adding real STATUS, ERROR type eventually.
-        unsafe extern "C" {
-            fn taskNameSet(task_id: libc::TASK_ID, task_name: *mut libc::c_char) -> libc::c_int;
-        }
-
-        //  VX_TASK_NAME_LEN is 31 in VxWorks 7.
-        const VX_TASK_NAME_LEN: usize = 31;
-
-        let mut name = truncate_cstr::<{ VX_TASK_NAME_LEN }>(name);
-        let res = unsafe { taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) };
+        let mut name = truncate_cstr::<{ libc::VX_TASK_RENAME_LENGTH - 1 }>(name);
+        let res = unsafe { libc::taskNameSet(libc::taskIdSelf(), name.as_mut_ptr()) };
         debug_assert_eq!(res, libc::OK);
     }
 
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 93900a9043e..1c317ce4b86 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -58,7 +58,7 @@ fn rustfmt(
 fn get_rustfmt_version(build: &Builder<'_>) -> Option<(String, BuildStamp)> {
     let stamp_file = BuildStamp::new(&build.out).with_prefix("rustfmt");
 
-    let mut cmd = command(build.initial_rustfmt()?);
+    let mut cmd = command(build.config.initial_rustfmt.as_ref()?);
     cmd.arg("--version");
 
     let output = cmd.allow_failure().run_capture(build);
@@ -243,7 +243,7 @@ pub fn format(build: &Builder<'_>, check: bool, all: bool, paths: &[PathBuf]) {
 
     let override_ = override_builder.build().unwrap(); // `override` is a reserved keyword
 
-    let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| {
+    let rustfmt_path = build.config.initial_rustfmt.clone().unwrap_or_else(|| {
         eprintln!("fmt error: `x fmt` is not supported on this channel");
         crate::exit!(1);
     });
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index f708b6e9fd6..b2dc509ddca 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1102,7 +1102,7 @@ impl Step for Tidy {
         if builder.config.channel == "dev" || builder.config.channel == "nightly" {
             if !builder.config.json_output {
                 builder.info("fmt check");
-                if builder.initial_rustfmt().is_none() {
+                if builder.config.initial_rustfmt.is_none() {
                     let inferred_rustfmt_dir = builder.initial_sysroot.join("bin");
                     eprintln!(
                         "\
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index c8beca25bcc..3b8c3655b8d 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -3,7 +3,7 @@
 //! This module implements parsing `bootstrap.toml` configuration files to tweak
 //! how the build runs.
 
-use std::cell::{Cell, RefCell};
+use std::cell::Cell;
 use std::collections::{BTreeSet, HashMap, HashSet};
 use std::fmt::{self, Display};
 use std::hash::Hash;
@@ -406,11 +406,7 @@ pub struct Config {
     pub initial_rustc: PathBuf,
     pub initial_cargo_clippy: Option<PathBuf>,
     pub initial_sysroot: PathBuf,
-
-    #[cfg(not(test))]
-    initial_rustfmt: RefCell<RustfmtState>,
-    #[cfg(test)]
-    pub initial_rustfmt: RefCell<RustfmtState>,
+    pub initial_rustfmt: Option<PathBuf>,
 
     /// The paths to work with. For example: with `./x check foo bar` we get
     /// `paths=["foo", "bar"]`.
@@ -428,15 +424,6 @@ pub struct Config {
     pub path_modification_cache: Arc<Mutex<HashMap<Vec<&'static str>, PathFreshness>>>,
 }
 
-#[derive(Clone, Debug, Default)]
-pub enum RustfmtState {
-    SystemToolchain(PathBuf),
-    Downloaded(PathBuf),
-    Unavailable,
-    #[default]
-    LazyEvaluated,
-}
-
 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
 pub enum LlvmLibunwind {
     #[default]
@@ -2448,13 +2435,8 @@ impl Config {
             });
         }
 
-        if let Some(r) = rustfmt {
-            *config.initial_rustfmt.borrow_mut() = if r.exists() {
-                RustfmtState::SystemToolchain(r)
-            } else {
-                RustfmtState::Unavailable
-            };
-        }
+        config.initial_rustfmt =
+            if let Some(r) = rustfmt { Some(r) } else { config.maybe_download_rustfmt() };
 
         // Now that we've reached the end of our configuration, infer the
         // default values for all options that we haven't otherwise stored yet.
@@ -2851,25 +2833,6 @@ impl Config {
             .as_deref()
     }
 
-    pub(crate) fn initial_rustfmt(&self) -> Option<PathBuf> {
-        match &mut *self.initial_rustfmt.borrow_mut() {
-            RustfmtState::SystemToolchain(p) | RustfmtState::Downloaded(p) => Some(p.clone()),
-            RustfmtState::Unavailable => None,
-            r @ RustfmtState::LazyEvaluated => {
-                if self.dry_run() {
-                    return Some(PathBuf::new());
-                }
-                let path = self.maybe_download_rustfmt();
-                *r = if let Some(p) = &path {
-                    RustfmtState::Downloaded(p.clone())
-                } else {
-                    RustfmtState::Unavailable
-                };
-                path
-            }
-        }
-    }
-
     /// Runs a function if verbosity is greater than 0
     pub fn verbose(&self, f: impl Fn()) {
         if self.is_verbose() {
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 64298964dad..e0c9877cd55 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -446,7 +446,7 @@ impl Config {
 
     #[cfg(test)]
     pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
-        None
+        Some(PathBuf::new())
     }
 
     /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
@@ -455,6 +455,10 @@ impl Config {
     pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
         use build_helper::stage0_parser::VersionMetadata;
 
+        if self.dry_run() {
+            return Some(PathBuf::new());
+        }
+
         let VersionMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
         let channel = format!("{version}-{date}");
 
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 1e6acad5c0f..9492ffaed75 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -325,7 +325,6 @@ forward! {
     tempdir() -> PathBuf,
     llvm_link_shared() -> bool,
     download_rustc() -> bool,
-    initial_rustfmt() -> Option<PathBuf>,
 }
 
 impl Build {
@@ -614,10 +613,6 @@ impl Build {
             crate::utils::job::setup(self);
         }
 
-        // Download rustfmt early so that it can be used in rust-analyzer configs.
-        trace!("downloading rustfmt early");
-        let _ = &builder::Builder::new(self).initial_rustfmt();
-
         // Handle hard-coded subcommands.
         {
             #[cfg(feature = "tracing")]
diff --git a/tests/ui/drop/dropck-normalize-errors.rs b/tests/ui/drop/dropck-normalize-errors.rs
new file mode 100644
index 00000000000..793122bd33d
--- /dev/null
+++ b/tests/ui/drop/dropck-normalize-errors.rs
@@ -0,0 +1,31 @@
+// Test that we don't ICE when computing the drop types for
+
+trait Decode<'a> {
+    type Decoder;
+}
+
+trait NonImplementedTrait {
+    type Assoc;
+}
+struct NonImplementedStruct;
+
+pub struct ADecoder<'a> {
+    b: <B as Decode<'a>>::Decoder,
+}
+fn make_a_decoder<'a>() -> ADecoder<'a> {
+    //~^ ERROR the trait bound
+    //~| ERROR the trait bound
+    panic!()
+}
+
+struct B;
+impl<'a> Decode<'a> for B {
+    type Decoder = BDecoder;
+    //~^ ERROR the trait bound
+}
+pub struct BDecoder {
+    non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc,
+    //~^ ERROR the trait bound
+}
+
+fn main() {}
diff --git a/tests/ui/drop/dropck-normalize-errors.stderr b/tests/ui/drop/dropck-normalize-errors.stderr
new file mode 100644
index 00000000000..2bb5909c6b2
--- /dev/null
+++ b/tests/ui/drop/dropck-normalize-errors.stderr
@@ -0,0 +1,76 @@
+error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>`
+  --> $DIR/dropck-normalize-errors.rs:15:28
+   |
+LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
+   |                            ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/dropck-normalize-errors.rs:7:1
+   |
+LL | trait NonImplementedTrait {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required because it appears within the type `BDecoder`
+  --> $DIR/dropck-normalize-errors.rs:26:12
+   |
+LL | pub struct BDecoder {
+   |            ^^^^^^^^
+note: required because it appears within the type `ADecoder<'a>`
+  --> $DIR/dropck-normalize-errors.rs:12:12
+   |
+LL | pub struct ADecoder<'a> {
+   |            ^^^^^^^^
+   = note: the return type of a function must have a statically known size
+
+error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder`
+  --> $DIR/dropck-normalize-errors.rs:23:20
+   |
+LL |     type Decoder = BDecoder;
+   |                    ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/dropck-normalize-errors.rs:7:1
+   |
+LL | trait NonImplementedTrait {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required because it appears within the type `BDecoder`
+  --> $DIR/dropck-normalize-errors.rs:26:12
+   |
+LL | pub struct BDecoder {
+   |            ^^^^^^^^
+note: required by a bound in `Decode::Decoder`
+  --> $DIR/dropck-normalize-errors.rs:4:5
+   |
+LL |     type Decoder;
+   |     ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL |     type Decoder: ?Sized;
+   |                 ++++++++
+
+error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
+  --> $DIR/dropck-normalize-errors.rs:27:22
+   |
+LL |     non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc,
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/dropck-normalize-errors.rs:7:1
+   |
+LL | trait NonImplementedTrait {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
+  --> $DIR/dropck-normalize-errors.rs:15:28
+   |
+LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
+   |                            ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/dropck-normalize-errors.rs:7:1
+   |
+LL | trait NonImplementedTrait {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs
index 96a0f2f40bf..82ffa0221b9 100644
--- a/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs
+++ b/tests/ui/generic-associated-types/guide-inference-in-gat-arg-deeper.rs
@@ -1,5 +1,9 @@
-// Fix for <https://github.com/rust-lang/rust/issues/125196>.
 //@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Fix for <https://github.com/rust-lang/rust/issues/125196>.
 
 trait Tr {
     type Gat<T>;
diff --git a/tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs b/tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs
new file mode 100644
index 00000000000..0c25c64224b
--- /dev/null
+++ b/tests/ui/generic-associated-types/no-incomplete-gat-arg-inference.rs
@@ -0,0 +1,33 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Regression test for trait-system-refactor-initiative#202. We have
+// to make sure we don't constrain ambiguous GAT args when normalizing
+// via where bounds or item bounds.
+
+trait Trait {
+    type Assoc<U>;
+}
+
+fn ret<T: Trait, U>(x: U) -> <T as Trait>::Assoc<U> {
+    loop {}
+}
+
+fn where_bound<T: Trait<Assoc<u32> = u32>>() {
+    let inf = Default::default();
+    let x = ret::<T, _>(inf);
+    let _: i32 = inf;
+}
+
+trait ItemBound {
+    type Bound: Trait<Assoc<u32> = u32>;
+}
+fn item_bound<T: ItemBound>() {
+    let inf = Default::default();
+    let x = ret::<T::Bound, _>(inf);
+    let _: i32 = inf;
+}
+
+fn main() {}
diff --git a/tests/ui/lint/implicit_autorefs.fixed b/tests/ui/lint/implicit_autorefs.fixed
index 96a617b20c9..454dfe76372 100644
--- a/tests/ui/lint/implicit_autorefs.fixed
+++ b/tests/ui/lint/implicit_autorefs.fixed
@@ -96,4 +96,10 @@ unsafe fn test_string(ptr: *mut String) {
     //~^ WARN implicit autoref
 }
 
+unsafe fn slice_ptr_len_because_of_msrv<T>(slice: *const [T]) {
+    let _ = (&(&(*slice))[..]).len();
+    //~^ WARN implicit autoref
+    //~^^ WARN implicit autoref
+}
+
 fn main() {}
diff --git a/tests/ui/lint/implicit_autorefs.rs b/tests/ui/lint/implicit_autorefs.rs
index 61dd0ac50ce..507d6536828 100644
--- a/tests/ui/lint/implicit_autorefs.rs
+++ b/tests/ui/lint/implicit_autorefs.rs
@@ -96,4 +96,10 @@ unsafe fn test_string(ptr: *mut String) {
     //~^ WARN implicit autoref
 }
 
+unsafe fn slice_ptr_len_because_of_msrv<T>(slice: *const [T]) {
+    let _ = (*slice)[..].len();
+    //~^ WARN implicit autoref
+    //~^^ WARN implicit autoref
+}
+
 fn main() {}
diff --git a/tests/ui/lint/implicit_autorefs.stderr b/tests/ui/lint/implicit_autorefs.stderr
index 6dd1ac65ada..80ba8ae2fd2 100644
--- a/tests/ui/lint/implicit_autorefs.stderr
+++ b/tests/ui/lint/implicit_autorefs.stderr
@@ -2,9 +2,16 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:10:13
    |
 LL |     let _ = (*ptr)[..16];
-   |             ^^^^^^^^^^^^
+   |             ^^---^^^^^^^
+   |               |
+   |               this raw pointer has type `*const [u8]`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[u8]`
+  --> $DIR/implicit_autorefs.rs:10:13
+   |
+LL |     let _ = (*ptr)[..16];
+   |             ^^^^^^
    = note: `#[warn(dangerous_implicit_autorefs)]` on by default
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
@@ -15,9 +22,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:19:13
    |
 LL |     let l = (*ptr).field.len();
-   |             ^^^^^^^^^^^^^^^^^^
+   |             ^^---^^^^^^^^^^^^^
+   |               |
+   |               this raw pointer has type `*const Test`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[u8]`
+  --> $DIR/implicit_autorefs.rs:19:13
+   |
+LL |     let l = (*ptr).field.len();
+   |             ^^^^^^^^^^^^
+note: method calls to `len` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let l = (&(*ptr).field).len();
@@ -27,9 +43,16 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:22:16
    |
 LL |     &raw const (*ptr).field[..l - 1]
-   |                ^^^^^^^^^^^^^^^^^^^^^
+   |                ^^---^^^^^^^^^^^^^^^^
+   |                  |
+   |                  this raw pointer has type `*const Test`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[u8]`
+  --> $DIR/implicit_autorefs.rs:22:16
+   |
+LL |     &raw const (*ptr).field[..l - 1]
+   |                ^^^^^^^^^^^^
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     &raw const (&(*ptr).field)[..l - 1]
@@ -39,9 +62,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:27:9
    |
 LL |     _ = (*a)[0].len();
-   |         ^^^^^^^^^^^^^
+   |         ^^-^^^^^^^^^^
+   |           |
+   |           this raw pointer has type `*mut [String]`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&String`
+  --> $DIR/implicit_autorefs.rs:27:9
+   |
+LL |     _ = (*a)[0].len();
+   |         ^^^^^^^
+note: method calls to `len` require a reference
+  --> $SRC_DIR/alloc/src/string.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     _ = (&(*a)[0]).len();
@@ -51,9 +83,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:30:9
    |
 LL |     _ = (*a)[..1][0].len();
-   |         ^^^^^^^^^^^^^^^^^^
+   |         ^^-^^^^^^^^^^^^^^^
+   |           |
+   |           this raw pointer has type `*mut [String]`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&String`
+  --> $DIR/implicit_autorefs.rs:30:9
+   |
+LL |     _ = (*a)[..1][0].len();
+   |         ^^^^^^^^^^^^
+note: method calls to `len` require a reference
+  --> $SRC_DIR/alloc/src/string.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     _ = (&(*a)[..1][0]).len();
@@ -63,9 +104,16 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:30:9
    |
 LL |     _ = (*a)[..1][0].len();
-   |         ^^^^^^^^^
+   |         ^^-^^^^^^
+   |           |
+   |           this raw pointer has type `*mut [String]`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[String]`
+  --> $DIR/implicit_autorefs.rs:30:9
+   |
+LL |     _ = (*a)[..1][0].len();
+   |         ^^^^
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     _ = (&(*a))[..1][0].len();
@@ -75,9 +123,12 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:36:13
    |
 LL |     let _ = (*ptr).field;
-   |             ^^^^^^^^^^^^
+   |             ^^---^^^^^^^
+   |               |
+   |               this raw pointer has type `*const ManuallyDrop<Test>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+   = note: references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).field;
@@ -87,9 +138,12 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:38:24
    |
 LL |     let _ = &raw const (*ptr).field;
-   |                        ^^^^^^^^^^^^
+   |                        ^^---^^^^^^^
+   |                          |
+   |                          this raw pointer has type `*const ManuallyDrop<Test>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+   = note: references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = &raw const (&(*ptr)).field;
@@ -99,9 +153,12 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:43:13
    |
 LL |     let _ = (*ptr).field;
-   |             ^^^^^^^^^^^^
+   |             ^^---^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut ManuallyDrop<Test>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+   = note: references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).field;
@@ -111,9 +168,12 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:48:13
    |
 LL |     let _ = (*ptr).field;
-   |             ^^^^^^^^^^^^
+   |             ^^---^^^^^^^
+   |               |
+   |               this raw pointer has type `*const ManuallyDrop<ManuallyDrop<Test>>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+   = note: references are created through calls to explicit `Deref(Mut)::deref(_mut)` implementations
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).field;
@@ -123,9 +183,16 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:62:26
    |
 LL |     let _p: *const i32 = &raw const **w;
-   |                          ^^^^^^^^^^^^^^
+   |                          ^^^^^^^^^^^^^-
+   |                                       |
+   |                                       this raw pointer has type `*const W<i32>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&W<i32>`
+  --> $DIR/implicit_autorefs.rs:62:38
+   |
+LL |     let _p: *const i32 = &raw const **w;
+   |                                      ^^
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _p: *const i32 = &raw const *(&**w);
@@ -135,9 +202,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:72:14
    |
 LL |     unsafe { (*ptr).field.len() }
-   |              ^^^^^^^^^^^^^^^^^^
+   |              ^^---^^^^^^^^^^^^^
+   |                |
+   |                this raw pointer has type `*const Test2`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[u8]`
+  --> $DIR/implicit_autorefs.rs:72:14
+   |
+LL |     unsafe { (*ptr).field.len() }
+   |              ^^^^^^^^^^^^
+note: method calls to `len` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     unsafe { (&(*ptr).field).len() }
@@ -147,9 +223,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:82:13
    |
 LL |     let _ = (*ptr).get(0);
-   |             ^^^^^^^^^^^^^
+   |             ^^---^^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut Vec<u8>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[u8]`
+  --> $DIR/implicit_autorefs.rs:82:13
+   |
+LL |     let _ = (*ptr).get(0);
+   |             ^^^^^^
+note: method calls to `get` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).get(0);
@@ -159,9 +244,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:84:13
    |
 LL |     let _ = (*ptr).get_unchecked(0);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^---^^^^^^^^^^^^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut Vec<u8>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[u8]`
+  --> $DIR/implicit_autorefs.rs:84:13
+   |
+LL |     let _ = (*ptr).get_unchecked(0);
+   |             ^^^^^^
+note: method calls to `get_unchecked` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).get_unchecked(0);
@@ -171,9 +265,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:86:13
    |
 LL |     let _ = (*ptr).get_mut(0);
-   |             ^^^^^^^^^^^^^^^^^
+   |             ^^---^^^^^^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut Vec<u8>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&mut [u8]`
+  --> $DIR/implicit_autorefs.rs:86:13
+   |
+LL |     let _ = (*ptr).get_mut(0);
+   |             ^^^^^^
+note: method calls to `get_mut` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&mut (*ptr)).get_mut(0);
@@ -183,9 +286,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:88:13
    |
 LL |     let _ = (*ptr).get_unchecked_mut(0);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^---^^^^^^^^^^^^^^^^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut Vec<u8>`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&mut [u8]`
+  --> $DIR/implicit_autorefs.rs:88:13
+   |
+LL |     let _ = (*ptr).get_unchecked_mut(0);
+   |             ^^^^^^
+note: method calls to `get_unchecked_mut` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&mut (*ptr)).get_unchecked_mut(0);
@@ -195,9 +307,18 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:93:13
    |
 LL |     let _ = (*ptr).len();
-   |             ^^^^^^^^^^^^
+   |             ^^---^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut String`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&String`
+  --> $DIR/implicit_autorefs.rs:93:13
+   |
+LL |     let _ = (*ptr).len();
+   |             ^^^^^^
+note: method calls to `len` require a reference
+  --> $SRC_DIR/alloc/src/string.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).len();
@@ -207,13 +328,62 @@ warning: implicit autoref creates a reference to the dereference of a raw pointe
   --> $DIR/implicit_autorefs.rs:95:13
    |
 LL |     let _ = (*ptr).is_empty();
-   |             ^^^^^^^^^^^^^^^^^
+   |             ^^---^^^^^^^^^^^^
+   |               |
+   |               this raw pointer has type `*mut String`
    |
    = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&String`
+  --> $DIR/implicit_autorefs.rs:95:13
+   |
+LL |     let _ = (*ptr).is_empty();
+   |             ^^^^^^
+note: method calls to `is_empty` require a reference
+  --> $SRC_DIR/alloc/src/string.rs:LL:COL
 help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
    |
 LL |     let _ = (&(*ptr)).is_empty();
    |             ++      +
 
-warning: 18 warnings emitted
+warning: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:100:13
+   |
+LL |     let _ = (*slice)[..].len();
+   |             ^^-----^^^^^^^^^^^
+   |               |
+   |               this raw pointer has type `*const [T]`
+   |
+   = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[T]`
+  --> $DIR/implicit_autorefs.rs:100:13
+   |
+LL |     let _ = (*slice)[..].len();
+   |             ^^^^^^^^^^^^
+note: method calls to `len` require a reference
+  --> $SRC_DIR/core/src/slice/mod.rs:LL:COL
+help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
+   |
+LL |     let _ = (&(*slice)[..]).len();
+   |             ++            +
+
+warning: implicit autoref creates a reference to the dereference of a raw pointer
+  --> $DIR/implicit_autorefs.rs:100:13
+   |
+LL |     let _ = (*slice)[..].len();
+   |             ^^-----^^^^^
+   |               |
+   |               this raw pointer has type `*const [T]`
+   |
+   = note: creating a reference requires the pointer target to be valid and imposes aliasing requirements
+note: autoref is being applied to this expression, resulting in: `&[T]`
+  --> $DIR/implicit_autorefs.rs:100:13
+   |
+LL |     let _ = (*slice)[..].len();
+   |             ^^^^^^^^
+help: try using a raw pointer method instead; or if this reference is intentional, make it explicit
+   |
+LL |     let _ = (&(*slice))[..].len();
+   |             ++        +
+
+warning: 20 warnings emitted