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