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