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