Skip to main content

rustc_next_trait_solver/solve/
trait_goals.rs

1//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
2
3use rustc_type_ir::data_structures::IndexSet;
4use rustc_type_ir::fast_reject::DeepRejectCtxt;
5use rustc_type_ir::inherent::*;
6use rustc_type_ir::lang_items::SolverTraitLangItem;
7use rustc_type_ir::solve::{
8    AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, MaybeInfo,
9    NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunNonErased,
10    RerunReason, RerunResultExt, SizedTraitKind,
11};
12use rustc_type_ir::{
13    self as ty, FieldInfo, Interner, MayBeErased, Movability, PredicatePolarity, Region,
14    TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _,
15    elaborate,
16};
17use tracing::{debug, instrument, trace, warn};
18
19use crate::delegate::SolverDelegate;
20use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
21use crate::solve::assembly::{
22    self, AllowInferenceConstraints, AssembleCandidatesFrom, Candidate, FailedCandidateInfo,
23};
24use crate::solve::inspect::ProbeKind;
25use crate::solve::{
26    BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
27    MergeCandidateInfo, NoSolution, ParamEnvSource, StalledOnCoroutines,
28    has_only_region_constraints,
29};
30
31impl<D, I> assembly::GoalKind<D> for TraitPredicate<I>
32where
33    D: SolverDelegate<Interner = I>,
34    I: Interner,
35{
36    fn self_ty(self) -> I::Ty {
37        self.self_ty()
38    }
39
40    fn trait_ref(self, _: I) -> ty::TraitRef<I> {
41        self.trait_ref
42    }
43
44    fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
45        self.with_replaced_self_ty(cx, self_ty)
46    }
47
48    fn trait_def_id(self, _: I) -> I::TraitId {
49        self.def_id()
50    }
51
52    fn consider_additional_alias_assumptions(
53        _ecx: &mut EvalCtxt<'_, D>,
54        _goal: Goal<I, Self>,
55        _alias_ty: ty::AliasTy<I>,
56    ) -> Vec<Candidate<I>> {
57        ::alloc::vec::Vec::new()vec![]
58    }
59
60    fn consider_impl_candidate(
61        ecx: &mut EvalCtxt<'_, D>,
62        goal: Goal<I, TraitPredicate<I>>,
63        impl_def_id: I::ImplId,
64        then: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResultOrRerunNonErased<I>,
65    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
66        let cx = ecx.cx();
67
68        let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
69        if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
70            .args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args)
71        {
72            return Err(NoSolution.into());
73        }
74
75        // An upper bound of the certainty of this goal, used to lower the certainty
76        // of reservation impl to ambiguous during coherence.
77        let impl_polarity = cx.impl_polarity(impl_def_id);
78        let maximal_certainty = match (impl_polarity, goal.predicate.polarity) {
79            // In coherence mode, this is ambiguous. But outside of coherence, it's not a real impl.
80            (ty::ImplPolarity::Reservation, _) => {
81                if ecx.typing_mode().is_coherence() {
82                    Certainty::AMBIGUOUS
83                } else {
84                    return Err(NoSolution.into());
85                }
86            }
87
88            // Impl matches polarity
89            (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive)
90            | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => Certainty::Yes,
91
92            // Impl doesn't match polarity
93            (ty::ImplPolarity::Positive, ty::PredicatePolarity::Negative)
94            | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Positive) => {
95                return Err(NoSolution.into());
96            }
97        };
98
99        ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
100            let impl_args = ecx.fresh_args_for_item(impl_def_id.into());
101            ecx.record_impl_args(impl_args);
102            let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip();
103
104            ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
105            let where_clause_bounds = cx
106                .predicates_of(impl_def_id.into())
107                .iter_instantiated(cx, impl_args)
108                .map(Unnormalized::skip_norm_wip)
109                .map(|pred| goal.with(cx, pred));
110            ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds)?;
111
112            // We currently elaborate all supertrait outlives obligations from impls.
113            // This can be removed when we actually do coinduction correctly, and prove
114            // all supertrait obligations unconditionally.
115            ecx.add_goals(
116                GoalSource::Misc,
117                cx.impl_super_outlives(impl_def_id)
118                    .iter_instantiated(cx, impl_args)
119                    .map(Unnormalized::skip_norm_wip)
120                    .map(|pred| goal.with(cx, pred)),
121            )?;
122
123            then(ecx, maximal_certainty)
124        })
125    }
126
127    fn consider_error_guaranteed_candidate(
128        ecx: &mut EvalCtxt<'_, D>,
129        _goal: Goal<I, Self>,
130        _guar: I::ErrorGuaranteed,
131    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
132        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
133            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
134    }
135
136    fn fast_reject_assumption(
137        ecx: &mut EvalCtxt<'_, D>,
138        goal: Goal<I, Self>,
139        assumption: I::Clause,
140    ) -> Result<(), NoSolution> {
141        fn trait_def_id_matches<I: Interner>(
142            cx: I,
143            clause_def_id: I::TraitId,
144            goal_def_id: I::TraitId,
145            polarity: PredicatePolarity,
146        ) -> bool {
147            clause_def_id == goal_def_id
148            // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
149            // check for a `MetaSized` supertrait being matched against a `Sized` assumption.
150            //
151            // `PointeeSized` bounds are syntactic sugar for a lack of bounds so don't need this.
152                || (polarity == PredicatePolarity::Positive
153                    && cx.is_trait_lang_item(clause_def_id, SolverTraitLangItem::Sized)
154                    && cx.is_trait_lang_item(goal_def_id, SolverTraitLangItem::MetaSized))
155        }
156
157        if let Some(trait_clause) = assumption.as_trait_clause()
158            && trait_clause.polarity() == goal.predicate.polarity
159            && trait_def_id_matches(
160                ecx.cx(),
161                trait_clause.def_id(),
162                goal.predicate.def_id(),
163                goal.predicate.polarity,
164            )
165            && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
166                goal.predicate.trait_ref.args,
167                trait_clause.skip_binder().trait_ref.args,
168            )
169        {
170            return Ok(());
171        } else {
172            Err(NoSolution)
173        }
174    }
175
176    fn match_assumption(
177        ecx: &mut EvalCtxt<'_, D>,
178        goal: Goal<I, Self>,
179        assumption: I::Clause,
180        then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
181    ) -> QueryResultOrRerunNonErased<I> {
182        let trait_clause = assumption.as_trait_clause().unwrap();
183
184        // PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
185        // check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
186        // are syntactic sugar for a lack of bounds so don't need this.
187        // We don't need to check polarity, `fast_reject_assumption` already rejected non-`Positive`
188        // polarity `Sized` assumptions as matching non-`Positive` `MetaSized` goals.
189        if ecx.cx().is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::MetaSized)
190            && ecx.cx().is_trait_lang_item(trait_clause.def_id(), SolverTraitLangItem::Sized)
191        {
192            let meta_sized_clause =
193                trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
194            return Self::match_assumption(ecx, goal, meta_sized_clause, then);
195        }
196
197        let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
198        ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
199
200        then(ecx)
201    }
202
203    fn consider_auto_trait_candidate(
204        ecx: &mut EvalCtxt<'_, D>,
205        goal: Goal<I, Self>,
206    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
207        let cx = ecx.cx();
208        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
209            return Err(NoSolution.into());
210        }
211
212        if let Some(result) = ecx.disqualify_auto_trait_candidate_due_to_possible_impl(goal) {
213            return result;
214        }
215
216        // Only consider auto impls of unsafe traits when there are no unsafe
217        // fields.
218        if cx.trait_is_unsafe(goal.predicate.def_id())
219            && goal.predicate.self_ty().has_unsafe_fields()
220        {
221            return Err(NoSolution.into());
222        }
223
224        // We leak the implemented auto traits of opaques outside of their defining scope.
225        // This depends on `typeck` of the defining scope of that opaque, which may result in
226        // fatal query cycles.
227        //
228        // We only get to this point if we're outside of the defining scope as we'd otherwise
229        // be able to normalize the opaque type. We may also cycle in case `typeck` of a defining
230        // scope relies on the current context, e.g. either because it also leaks auto trait
231        // bounds of opaques defined in the current context or by evaluating the current item.
232        //
233        // To avoid this we don't try to leak auto trait bounds if they can also be proven via
234        // item bounds of the opaque. These bounds are always applicable as auto traits must not
235        // have any generic parameters. They would also get preferred over the impl candidate
236        // when merging candidates anyways.
237        //
238        // See tests/ui/impl-trait/auto-trait-leakage/avoid-query-cycle-via-item-bound.rs.
239        if let ty::Alias(is_rigid, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) =
240            goal.predicate.self_ty().kind()
241        {
242            if true {
    if !(is_rigid == ty::IsRigid::Yes) {
        ::core::panicking::panic("assertion failed: is_rigid == ty::IsRigid::Yes")
    };
};debug_assert!(is_rigid == ty::IsRigid::Yes);
243            if ecx.opaque_accesses.might_rerun() {
244                ecx.opaque_accesses.rerun_always(RerunReason::AutoTraitLeakage)?;
245                return Err(NoSolution.into());
246            }
247
248            for item_bound in cx.item_self_bounds(def_id.into()).skip_binder() {
249                if item_bound
250                    .as_trait_clause()
251                    .is_some_and(|b| b.def_id() == goal.predicate.def_id())
252                {
253                    return Err(NoSolution.into());
254                }
255            }
256        }
257
258        // We need to make sure to stall any coroutines we are inferring to avoid query cycles.
259        if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
260            return cand;
261        }
262
263        ecx.probe_and_evaluate_goal_for_constituent_tys(
264            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
265            goal,
266            structural_traits::instantiate_constituent_tys_for_auto_trait,
267        )
268    }
269
270    fn consider_trait_alias_candidate(
271        ecx: &mut EvalCtxt<'_, D>,
272        goal: Goal<I, Self>,
273    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
274        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
275            return Err(NoSolution.into());
276        }
277
278        let cx = ecx.cx();
279
280        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
281            let nested_obligations = cx
282                .predicates_of(goal.predicate.def_id().into())
283                .iter_instantiated(cx, goal.predicate.trait_ref.args)
284                .map(Unnormalized::skip_norm_wip)
285                .map(|p| goal.with(cx, p));
286            // While you could think of trait aliases to have a single builtin impl
287            // which uses its implied trait bounds as where-clauses, using
288            // `GoalSource::ImplWhereClause` here would be incorrect, as we also
289            // impl them, which means we're "stepping out of the impl constructor"
290            // again. To handle this, we treat these cycles as ambiguous for now.
291            ecx.add_goals(GoalSource::Misc, nested_obligations)?;
292            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
293        })
294    }
295
296    fn consider_builtin_sizedness_candidates(
297        ecx: &mut EvalCtxt<'_, D>,
298        goal: Goal<I, Self>,
299        sizedness: SizedTraitKind,
300    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
301        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
302            return Err(NoSolution.into());
303        }
304
305        ecx.probe_and_evaluate_goal_for_constituent_tys(
306            CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial),
307            goal,
308            |ecx, ty| {
309                structural_traits::instantiate_constituent_tys_for_sizedness_trait(
310                    ecx, sizedness, ty,
311                )
312            },
313        )
314    }
315
316    fn consider_builtin_copy_clone_candidate(
317        ecx: &mut EvalCtxt<'_, D>,
318        goal: Goal<I, Self>,
319    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
320        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
321            return Err(NoSolution.into());
322        }
323
324        // We need to make sure to stall any coroutines we are inferring to avoid query cycles.
325        if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
326            return cand;
327        }
328
329        ecx.probe_and_evaluate_goal_for_constituent_tys(
330            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
331            goal,
332            structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
333        )
334    }
335
336    fn consider_builtin_fn_ptr_trait_candidate(
337        ecx: &mut EvalCtxt<'_, D>,
338        goal: Goal<I, Self>,
339    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
340        let self_ty = goal.predicate.self_ty();
341        match goal.predicate.polarity {
342            // impl FnPtr for FnPtr {}
343            ty::PredicatePolarity::Positive => {
344                if self_ty.is_fn_ptr() {
345                    ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
346                        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
347                    })
348                } else {
349                    Err(NoSolution.into())
350                }
351            }
352            //  impl !FnPtr for T where T != FnPtr && T is rigid {}
353            ty::PredicatePolarity::Negative => {
354                // If a type is rigid and not a fn ptr, then we know for certain
355                // that it does *not* implement `FnPtr`.
356                if !self_ty.is_fn_ptr() && self_ty.is_known_rigid() {
357                    ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
358                        ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
359                    })
360                } else {
361                    Err(NoSolution.into())
362                }
363            }
364        }
365    }
366
367    fn consider_builtin_fn_trait_candidates(
368        ecx: &mut EvalCtxt<'_, D>,
369        goal: Goal<I, Self>,
370        goal_kind: ty::ClosureKind,
371    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
372        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
373            return Err(NoSolution.into());
374        }
375
376        let cx = ecx.cx();
377        let Some(tupled_inputs_and_output) =
378            structural_traits::extract_tupled_inputs_and_output_from_callable(
379                cx,
380                goal.predicate.self_ty(),
381                goal_kind,
382            )?
383        else {
384            return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
385        };
386        let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
387
388        // A built-in `Fn` impl only holds if the output is sized.
389        // (FIXME: technically we only need to check this if the type is a fn ptr...)
390        let output_is_sized_pred =
391            ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
392
393        let pred =
394            ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
395                .upcast(cx);
396        Self::probe_and_consider_implied_clause(
397            ecx,
398            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
399            goal,
400            pred,
401            [(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))],
402        )
403    }
404
405    fn consider_builtin_async_fn_trait_candidates(
406        ecx: &mut EvalCtxt<'_, D>,
407        goal: Goal<I, Self>,
408        goal_kind: ty::ClosureKind,
409    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
410        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
411            return Err(NoSolution.into());
412        }
413
414        let cx = ecx.cx();
415        let (tupled_inputs_and_output_and_coroutine, nested_preds) =
416            structural_traits::extract_tupled_inputs_and_output_from_async_callable(
417                cx,
418                goal.predicate.self_ty(),
419                goal_kind,
420                // This region doesn't matter because we're throwing away the coroutine type
421                Region::new_static(cx),
422            )?;
423        let AsyncCallableRelevantTypes {
424            tupled_inputs_ty,
425            output_coroutine_ty,
426            coroutine_return_ty: _,
427        } = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
428
429        // A built-in `AsyncFn` impl only holds if the output is sized.
430        // (FIXME: technically we only need to check this if the type is a fn ptr...)
431        let output_is_sized_pred = ty::TraitRef::new(
432            cx,
433            cx.require_trait_lang_item(SolverTraitLangItem::Sized),
434            [output_coroutine_ty],
435        );
436
437        let pred = ty::TraitRef::new(
438            cx,
439            goal.predicate.def_id(),
440            [goal.predicate.self_ty(), tupled_inputs_ty],
441        )
442        .upcast(cx);
443        Self::probe_and_consider_implied_clause(
444            ecx,
445            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
446            goal,
447            pred,
448            [goal.with(cx, output_is_sized_pred)]
449                .into_iter()
450                .chain(nested_preds.into_iter().map(|pred| goal.with(cx, pred)))
451                .map(|goal| (GoalSource::ImplWhereBound, goal)),
452        )
453    }
454
455    fn consider_builtin_async_fn_kind_helper_candidate(
456        ecx: &mut EvalCtxt<'_, D>,
457        goal: Goal<I, Self>,
458    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
459        let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else {
460            ::core::panicking::panic("explicit panic");panic!();
461        };
462
463        let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else {
464            // We don't need to worry about the self type being an infer var.
465            return Err(NoSolution.into());
466        };
467        let goal_kind = goal_kind_ty.expect_ty().to_opt_closure_kind().unwrap();
468        if closure_kind.extends(goal_kind) {
469            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
470                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
471        } else {
472            Err(NoSolution.into())
473        }
474    }
475
476    /// ```rust, ignore (not valid rust syntax)
477    /// impl Tuple for () {}
478    /// impl Tuple for (T1,) {}
479    /// impl Tuple for (T1, T2) {}
480    /// impl Tuple for (T1, .., Tn) {}
481    /// ```
482    fn consider_builtin_tuple_candidate(
483        ecx: &mut EvalCtxt<'_, D>,
484        goal: Goal<I, Self>,
485    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
486        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
487            return Err(NoSolution.into());
488        }
489
490        if let ty::Tuple(..) = goal.predicate.self_ty().kind() {
491            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
492                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
493        } else {
494            Err(NoSolution.into())
495        }
496    }
497
498    fn consider_builtin_pointee_candidate(
499        ecx: &mut EvalCtxt<'_, D>,
500        goal: Goal<I, Self>,
501    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
502        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
503            return Err(NoSolution.into());
504        }
505
506        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
507            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
508    }
509
510    fn consider_builtin_future_candidate(
511        ecx: &mut EvalCtxt<'_, D>,
512        goal: Goal<I, Self>,
513    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
514        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
515            return Err(NoSolution.into());
516        }
517
518        let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
519            return Err(NoSolution.into());
520        };
521
522        // Coroutines are not futures unless they come from `async` desugaring
523        let cx = ecx.cx();
524        if !cx.coroutine_is_async(def_id) {
525            return Err(NoSolution.into());
526        }
527
528        // Async coroutine unconditionally implement `Future`
529        // Technically, we need to check that the future output type is Sized,
530        // but that's already proven by the coroutine being WF.
531        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
532            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
533    }
534
535    fn consider_builtin_iterator_candidate(
536        ecx: &mut EvalCtxt<'_, D>,
537        goal: Goal<I, Self>,
538    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
539        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
540            return Err(NoSolution.into());
541        }
542
543        let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
544            return Err(NoSolution.into());
545        };
546
547        // Coroutines are not iterators unless they come from `gen` desugaring
548        let cx = ecx.cx();
549        if !cx.coroutine_is_gen(def_id) {
550            return Err(NoSolution.into());
551        }
552
553        // Gen coroutines unconditionally implement `Iterator`
554        // Technically, we need to check that the iterator output type is Sized,
555        // but that's already proven by the coroutines being WF.
556        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
557            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
558    }
559
560    fn consider_builtin_fused_iterator_candidate(
561        ecx: &mut EvalCtxt<'_, D>,
562        goal: Goal<I, Self>,
563    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
564        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
565            return Err(NoSolution.into());
566        }
567
568        let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
569            return Err(NoSolution.into());
570        };
571
572        // Coroutines are not iterators unless they come from `gen` desugaring
573        let cx = ecx.cx();
574        if !cx.coroutine_is_gen(def_id) {
575            return Err(NoSolution.into());
576        }
577
578        // Gen coroutines unconditionally implement `FusedIterator`.
579        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
580            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
581    }
582
583    fn consider_builtin_async_iterator_candidate(
584        ecx: &mut EvalCtxt<'_, D>,
585        goal: Goal<I, Self>,
586    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
587        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
588            return Err(NoSolution.into());
589        }
590
591        let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
592            return Err(NoSolution.into());
593        };
594
595        // Coroutines are not iterators unless they come from `gen` desugaring
596        let cx = ecx.cx();
597        if !cx.coroutine_is_async_gen(def_id) {
598            return Err(NoSolution.into());
599        }
600
601        // Gen coroutines unconditionally implement `Iterator`
602        // Technically, we need to check that the iterator output type is Sized,
603        // but that's already proven by the coroutines being WF.
604        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
605            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
606    }
607
608    fn consider_builtin_coroutine_candidate(
609        ecx: &mut EvalCtxt<'_, D>,
610        goal: Goal<I, Self>,
611    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
612        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
613            return Err(NoSolution.into());
614        }
615
616        let self_ty = goal.predicate.self_ty();
617        let ty::Coroutine(def_id, args) = self_ty.kind() else {
618            return Err(NoSolution.into());
619        };
620
621        // `async`-desugared coroutines do not implement the coroutine trait
622        let cx = ecx.cx();
623        if !cx.is_general_coroutine(def_id) {
624            return Err(NoSolution.into());
625        }
626
627        let coroutine = args.as_coroutine();
628        Self::probe_and_consider_implied_clause(
629            ecx,
630            CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
631            goal,
632            ty::TraitRef::new(cx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()])
633                .upcast(cx),
634            // Technically, we need to check that the coroutine types are Sized,
635            // but that's already proven by the coroutine being WF.
636            [],
637        )
638    }
639
640    fn consider_builtin_discriminant_kind_candidate(
641        ecx: &mut EvalCtxt<'_, D>,
642        goal: Goal<I, Self>,
643    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
644        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
645            return Err(NoSolution.into());
646        }
647
648        // `DiscriminantKind` is automatically implemented for every type.
649        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
650            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
651    }
652
653    fn consider_builtin_destruct_candidate(
654        ecx: &mut EvalCtxt<'_, D>,
655        goal: Goal<I, Self>,
656    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
657        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
658            return Err(NoSolution.into());
659        }
660
661        // `Destruct` is automatically implemented for every type in
662        // non-const environments.
663        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
664            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
665    }
666
667    fn consider_builtin_transmute_candidate(
668        ecx: &mut EvalCtxt<'_, D>,
669        goal: Goal<I, Self>,
670    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
671        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
672            return Err(NoSolution.into());
673        }
674
675        // `rustc_transmute` does not have support for type or const params
676        if goal.predicate.has_non_region_placeholders() {
677            return Err(NoSolution.into());
678        }
679
680        // Match the old solver by treating unresolved inference variables as
681        // ambiguous until `rustc_transmute` can compute their layout.
682        if goal.has_non_region_infer() {
683            return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
684        }
685
686        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(
687            |ecx| -> Result<_, NoSolutionOrRerunNonErased> {
688                let assume = ecx.structurally_normalize_const(
689                    goal.param_env,
690                    goal.predicate.trait_ref.args.const_at(2),
691                )?;
692
693                let certainty = ecx.is_transmutable(
694                    goal.predicate.trait_ref.args.type_at(0),
695                    goal.predicate.trait_ref.args.type_at(1),
696                    assume,
697                )?;
698                ecx.evaluate_added_goals_and_make_canonical_response(certainty)
699            },
700        )
701    }
702
703    /// NOTE: This is implemented as a built-in goal and not a set of impls like:
704    ///
705    /// ```rust,ignore (illustrative)
706    /// impl<T> BikeshedGuaranteedNoDrop for T where T: Copy {}
707    /// impl<T> BikeshedGuaranteedNoDrop for ManuallyDrop<T> {}
708    /// ```
709    ///
710    /// because these impls overlap, and I'd rather not build a coherence hack for
711    /// this harmless overlap.
712    ///
713    /// This trait is indirectly exposed on stable, so do *not* extend the set of types that
714    /// implement the trait without FCP!
715    fn consider_builtin_bikeshed_guaranteed_no_drop_candidate(
716        ecx: &mut EvalCtxt<'_, D>,
717        goal: Goal<I, Self>,
718    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
719        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
720            return Err(NoSolution.into());
721        }
722
723        let cx = ecx.cx();
724        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
725            let ty = goal.predicate.self_ty();
726            match ty.kind() {
727                // `&mut T` and `&T` always implement `BikeshedGuaranteedNoDrop`.
728                ty::Ref(..) => {}
729                // `ManuallyDrop<T>` always implements `BikeshedGuaranteedNoDrop`.
730                ty::Adt(def, _) if def.is_manually_drop() => {}
731                // Arrays and tuples implement `BikeshedGuaranteedNoDrop` only if
732                // their constituent types implement `BikeshedGuaranteedNoDrop`.
733                ty::Tuple(tys) => {
734                    ecx.add_goals(
735                        GoalSource::ImplWhereBound,
736                        tys.iter().map(|elem_ty| {
737                            goal.with(cx, ty::TraitRef::new(cx, goal.predicate.def_id(), [elem_ty]))
738                        }),
739                    )?;
740                }
741                ty::Array(elem_ty, _) => {
742                    ecx.add_goal(
743                        GoalSource::ImplWhereBound,
744                        goal.with(cx, ty::TraitRef::new(cx, goal.predicate.def_id(), [elem_ty])),
745                    )?;
746                }
747
748                // All other types implement `BikeshedGuaranteedNoDrop` only if
749                // they implement `Copy`. We could be smart here and short-circuit
750                // some trivially `Copy`/`!Copy` types, but there's no benefit.
751                ty::FnDef(..)
752                | ty::FnPtr(..)
753                | ty::Error(_)
754                | ty::Uint(_)
755                | ty::Int(_)
756                | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
757                | ty::Bool
758                | ty::Float(_)
759                | ty::Char
760                | ty::RawPtr(..)
761                | ty::Never
762                | ty::Pat(..)
763                | ty::Dynamic(..)
764                | ty::Str
765                | ty::Slice(_)
766                | ty::Foreign(..)
767                | ty::Adt(..)
768                | ty::Alias(..)
769                | ty::Param(_)
770                | ty::Placeholder(..)
771                | ty::Closure(..)
772                | ty::CoroutineClosure(..)
773                | ty::Coroutine(..)
774                | ty::UnsafeBinder(_)
775                | ty::CoroutineWitness(..) => {
776                    ecx.add_goal(
777                        GoalSource::ImplWhereBound,
778                        goal.with(
779                            cx,
780                            ty::TraitRef::new(
781                                cx,
782                                cx.require_trait_lang_item(SolverTraitLangItem::Copy),
783                                [ty],
784                            ),
785                        ),
786                    )?;
787                }
788
789                ty::Bound(..)
790                | ty::Infer(
791                    ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),
792                ) => {
793                    { ::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`", ty)); }panic!("unexpected type `{ty:?}`")
794                }
795            }
796
797            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
798        })
799    }
800
801    /// ```ignore (builtin impl example)
802    /// trait Trait {
803    ///     fn foo(&self);
804    /// }
805    /// // results in the following builtin impl
806    /// impl<'a, T: Trait + 'a> Unsize<dyn Trait + 'a> for T {}
807    /// ```
808    fn consider_structural_builtin_unsize_candidates(
809        ecx: &mut EvalCtxt<'_, D>,
810        goal: Goal<I, Self>,
811    ) -> Result<Vec<Candidate<I>>, RerunNonErased> {
812        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
813            return Ok(::alloc::vec::Vec::new()vec![]);
814        }
815
816        let result = ecx.probe(|_| ProbeKind::UnsizeAssembly).enter(
817            |ecx| -> Result<Vec<Candidate<I>>, NoSolutionOrRerunNonErased> {
818                let a_ty = goal.predicate.self_ty();
819                // We need to normalize the b_ty since it's matched structurally
820                // in the other functions below.
821                let b_ty = ecx.structurally_normalize_ty(
822                    goal.param_env,
823                    goal.predicate.trait_ref.args.type_at(1),
824                )?;
825
826                let goal = goal.with(ecx.cx(), (a_ty, b_ty));
827                match (a_ty.kind(), b_ty.kind()) {
828                    (ty::Infer(ty::TyVar(..)), ..) => {
    ::core::panicking::panic_fmt(format_args!("unexpected infer {0:?} {1:?}",
            a_ty, b_ty));
}panic!("unexpected infer {a_ty:?} {b_ty:?}"),
829
830                    (_, ty::Infer(ty::TyVar(..))) => {
831                        Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)?]))vec![ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)?])
832                    }
833
834                    // Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b`.
835                    (ty::Dynamic(a_data, a_region), ty::Dynamic(b_data, b_region)) => Ok(ecx
836                        .consider_builtin_dyn_upcast_candidates(
837                            goal, a_data, a_region, b_data, b_region,
838                        )),
839
840                    // `T` -> `dyn Trait` unsizing.
841                    (_, ty::Dynamic(b_region, b_data)) => Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region,
                        b_data)?]))vec![
842                        ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region, b_data)?,
843                    ]),
844
845                    // `[T; N]` -> `[T]` unsizing
846                    (ty::Array(a_elem_ty, ..), ty::Slice(b_elem_ty)) => {
847                        Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)?]))vec![ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)?])
848                    }
849
850                    // `Struct<T>` -> `Struct<U>` where `T: Unsize<U>`
851                    (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args))
852                        if a_def.is_struct() && a_def == b_def =>
853                    {
854                        Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args)?]))vec![ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args)?])
855                    }
856
857                    _ => Err(NoSolution.into()),
858                }
859            },
860        );
861
862        match result.map_err_to_rerun()? {
863            Ok(resp) => Ok(resp),
864            Err(NoSolution) => Ok(::alloc::vec::Vec::new()vec![]),
865        }
866    }
867
868    fn consider_builtin_field_candidate(
869        ecx: &mut EvalCtxt<'_, D>,
870        goal: Goal<I, Self>,
871    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
872        if goal.predicate.polarity != ty::PredicatePolarity::Positive {
873            return Err(NoSolution.into());
874        }
875        if let ty::Adt(def, args) = goal.predicate.self_ty().kind()
876            && let Some(FieldInfo { base, ty, .. }) =
877                def.field_representing_type_info(ecx.cx(), args)
878            && {
879                let sized_trait = ecx.cx().require_trait_lang_item(SolverTraitLangItem::Sized);
880                // FIXME: add better support for builtin impls of traits that check for the bounds
881                // on the trait definition in std.
882
883                // NOTE: these bounds have to be kept in sync with the definition of the `Field`
884                // trait in `library/core/src/field.rs` as well as the old trait solver `fn
885                // assemble_candidates_for_field_trait` in
886                // `compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs`.
887                ecx.add_goal(
888                    GoalSource::ImplWhereBound,
889                    Goal {
890                        param_env: goal.param_env,
891                        predicate: TraitRef::new(ecx.cx(), sized_trait, [base]).upcast(ecx.cx()),
892                    },
893                )?;
894                ecx.add_goal(
895                    GoalSource::ImplWhereBound,
896                    Goal {
897                        param_env: goal.param_env,
898                        predicate: TraitRef::new(ecx.cx(), sized_trait, [ty]).upcast(ecx.cx()),
899                    },
900                )?;
901                // FIXME(field_projections): This function does some questionable incomplete stuff by
902                // returning `Err(NoSolution)` on ambiguity.
903                ecx.try_evaluate_added_goals()? == Certainty::Yes
904            }
905            && match base.kind() {
906                ty::Adt(def, _) => def.is_struct() && !def.is_packed(),
907                ty::Tuple(..) => true,
908                _ => false,
909            }
910        {
911            ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
912                .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
913        } else {
914            Err(NoSolution.into())
915        }
916    }
917}
918
919/// Small helper function to change the `def_id` of a trait predicate - this is not normally
920/// something that you want to do, as different traits will require different args and so making
921/// it easy to change the trait is something of a footgun, but it is useful in the narrow
922/// circumstance of changing from `MetaSized` to `Sized`, which happens as part of the lazy
923/// elaboration of sizedness candidates.
924#[inline(always)]
925fn trait_predicate_with_def_id<I: Interner>(
926    cx: I,
927    clause: ty::Binder<I, ty::TraitPredicate<I>>,
928    did: I::TraitId,
929) -> I::Clause {
930    clause
931        .map_bound(|c| TraitPredicate {
932            trait_ref: TraitRef::new_from_args(cx, did, c.trait_ref.args),
933            polarity: c.polarity,
934        })
935        .upcast(cx)
936}
937
938impl<D, I> EvalCtxt<'_, D>
939where
940    D: SolverDelegate<Interner = I>,
941    I: Interner,
942{
943    /// Trait upcasting allows for coercions between trait objects:
944    /// ```ignore (builtin impl example)
945    /// trait Super {}
946    /// trait Trait: Super {}
947    /// // results in builtin impls upcasting to a super trait
948    /// impl<'a, 'b: 'a> Unsize<dyn Super + 'a> for dyn Trait + 'b {}
949    /// // and impls removing auto trait bounds.
950    /// impl<'a, 'b: 'a> Unsize<dyn Trait + 'a> for dyn Trait + Send + 'b {}
951    /// ```
952    fn consider_builtin_dyn_upcast_candidates(
953        &mut self,
954        goal: Goal<I, (I::Ty, I::Ty)>,
955        a_data: I::BoundExistentialPredicates,
956        a_region: Region<I>,
957        b_data: I::BoundExistentialPredicates,
958        b_region: Region<I>,
959    ) -> Vec<Candidate<I>> {
960        let cx = self.cx();
961        let Goal { predicate: (a_ty, _b_ty), .. } = goal;
962
963        let mut responses = ::alloc::vec::Vec::new()vec![];
964        // If the principal def ids match (or are both none), then we're not doing
965        // trait upcasting. We're just removing auto traits (or shortening the lifetime).
966        let b_principal_def_id = b_data.principal_def_id();
967        if a_data.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
968            responses.extend(self.consider_builtin_upcast_to_principal(
969                goal,
970                CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
971                a_data,
972                a_region,
973                b_data,
974                b_region,
975                a_data.principal(),
976            ));
977        } else if let Some(a_principal) = a_data.principal() {
978            for (idx, new_a_principal) in
979                elaborate::supertraits(self.cx(), a_principal.with_self_ty(cx, a_ty))
980                    .enumerate()
981                    .skip(1)
982            {
983                responses.extend(self.consider_builtin_upcast_to_principal(
984                    goal,
985                    CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting(idx)),
986                    a_data,
987                    a_region,
988                    b_data,
989                    b_region,
990                    Some(new_a_principal.map_bound(|trait_ref| {
991                        ty::ExistentialTraitRef::erase_self_ty(cx, trait_ref)
992                    })),
993                ));
994            }
995        }
996
997        responses
998    }
999
1000    fn consider_builtin_unsize_to_dyn_candidate(
1001        &mut self,
1002        goal: Goal<I, (I::Ty, I::Ty)>,
1003        b_data: I::BoundExistentialPredicates,
1004        b_region: Region<I>,
1005    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1006        let cx = self.cx();
1007        let Goal { predicate: (a_ty, _), .. } = goal;
1008
1009        // Can only unsize to an dyn-compatible trait.
1010        if b_data.principal_def_id().is_some_and(|def_id| !cx.trait_is_dyn_compatible(def_id)) {
1011            return Err(NoSolution.into());
1012        }
1013
1014        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1015            // Check that the type implements all of the predicates of the trait object.
1016            // (i.e. the principal, all of the associated types match, and any auto traits)
1017            ecx.add_goals(
1018                GoalSource::ImplWhereBound,
1019                b_data.iter().map(|pred| goal.with(cx, pred.with_self_ty(cx, a_ty))),
1020            )?;
1021
1022            // The type must be `Sized` to be unsized.
1023            ecx.add_goal(
1024                GoalSource::ImplWhereBound,
1025                goal.with(
1026                    cx,
1027                    ty::TraitRef::new(
1028                        cx,
1029                        cx.require_trait_lang_item(SolverTraitLangItem::Sized),
1030                        [a_ty],
1031                    ),
1032                ),
1033            )?;
1034
1035            // The type must outlive the lifetime of the `dyn` we're unsizing into.
1036            ecx.add_goal(GoalSource::Misc, goal.with(cx, ty::OutlivesPredicate(a_ty, b_region)))?;
1037            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1038        })
1039    }
1040
1041    fn consider_builtin_upcast_to_principal(
1042        &mut self,
1043        goal: Goal<I, (I::Ty, I::Ty)>,
1044        source: CandidateSource<I>,
1045        a_data: I::BoundExistentialPredicates,
1046        a_region: Region<I>,
1047        b_data: I::BoundExistentialPredicates,
1048        b_region: Region<I>,
1049        upcast_principal: Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>,
1050    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1051        let param_env = goal.param_env;
1052
1053        // We may upcast to auto traits that are either explicitly listed in
1054        // the object type's bounds, or implied by the principal trait ref's
1055        // supertraits.
1056        let a_auto_traits: IndexSet<I::TraitId> = a_data
1057            .auto_traits()
1058            .into_iter()
1059            .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
1060                elaborate::supertrait_def_ids(self.cx(), principal_def_id)
1061                    .filter(|def_id| self.cx().trait_is_auto(*def_id))
1062            }))
1063            .collect();
1064
1065        // More than one projection in a_ty's bounds may match the projection
1066        // in b_ty's bound. Use this to first determine *which* apply without
1067        // having any inference side-effects. We process obligations because
1068        // unification may initially succeed due to deferred projection equality.
1069        let projection_may_match =
1070            |ecx: &mut EvalCtxt<'_, D>,
1071             source_projection: ty::Binder<I, ty::ExistentialProjection<I>>,
1072             target_projection: ty::Binder<I, ty::ExistentialProjection<I>>| {
1073                source_projection.item_def_id() == target_projection.item_def_id()
1074                    && ecx
1075                        .probe(|_| ProbeKind::ProjectionCompatibility)
1076                        .enter(|ecx| {
1077                            ecx.enter_forall_with_assumptions(
1078                                target_projection,
1079                                param_env,
1080                                |ecx, target_projection| {
1081                                    let source_projection =
1082                                        ecx.instantiate_binder_with_infer(source_projection);
1083                                    ecx.eq(param_env, source_projection, target_projection)?;
1084                                    ecx.try_evaluate_added_goals()
1085                                },
1086                            )
1087                        })
1088                        .is_ok()
1089            };
1090
1091        self.probe_trait_candidate(source).enter(|ecx| {
1092            for bound in b_data.iter() {
1093                match bound.skip_binder() {
1094                    // Check that a's supertrait (upcast_principal) is compatible
1095                    // with the target (b_ty).
1096                    ty::ExistentialPredicate::Trait(target_principal) => {
1097                        let source_principal = upcast_principal.unwrap();
1098                        let target_principal = bound.rebind(target_principal);
1099                        ecx.enter_forall_with_assumptions(
1100                            target_principal,
1101                            param_env,
1102                            |ecx, target_principal| {
1103                                let source_principal =
1104                                    ecx.instantiate_binder_with_infer(source_principal);
1105                                ecx.eq(param_env, source_principal, target_principal)?;
1106                                ecx.try_evaluate_added_goals()
1107                            },
1108                        )?;
1109                    }
1110                    // Check that b_ty's projection is satisfied by exactly one of
1111                    // a_ty's projections. First, we look through the list to see if
1112                    // any match. If not, error. Then, if *more* than one matches, we
1113                    // return ambiguity. Otherwise, if exactly one matches, equate
1114                    // it with b_ty's projection.
1115                    ty::ExistentialPredicate::Projection(target_projection) => {
1116                        let target_projection = bound.rebind(target_projection);
1117                        let mut matching_projections =
1118                            a_data.projection_bounds().into_iter().filter(|source_projection| {
1119                                projection_may_match(ecx, *source_projection, target_projection)
1120                            });
1121                        let Some(source_projection) = matching_projections.next() else {
1122                            return Err(NoSolution.into());
1123                        };
1124                        if matching_projections.next().is_some() {
1125                            return ecx.evaluate_added_goals_and_make_canonical_response(
1126                                Certainty::AMBIGUOUS,
1127                            );
1128                        }
1129                        ecx.enter_forall_with_assumptions(
1130                            target_projection,
1131                            param_env,
1132                            |ecx, target_projection| {
1133                                let source_projection =
1134                                    ecx.instantiate_binder_with_infer(source_projection);
1135                                ecx.eq(param_env, source_projection, target_projection)?;
1136                                ecx.try_evaluate_added_goals()
1137                            },
1138                        )?;
1139                    }
1140                    // Check that b_ty's auto traits are present in a_ty's bounds.
1141                    ty::ExistentialPredicate::AutoTrait(def_id) => {
1142                        if !a_auto_traits.contains(&def_id) {
1143                            return Err(NoSolution.into());
1144                        }
1145                    }
1146                }
1147            }
1148
1149            // Also require that a_ty's lifetime outlives b_ty's lifetime.
1150            ecx.add_goal(
1151                GoalSource::ImplWhereBound,
1152                Goal::new(ecx.cx(), param_env, ty::OutlivesPredicate(a_region, b_region)),
1153            )?;
1154
1155            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1156        })
1157    }
1158
1159    /// We have the following builtin impls for arrays:
1160    /// ```ignore (builtin impl example)
1161    /// impl<T: ?Sized, const N: usize> Unsize<[T]> for [T; N] {}
1162    /// ```
1163    /// While the impl itself could theoretically not be builtin,
1164    /// the actual unsizing behavior is builtin. Its also easier to
1165    /// make all impls of `Unsize` builtin as we're able to use
1166    /// `#[rustc_deny_explicit_impl]` in this case.
1167    fn consider_builtin_array_unsize(
1168        &mut self,
1169        goal: Goal<I, (I::Ty, I::Ty)>,
1170        a_elem_ty: I::Ty,
1171        b_elem_ty: I::Ty,
1172    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1173        self.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
1174        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
1175            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
1176    }
1177
1178    /// We generate a builtin `Unsize` impls for structs with generic parameters only
1179    /// mentioned by the last field.
1180    /// ```ignore (builtin impl example)
1181    /// struct Foo<T, U: ?Sized> {
1182    ///     sized_field: Vec<T>,
1183    ///     unsizable: Box<U>,
1184    /// }
1185    /// // results in the following builtin impl
1186    /// impl<T: ?Sized, U: ?Sized, V: ?Sized> Unsize<Foo<T, V>> for Foo<T, U>
1187    /// where
1188    ///     Box<U>: Unsize<Box<V>>,
1189    /// {}
1190    /// ```
1191    fn consider_builtin_struct_unsize(
1192        &mut self,
1193        goal: Goal<I, (I::Ty, I::Ty)>,
1194        def: I::AdtDef,
1195        a_args: I::GenericArgs,
1196        b_args: I::GenericArgs,
1197    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1198        let cx = self.cx();
1199        let Goal { predicate: (_a_ty, b_ty), .. } = goal;
1200
1201        let unsizing_params = cx.unsizing_params_for_adt(def.def_id());
1202        // We must be unsizing some type parameters. This also implies
1203        // that the struct has a tail field.
1204        if unsizing_params.is_empty() {
1205            return Err(NoSolution.into());
1206        }
1207
1208        let tail_field_ty = def.struct_tail_ty(cx).unwrap();
1209
1210        let a_tail_ty = tail_field_ty.instantiate(cx, a_args).skip_norm_wip();
1211        let b_tail_ty = tail_field_ty.instantiate(cx, b_args).skip_norm_wip();
1212
1213        // Instantiate just the unsizing params from B into A. The type after
1214        // this instantiation must be equal to B. This is so we don't unsize
1215        // unrelated type parameters.
1216        let new_a_args = cx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
1217            if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a }
1218        }));
1219        let unsized_a_ty = Ty::new_adt(cx, def, new_a_args);
1220
1221        // Finally, we require that `TailA: Unsize<TailB>` for the tail field
1222        // types.
1223        self.eq(goal.param_env, unsized_a_ty, b_ty)?;
1224        self.add_goal(
1225            GoalSource::ImplWhereBound,
1226            goal.with(
1227                cx,
1228                ty::TraitRef::new(
1229                    cx,
1230                    cx.require_trait_lang_item(SolverTraitLangItem::Unsize),
1231                    [a_tail_ty, b_tail_ty],
1232                ),
1233            ),
1234        )?;
1235        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
1236            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
1237    }
1238
1239    // Return `Some` if there is an impl (built-in or user provided) that may
1240    // hold for the self type of the goal, which for coherence and soundness
1241    // purposes must disqualify the built-in auto impl assembled by considering
1242    // the type's constituent types.
1243    fn disqualify_auto_trait_candidate_due_to_possible_impl(
1244        &mut self,
1245        goal: Goal<I, TraitPredicate<I>>,
1246    ) -> Option<Result<Candidate<I>, NoSolutionOrRerunNonErased>> {
1247        let self_ty = goal.predicate.self_ty();
1248        let check_impls = || {
1249            let mut disqualifying_impl = None;
1250            self.cx().for_each_relevant_impl(goal.predicate.trait_ref, |impl_def_id| {
1251                disqualifying_impl = Some(impl_def_id);
1252            });
1253            if let Some(def_id) = disqualifying_impl {
1254                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1254",
                        "rustc_next_trait_solver::solve::trait_goals",
                        ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
                        ::tracing_core::__macro_support::Option::Some(1254u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("def_id")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("def_id");
                                            NAME.as_str()
                                        },
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("goal")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("goal");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("disqualified auto-trait implementation")
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};trace!(?def_id, ?goal, "disqualified auto-trait implementation");
1255                // No need to actually consider the candidate here,
1256                // since we do that in `consider_impl_candidate`.
1257                return Some(Err(NoSolution.into()));
1258            } else {
1259                None
1260            }
1261        };
1262
1263        match self_ty.kind() {
1264            // Stall int and float vars until they are resolved to a concrete
1265            // numerical type. That's because the check for impls below treats
1266            // int vars as matching any impl. Even if we filtered such impls,
1267            // we probably don't want to treat an `impl !AutoTrait for i32` as
1268            // disqualifying the built-in auto impl for `i64: AutoTrait` either.
1269            ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
1270                Some(self.forced_ambiguity(MaybeInfo::AMBIGUOUS))
1271            }
1272
1273            // Backward compatibility for default auto traits.
1274            // Test: ui/traits/default_auto_traits/extern-types.rs
1275            ty::Foreign(..) if self.cx().is_default_trait(goal.predicate.def_id()) => check_impls(),
1276
1277            // These types cannot be structurally decomposed into constituent
1278            // types, and therefore have no built-in auto impl.
1279            ty::Dynamic(..)
1280            | ty::Param(..)
1281            | ty::Foreign(..)
1282            | ty::Alias(
1283                ty::IsRigid::Yes,
1284                ty::AliasTy {
1285                    kind: ty::Projection { .. } | ty::Free { .. } | ty::Inherent { .. },
1286                    ..
1287                },
1288            )
1289            | ty::Placeholder(..) => Some(Err(NoSolution.into())),
1290
1291            // Coroutines have one special built-in candidate, `Unpin`, which
1292            // takes precedence over the structural auto trait candidate being
1293            // assembled.
1294            ty::Coroutine(def_id, _)
1295                if self
1296                    .cx()
1297                    .is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::Unpin) =>
1298            {
1299                match self.cx().coroutine_movability(def_id) {
1300                    Movability::Static => Some(Err(NoSolution.into())),
1301                    Movability::Movable => Some(
1302                        self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1303                            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1304                        }),
1305                    ),
1306                }
1307            }
1308
1309            // If we still have an alias here, it must be rigid. For opaques, it's always
1310            // okay to consider auto traits because that'll reveal its hidden type. For
1311            // non-opaque aliases, we will not assemble any candidates since there's no way
1312            // to further look into its type.
1313            ty::Alias(ty::IsRigid::Yes, ty::AliasTy { kind: ty::Opaque { .. }, .. }) => None,
1314
1315            // For rigid types, any possible implementation that could apply to
1316            // the type (even if after unification and processing nested goals
1317            // it does not hold) will disqualify the built-in auto impl.
1318            //
1319            // We've originally had a more permissive check here which resulted
1320            // in unsoundness, see #84857.
1321            ty::Bool
1322            | ty::Char
1323            | ty::Int(_)
1324            | ty::Uint(_)
1325            | ty::Float(_)
1326            | ty::Str
1327            | ty::Array(_, _)
1328            | ty::Pat(_, _)
1329            | ty::Slice(_)
1330            | ty::RawPtr(_, _)
1331            | ty::Ref(_, _, _)
1332            | ty::FnDef(_, _)
1333            | ty::FnPtr(..)
1334            | ty::Closure(..)
1335            | ty::CoroutineClosure(..)
1336            | ty::Coroutine(_, _)
1337            | ty::CoroutineWitness(..)
1338            | ty::Never
1339            | ty::Tuple(_)
1340            | ty::Adt(_, _)
1341            | ty::UnsafeBinder(_) => check_impls(),
1342            ty::Error(_) => None,
1343
1344            ty::Infer(_) | ty::Alias(ty::IsRigid::No, _) | ty::Bound(_, _) => {
1345                {
    ::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`",
            self_ty));
}panic!("unexpected type `{self_ty:?}`")
1346            }
1347        }
1348    }
1349
1350    /// Convenience function for traits that are structural, i.e. that only
1351    /// have nested subgoals that only change the self type. Unlike other
1352    /// evaluate-like helpers, this does a probe, so it doesn't need to be
1353    /// wrapped in one.
1354    fn probe_and_evaluate_goal_for_constituent_tys(
1355        &mut self,
1356        source: CandidateSource<I>,
1357        goal: Goal<I, TraitPredicate<I>>,
1358        constituent_tys: impl Fn(
1359            &EvalCtxt<'_, D>,
1360            I::Ty,
1361        ) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>,
1362    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1363        self.probe_trait_candidate(source).enter(|ecx| {
1364            let goals = ecx.enter_forall_with_assumptions(
1365                constituent_tys(ecx, goal.predicate.self_ty())?,
1366                goal.param_env,
1367                |ecx, tys| {
1368                    tys.into_iter()
1369                        .map(|ty| {
1370                            goal.with(ecx.cx(), goal.predicate.with_replaced_self_ty(ecx.cx(), ty))
1371                        })
1372                        .collect::<Vec<_>>()
1373                },
1374            );
1375            ecx.add_goals(GoalSource::ImplWhereBound, goals)?;
1376            ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1377        })
1378    }
1379}
1380
1381/// How we've proven this trait goal.
1382///
1383/// This is used by `NormalizesTo` goals to only normalize
1384/// by using the same 'kind of candidate' we've used to prove
1385/// its corresponding trait goal. Most notably, we do not
1386/// normalize by using an impl if the trait goal has been
1387/// proven via a `ParamEnv` candidate.
1388///
1389/// This is necessary to avoid unnecessary region constraints,
1390/// see trait-system-refactor-initiative#125 for more details.
1391#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TraitGoalProvenVia {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                TraitGoalProvenVia::Misc => "Misc",
                TraitGoalProvenVia::ParamEnv => "ParamEnv",
                TraitGoalProvenVia::AliasBound => "AliasBound",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for TraitGoalProvenVia {
    #[inline]
    fn clone(&self) -> TraitGoalProvenVia { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for TraitGoalProvenVia { }Copy)]
1392pub(super) enum TraitGoalProvenVia {
1393    /// We've proven the trait goal by something which is
1394    /// is not a non-global where-bound or an alias-bound.
1395    ///
1396    /// This means we don't disable any candidates during
1397    /// normalization.
1398    Misc,
1399    ParamEnv,
1400    AliasBound,
1401}
1402
1403impl<D, I> EvalCtxt<'_, D>
1404where
1405    D: SolverDelegate<Interner = I>,
1406    I: Interner,
1407{
1408    /// FIXME(#57893): For backwards compatibility with the old trait solver implementation,
1409    /// we need to handle overlap between builtin and user-written impls for trait objects.
1410    ///
1411    /// This overlap is unsound in general and something which we intend to fix separately.
1412    /// To avoid blocking the stabilization of the trait solver, we add this hack to avoid
1413    /// breakage in cases which are *mostly fine*™. Importantly, this preference is strictly
1414    /// weaker than the old behavior.
1415    ///
1416    /// We only prefer builtin over user-written impls if there are no inference constraints.
1417    /// Importantly, we also only prefer the builtin impls for trait goals, and not during
1418    /// normalization. This means the only case where this special-case results in exploitable
1419    /// unsoundness should be lifetime dependent user-written impls.
1420    pub(super) fn unsound_prefer_builtin_dyn_impl(&mut self, candidates: &mut Vec<Candidate<I>>) {
1421        if self.typing_mode().is_coherence() {
1422            return;
1423        }
1424
1425        if candidates
1426            .iter()
1427            .find(|c| {
1428                #[allow(non_exhaustive_omitted_patterns)] match c.source {
    CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)) => true,
    _ => false,
}matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)))
1429            })
1430            .is_some_and(|c| has_only_region_constraints(c.result))
1431        {
1432            candidates.retain(|c| {
1433                if #[allow(non_exhaustive_omitted_patterns)] match c.source {
    CandidateSource::Impl(_) => true,
    _ => false,
}matches!(c.source, CandidateSource::Impl(_)) {
1434                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1434",
                        "rustc_next_trait_solver::solve::trait_goals",
                        ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
                        ::tracing_core::__macro_support::Option::Some(1434u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("c")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("c");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("unsoundly dropping impl in favor of builtin dyn-candidate")
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&c)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(?c, "unsoundly dropping impl in favor of builtin dyn-candidate");
1435                    false
1436                } else {
1437                    true
1438                }
1439            });
1440        }
1441    }
1442
1443    x;#[instrument(level = "debug", skip(self), ret)]
1444    pub(super) fn merge_trait_candidates(
1445        &mut self,
1446        candidate_preference_mode: CandidatePreferenceMode,
1447        mut candidates: Vec<Candidate<I>>,
1448        failed_candidate_info: FailedCandidateInfo,
1449    ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
1450        if self.typing_mode().is_coherence() {
1451            return if let Some((response, _)) = self.try_merge_candidates(&candidates) {
1452                Ok((response, Some(TraitGoalProvenVia::Misc)))
1453            } else {
1454                self.flounder(&candidates).map(|r| (r, None))
1455            };
1456        }
1457
1458        // We prefer trivial builtin candidates, i.e. builtin impls without any
1459        // nested requirements, over all others. This is a fix for #53123 and
1460        // prevents where-bounds from accidentally extending the lifetime of a
1461        // variable.
1462        let mut trivial_builtin_impls = candidates.iter().filter(|c| {
1463            matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))
1464        });
1465        if let Some(candidate) = trivial_builtin_impls.next() {
1466            // There should only ever be a single trivial builtin candidate
1467            // as they would otherwise overlap.
1468            assert!(trivial_builtin_impls.next().is_none());
1469            return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
1470        }
1471
1472        // Extract non-nested alias bound candidates, will be preferred over where bounds if
1473        // we're proving an auto-trait, sizedness trait or default trait.
1474        if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
1475            && candidates.iter().any(|c| {
1476                matches!(c.source, CandidateSource::AliasBound(AliasBoundKind::SelfBounds))
1477            })
1478        {
1479            let alias_bounds: Vec<_> = candidates
1480                .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(..)))
1481                .collect();
1482            return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1483                Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1484            } else {
1485                Ok((self.bail_with_ambiguity(&alias_bounds), None))
1486            };
1487        }
1488
1489        // If there are non-global where-bounds, prefer where-bounds
1490        // (including global ones) over everything else.
1491        let has_non_global_where_bounds = candidates
1492            .iter()
1493            .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)));
1494        if has_non_global_where_bounds {
1495            let where_bounds: Vec<_> = candidates
1496                .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_)))
1497                .collect();
1498            let Some((response, info)) = self.try_merge_candidates(&where_bounds) else {
1499                return Ok((self.bail_with_ambiguity(&where_bounds), None));
1500            };
1501            match info {
1502                // If there's an always applicable candidate, the result of all
1503                // other candidates does not matter. This means we can ignore
1504                // them when checking whether we've reached a fixpoint.
1505                //
1506                // We always prefer the first always applicable candidate, even if a
1507                // later candidate is also always applicable and would result in fewer
1508                // reruns. We could slightly improve this by e.g. searching for another
1509                // always applicable candidate which doesn't depend on any cycle heads.
1510                //
1511                // NOTE: This is optimization is observable in case there is an always
1512                // applicable global candidate and another non-global candidate which only
1513                // applies because of a provisional result. I can't even think of a test
1514                // case where this would occur and even then, this would not be unsound.
1515                // Supporting this makes the code more involved, so I am just going to
1516                // ignore this for now.
1517                MergeCandidateInfo::AlwaysApplicable(i) => {
1518                    for (j, c) in where_bounds.into_iter().enumerate() {
1519                        if i != j {
1520                            self.ignore_candidate_head_usages(c.head_usages)
1521                        }
1522                    }
1523                    // If a where-bound does not apply, we don't actually get a
1524                    // candidate for it. We manually track the head usages
1525                    // of all failed `ParamEnv` candidates instead.
1526                    self.ignore_candidate_head_usages(failed_candidate_info.param_env_head_usages);
1527                }
1528                MergeCandidateInfo::EqualResponse => {}
1529            }
1530            return Ok((response, Some(TraitGoalProvenVia::ParamEnv)));
1531        }
1532
1533        // Next, prefer any alias bound (nested or otherwise).
1534        if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound(_))) {
1535            let alias_bounds: Vec<_> = candidates
1536                .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(_)))
1537                .collect();
1538            return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1539                Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1540            } else {
1541                Ok((self.bail_with_ambiguity(&alias_bounds), None))
1542            };
1543        }
1544
1545        self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);
1546        self.unsound_prefer_builtin_dyn_impl(&mut candidates);
1547
1548        // If there are *only* global where bounds, then make sure to return that this
1549        // is still reported as being proven-via the param-env so that rigid projections
1550        // operate correctly. Otherwise, drop all global where-bounds before merging the
1551        // remaining candidates.
1552        let proven_via = if candidates
1553            .iter()
1554            .all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)))
1555        {
1556            TraitGoalProvenVia::ParamEnv
1557        } else {
1558            candidates
1559                .retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
1560            TraitGoalProvenVia::Misc
1561        };
1562
1563        if let Some((response, _)) = self.try_merge_candidates(&candidates) {
1564            Ok((response, Some(proven_via)))
1565        } else {
1566            self.flounder(&candidates).map(|r| (r, None))
1567        }
1568    }
1569
1570    #[allow(clippy :: suspicious_else_formatting)]
{
    let __tracing_attr_span;
    let __tracing_attr_guard;
    if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() ||
            { false } {
        __tracing_attr_span =
            {
                use ::tracing::__macro_support::Callsite as _;
                static __CALLSITE: ::tracing::callsite::DefaultCallsite =
                    {
                        static META: ::tracing::Metadata<'static> =
                            {
                                ::tracing_core::metadata::Metadata::new("compute_trait_goal",
                                    "rustc_next_trait_solver::solve::trait_goals",
                                    ::tracing::Level::TRACE,
                                    ::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
                                    ::tracing_core::__macro_support::Option::Some(1570u32),
                                    ::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
                                    ::tracing_core::field::FieldSet::new(&[{
                                                        const NAME:
                                                            ::tracing::__macro_support::FieldName<{
                                                                ::tracing::__macro_support::FieldName::len("goal")
                                                            }> =
                                                            ::tracing::__macro_support::FieldName::new("goal");
                                                        NAME.as_str()
                                                    }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                                    ::tracing::metadata::Kind::SPAN)
                            };
                        ::tracing::callsite::DefaultCallsite::new(&META)
                    };
                let mut interest = ::tracing::subscriber::Interest::never();
                if ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::STATIC_MAX_LEVEL &&
                                ::tracing::Level::TRACE <=
                                    ::tracing::level_filters::LevelFilter::current() &&
                            { interest = __CALLSITE.interest(); !interest.is_never() }
                        &&
                        ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                            interest) {
                    let meta = __CALLSITE.metadata();
                    ::tracing::Span::new(meta,
                        &{
                                #[allow(unused_imports)]
                                use ::tracing::field::{debug, display, Value};
                                meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
                                                            as &dyn ::tracing::field::Value))])
                            })
                } else {
                    let span =
                        ::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
                    {};
                    span
                }
            };
        __tracing_attr_guard = __tracing_attr_span.enter();
    }

    #[warn(clippy :: suspicious_else_formatting)]
    {

        #[allow(unknown_lints, unreachable_code, clippy ::
        diverging_sub_expression, clippy :: empty_loop, clippy ::
        let_unit_value, clippy :: let_with_type_underscore, clippy ::
        needless_return, clippy :: unreachable)]
        if false {
            let __tracing_attr_fake_return:
                    Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>),
                    NoSolutionOrRerunNonErased> = loop {};
            return __tracing_attr_fake_return;
        }
        {
            let (candidates, failed_candidate_info) =
                self.assemble_and_evaluate_candidates(goal,
                        AssembleCandidatesFrom::All)?;
            let candidate_preference_mode =
                CandidatePreferenceMode::compute(self.cx(),
                    goal.predicate.def_id());
            self.merge_trait_candidates(candidate_preference_mode, candidates,
                    failed_candidate_info).map_err(Into::into)
        }
    }
}#[instrument(level = "trace", skip(self))]
1571    pub(super) fn compute_trait_goal(
1572        &mut self,
1573        goal: Goal<I, TraitPredicate<I>>,
1574    ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolutionOrRerunNonErased>
1575    {
1576        let (candidates, failed_candidate_info) =
1577            self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All)?;
1578        let candidate_preference_mode =
1579            CandidatePreferenceMode::compute(self.cx(), goal.predicate.def_id());
1580        self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info)
1581            .map_err(Into::into)
1582    }
1583
1584    fn try_stall_coroutine(
1585        &mut self,
1586        self_ty: I::Ty,
1587    ) -> Option<Result<Candidate<I>, NoSolutionOrRerunNonErased>> {
1588        if let ty::Coroutine(def_id, _) = self_ty.kind() {
1589            match self.typing_mode() {
1590                TypingMode::Typeck { defining_opaque_types_and_generators: stalled_generators } => {
1591                    if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
1592                    {
1593                        return Some(self.forced_ambiguity(MaybeInfo {
1594                            cause: MaybeCause::Ambiguity,
1595                            opaque_types_jank: OpaqueTypesJank::AllGood,
1596                            stalled_on_coroutines: StalledOnCoroutines::Yes,
1597                        }));
1598                    }
1599                }
1600                TypingMode::ErasedNotCoherence(MayBeErased) => {
1601                    // Trying to continue here isn't worth it.
1602                    return Some(
1603                        match self.opaque_accesses.rerun_always(RerunReason::TryStallCoroutine) {
1604                            Err(e) => Err(e.into()),
1605                        },
1606                    );
1607                }
1608                TypingMode::Coherence
1609                | TypingMode::PostAnalysis
1610                | TypingMode::Codegen
1611                | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ }
1612                | TypingMode::PostBorrowck { defined_opaque_types: _ } => {}
1613            }
1614        }
1615
1616        None
1617    }
1618}