diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 1e7989988955..73cf15ff94b5 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -10,9 +10,11 @@ use rustc_infer::traits::util::elaborate;
use rustc_infer::traits::Reveal;
use rustc_middle::traits::solve::inspect::CandidateKind;
use rustc_middle::traits::solve::{CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult};
-use rustc_middle::ty::fast_reject::TreatProjections;
-use rustc_middle::ty::TypeFoldable;
+use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
+use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{fast_reject, TypeFoldable};
+use rustc_span::ErrorGuaranteed;
use std::fmt::Debug;
pub(super) mod structural_traits;
@@ -109,10 +111,10 @@ pub(super) trait GoalKind<'tcx>:
fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId;
- // Try equating an assumption predicate against a goal's predicate. If it
- // holds, then execute the `then` callback, which should do any additional
- // work, then produce a response (typically by executing
- // [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
+ /// Try equating an assumption predicate against a goal's predicate. If it
+ /// holds, then execute the `then` callback, which should do any additional
+ /// work, then produce a response (typically by executing
+ /// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
fn probe_and_match_goal_against_assumption(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
@@ -120,9 +122,9 @@ pub(super) trait GoalKind<'tcx>:
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
) -> QueryResult<'tcx>;
- // Consider a clause, which consists of a "assumption" and some "requirements",
- // to satisfy a goal. If the requirements hold, then attempt to satisfy our
- // goal by equating it with the assumption.
+ /// Consider a clause, which consists of a "assumption" and some "requirements",
+ /// to satisfy a goal. If the requirements hold, then attempt to satisfy our
+ /// goal by equating it with the assumption.
fn consider_implied_clause(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
@@ -149,9 +151,9 @@ pub(super) trait GoalKind<'tcx>:
})
}
- // Consider a clause specifically for a `dyn Trait` self type. This requires
- // additionally checking all of the supertraits and object bounds to hold,
- // since they're not implied by the well-formedness of the object type.
+ /// Consider a clause specifically for a `dyn Trait` self type. This requires
+ /// additionally checking all of the supertraits and object bounds to hold,
+ /// since they're not implied by the well-formedness of the object type.
fn consider_object_bound_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
@@ -182,96 +184,106 @@ pub(super) trait GoalKind<'tcx>:
impl_def_id: DefId,
) -> QueryResult<'tcx>;
- // A type implements an `auto trait` if its components do as well. These components
- // are given by built-in rules from [`instantiate_constituent_tys_for_auto_trait`].
+ /// If the predicate contained an error, we want to avoid emitting unnecessary trait errors but
+ /// still want to emit errors for other trait goals. We have some special handling for this case.
+ ///
+ /// Trait goals always hold while projection goals never do. This is a bit arbitrary but prevents
+ /// incorrect normalization while hiding any trait errors.
+ fn consider_error_guaranteed_candidate(
+ ecx: &mut EvalCtxt<'_, 'tcx>,
+ guar: ErrorGuaranteed,
+ ) -> QueryResult<'tcx>;
+
+ /// A type implements an `auto trait` if its components do as well. These components
+ /// are given by built-in rules from [`instantiate_constituent_tys_for_auto_trait`].
fn consider_auto_trait_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A trait alias holds if the RHS traits and `where` clauses hold.
+ /// A trait alias holds if the RHS traits and `where` clauses hold.
fn consider_trait_alias_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A type is `Copy` or `Clone` if its components are `Sized`. These components
- // are given by built-in rules from [`instantiate_constituent_tys_for_sized_trait`].
+ /// A type is `Copy` or `Clone` if its components are `Sized`. These components
+ /// are given by built-in rules from [`instantiate_constituent_tys_for_sized_trait`].
fn consider_builtin_sized_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. These
- // components are given by built-in rules from [`instantiate_constituent_tys_for_copy_clone_trait`].
+ /// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`. These
+ /// components are given by built-in rules from [`instantiate_constituent_tys_for_copy_clone_trait`].
fn consider_builtin_copy_clone_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A type is `PointerLike` if we can compute its layout, and that layout
- // matches the layout of `usize`.
+ /// A type is `PointerLike` if we can compute its layout, and that layout
+ /// matches the layout of `usize`.
fn consider_builtin_pointer_like_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A type is a `FnPtr` if it is of `FnPtr` type.
+ /// A type is a `FnPtr` if it is of `FnPtr` type.
fn consider_builtin_fn_ptr_trait_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn`
- // family of traits where `A` is given by the signature of the type.
+ /// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn`
+ /// family of traits where `A` is given by the signature of the type.
fn consider_builtin_fn_trait_candidates(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
kind: ty::ClosureKind,
) -> QueryResult<'tcx>;
- // `Tuple` is implemented if the `Self` type is a tuple.
+ /// `Tuple` is implemented if the `Self` type is a tuple.
fn consider_builtin_tuple_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // `Pointee` is always implemented.
- //
- // See the projection implementation for the `Metadata` types for all of
- // the built-in types. For structs, the metadata type is given by the struct
- // tail.
+ /// `Pointee` is always implemented.
+ ///
+ /// See the projection implementation for the `Metadata` types for all of
+ /// the built-in types. For structs, the metadata type is given by the struct
+ /// tail.
fn consider_builtin_pointee_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
- // A generator (that comes from an `async` desugaring) is known to implement
- // `Future