rustc_trait_selection/traits/select/
confirmation.rs

1//! Confirmation.
2//!
3//! Confirmation unifies the output type parameters of the trait
4//! with the values found in the obligation, possibly yielding a
5//! type error. See the [rustc dev guide] for more details.
6//!
7//! [rustc dev guide]:
8//! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
9
10use std::ops::ControlFlow;
11
12use rustc_data_structures::stack::ensure_sufficient_stack;
13use rustc_hir::lang_items::LangItem;
14use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk};
15use rustc_infer::traits::ObligationCauseCode;
16use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
17use rustc_middle::ty::{self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast};
18use rustc_middle::{bug, span_bug};
19use rustc_span::def_id::DefId;
20use thin_vec::thin_vec;
21use tracing::{debug, instrument};
22
23use super::SelectionCandidate::{self, *};
24use super::{PredicateObligations, SelectionContext};
25use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
26use crate::traits::util::{self, closure_trait_ref_and_return_type};
27use crate::traits::{
28    ImplSource, ImplSourceUserDefinedData, Normalized, Obligation, ObligationCause,
29    PolyTraitObligation, PredicateObligation, Selection, SelectionError, TraitObligation,
30};
31
32impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
33    #[instrument(level = "debug", skip(self))]
34    pub(super) fn confirm_candidate(
35        &mut self,
36        obligation: &PolyTraitObligation<'tcx>,
37        candidate: SelectionCandidate<'tcx>,
38    ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
39        Ok(match candidate {
40            SizedCandidate => {
41                let data = self.confirm_builtin_candidate(obligation);
42                ImplSource::Builtin(BuiltinImplSource::Misc, data)
43            }
44
45            BuiltinCandidate => {
46                let data = self.confirm_builtin_candidate(obligation);
47                ImplSource::Builtin(BuiltinImplSource::Misc, data)
48            }
49
50            TransmutabilityCandidate => {
51                let data = self.confirm_transmutability_candidate(obligation)?;
52                ImplSource::Builtin(BuiltinImplSource::Misc, data)
53            }
54
55            ParamCandidate(param) => {
56                let obligations =
57                    self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
58                ImplSource::Param(obligations)
59            }
60
61            ImplCandidate(impl_def_id) => {
62                ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))
63            }
64
65            AutoImplCandidate => {
66                let data = self.confirm_auto_impl_candidate(obligation)?;
67                ImplSource::Builtin(BuiltinImplSource::Misc, data)
68            }
69
70            ProjectionCandidate(idx) => {
71                let obligations = self.confirm_projection_candidate(obligation, idx)?;
72                ImplSource::Param(obligations)
73            }
74
75            ObjectCandidate(idx) => self.confirm_object_candidate(obligation, idx)?,
76
77            ClosureCandidate { .. } => {
78                let vtable_closure = self.confirm_closure_candidate(obligation)?;
79                ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
80            }
81
82            AsyncClosureCandidate => {
83                let vtable_closure = self.confirm_async_closure_candidate(obligation)?;
84                ImplSource::Builtin(BuiltinImplSource::Misc, vtable_closure)
85            }
86
87            // No nested obligations or confirmation process. The checks that we do in
88            // candidate assembly are sufficient.
89            AsyncFnKindHelperCandidate => {
90                ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new())
91            }
92
93            CoroutineCandidate => {
94                let vtable_coroutine = self.confirm_coroutine_candidate(obligation)?;
95                ImplSource::Builtin(BuiltinImplSource::Misc, vtable_coroutine)
96            }
97
98            FutureCandidate => {
99                let vtable_future = self.confirm_future_candidate(obligation)?;
100                ImplSource::Builtin(BuiltinImplSource::Misc, vtable_future)
101            }
102
103            IteratorCandidate => {
104                let vtable_iterator = self.confirm_iterator_candidate(obligation)?;
105                ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
106            }
107
108            AsyncIteratorCandidate => {
109                let vtable_iterator = self.confirm_async_iterator_candidate(obligation)?;
110                ImplSource::Builtin(BuiltinImplSource::Misc, vtable_iterator)
111            }
112
113            FnPointerCandidate => {
114                let data = self.confirm_fn_pointer_candidate(obligation)?;
115                ImplSource::Builtin(BuiltinImplSource::Misc, data)
116            }
117
118            TraitAliasCandidate => {
119                let data = self.confirm_trait_alias_candidate(obligation);
120                ImplSource::Builtin(BuiltinImplSource::Misc, data)
121            }
122
123            BuiltinObjectCandidate => {
124                // This indicates something like `Trait + Send: Send`. In this case, we know that
125                // this holds because that's what the object type is telling us, and there's really
126                // no additional obligations to prove and no types in particular to unify, etc.
127                ImplSource::Builtin(BuiltinImplSource::Misc, PredicateObligations::new())
128            }
129
130            BuiltinUnsizeCandidate => self.confirm_builtin_unsize_candidate(obligation)?,
131
132            TraitUpcastingUnsizeCandidate(idx) => {
133                self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?
134            }
135
136            BikeshedGuaranteedNoDropCandidate => {
137                self.confirm_bikeshed_guaranteed_no_drop_candidate(obligation)
138            }
139        })
140    }
141
142    fn confirm_projection_candidate(
143        &mut self,
144        obligation: &PolyTraitObligation<'tcx>,
145        idx: usize,
146    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
147        let tcx = self.tcx();
148
149        let placeholder_trait_predicate =
150            self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref;
151        let placeholder_self_ty = self.infcx.shallow_resolve(placeholder_trait_predicate.self_ty());
152        let candidate_predicate = self
153            .for_each_item_bound(
154                placeholder_self_ty,
155                |_, clause, clause_idx| {
156                    if clause_idx == idx {
157                        ControlFlow::Break(clause)
158                    } else {
159                        ControlFlow::Continue(())
160                    }
161                },
162                || unreachable!(),
163            )
164            .break_value()
165            .expect("expected to index into clause that exists");
166        let candidate_predicate = candidate_predicate
167            .as_trait_clause()
168            .expect("projection candidate is not a trait predicate");
169        let candidate_predicate =
170            util::lazily_elaborate_sizedness_candidate(self.infcx, obligation, candidate_predicate);
171
172        let candidate = candidate_predicate.map_bound(|t| t.trait_ref);
173
174        let candidate = self.infcx.instantiate_binder_with_fresh_vars(
175            obligation.cause.span,
176            BoundRegionConversionTime::HigherRankedType,
177            candidate,
178        );
179        let mut obligations = PredicateObligations::new();
180        let candidate = normalize_with_depth_to(
181            self,
182            obligation.param_env,
183            obligation.cause.clone(),
184            obligation.recursion_depth + 1,
185            candidate,
186            &mut obligations,
187        );
188
189        obligations.extend(
190            self.infcx
191                .at(&obligation.cause, obligation.param_env)
192                .eq(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
193                .map(|InferOk { obligations, .. }| obligations)
194                .map_err(|_| SelectionError::Unimplemented)?,
195        );
196
197        // FIXME(compiler-errors): I don't think this is needed.
198        if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
199            let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
200            for (predicate, _) in predicates {
201                let normalized = normalize_with_depth_to(
202                    self,
203                    obligation.param_env,
204                    obligation.cause.clone(),
205                    obligation.recursion_depth + 1,
206                    predicate,
207                    &mut obligations,
208                );
209                obligations.push(Obligation::with_depth(
210                    self.tcx(),
211                    obligation.cause.clone(),
212                    obligation.recursion_depth + 1,
213                    obligation.param_env,
214                    normalized,
215                ));
216            }
217        }
218
219        Ok(obligations)
220    }
221
222    fn confirm_param_candidate(
223        &mut self,
224        obligation: &PolyTraitObligation<'tcx>,
225        param: ty::PolyTraitRef<'tcx>,
226    ) -> PredicateObligations<'tcx> {
227        debug!(?obligation, ?param, "confirm_param_candidate");
228
229        let param = util::lazily_elaborate_sizedness_candidate(
230            self.infcx,
231            obligation,
232            param.upcast(self.infcx.tcx),
233        )
234        .map_bound(|p| p.trait_ref);
235
236        // During evaluation, we already checked that this
237        // where-clause trait-ref could be unified with the obligation
238        // trait-ref. Repeat that unification now without any
239        // transactional boundary; it should not fail.
240        match self.match_where_clause_trait_ref(obligation, param) {
241            Ok(obligations) => obligations,
242            Err(()) => {
243                bug!(
244                    "Where clause `{:?}` was applicable to `{:?}` but now is not",
245                    param,
246                    obligation
247                );
248            }
249        }
250    }
251
252    #[instrument(level = "debug", skip(self), ret)]
253    fn confirm_builtin_candidate(
254        &mut self,
255        obligation: &PolyTraitObligation<'tcx>,
256    ) -> PredicateObligations<'tcx> {
257        debug!(?obligation, "confirm_builtin_candidate");
258        let tcx = self.tcx();
259        let trait_def = obligation.predicate.def_id();
260        let self_ty = self.infcx.shallow_resolve(
261            self.infcx.enter_forall_and_leak_universe(obligation.predicate.self_ty()),
262        );
263        let types = match tcx.as_lang_item(trait_def) {
264            Some(LangItem::Sized) => self.sizedness_conditions(self_ty, SizedTraitKind::Sized),
265            Some(LangItem::MetaSized) => {
266                self.sizedness_conditions(self_ty, SizedTraitKind::MetaSized)
267            }
268            Some(LangItem::PointeeSized) => {
269                bug!("`PointeeSized` is removing during lowering");
270            }
271            Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(self_ty),
272            Some(LangItem::FusedIterator) => {
273                if self.coroutine_is_gen(self_ty) {
274                    ty::Binder::dummy(vec![])
275                } else {
276                    unreachable!("tried to assemble `FusedIterator` for non-gen coroutine");
277                }
278            }
279            Some(
280                LangItem::Destruct
281                | LangItem::DiscriminantKind
282                | LangItem::FnPtrTrait
283                | LangItem::PointeeTrait
284                | LangItem::Tuple
285                | LangItem::Unpin,
286            ) => ty::Binder::dummy(vec![]),
287            other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
288        };
289        let types = self.infcx.enter_forall_and_leak_universe(types);
290
291        let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
292        self.collect_predicates_for_types(
293            obligation.param_env,
294            cause,
295            obligation.recursion_depth + 1,
296            trait_def,
297            types,
298        )
299    }
300
301    #[instrument(level = "debug", skip(self))]
302    fn confirm_transmutability_candidate(
303        &mut self,
304        obligation: &PolyTraitObligation<'tcx>,
305    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
306        use rustc_transmute::{Answer, Assume, Condition};
307
308        /// Flatten the `Condition` tree into a conjunction of obligations.
309        #[instrument(level = "debug", skip(tcx, obligation))]
310        fn flatten_answer_tree<'tcx>(
311            tcx: TyCtxt<'tcx>,
312            obligation: &PolyTraitObligation<'tcx>,
313            cond: Condition<Region<'tcx>, Ty<'tcx>>,
314            assume: Assume,
315        ) -> PredicateObligations<'tcx> {
316            match cond {
317                // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll`
318                // Not possible until the trait solver supports disjunctions of obligations
319                Condition::IfAll(conds) | Condition::IfAny(conds) => conds
320                    .into_iter()
321                    .flat_map(|cond| flatten_answer_tree(tcx, obligation, cond, assume))
322                    .collect(),
323                Condition::Immutable { ty } => {
324                    let trait_ref = ty::TraitRef::new(
325                        tcx,
326                        tcx.require_lang_item(LangItem::Freeze, obligation.cause.span),
327                        [ty::GenericArg::from(ty)],
328                    );
329                    thin_vec![Obligation::with_depth(
330                        tcx,
331                        obligation.cause.clone(),
332                        obligation.recursion_depth + 1,
333                        obligation.param_env,
334                        trait_ref,
335                    )]
336                }
337                Condition::Outlives { long, short } => {
338                    let outlives = ty::OutlivesPredicate(long, short);
339                    thin_vec![Obligation::with_depth(
340                        tcx,
341                        obligation.cause.clone(),
342                        obligation.recursion_depth + 1,
343                        obligation.param_env,
344                        outlives,
345                    )]
346                }
347                Condition::Transmutable { src, dst } => {
348                    let transmute_trait = obligation.predicate.def_id();
349                    let assume = obligation.predicate.skip_binder().trait_ref.args.const_at(2);
350                    let trait_ref = ty::TraitRef::new(
351                        tcx,
352                        transmute_trait,
353                        [
354                            ty::GenericArg::from(dst),
355                            ty::GenericArg::from(src),
356                            ty::GenericArg::from(assume),
357                        ],
358                    );
359                    thin_vec![Obligation::with_depth(
360                        tcx,
361                        obligation.cause.clone(),
362                        obligation.recursion_depth + 1,
363                        obligation.param_env,
364                        trait_ref,
365                    )]
366                }
367            }
368        }
369
370        let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
371
372        let mut assume = predicate.trait_ref.args.const_at(2);
373        if self.tcx().features().generic_const_exprs() {
374            assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env)
375        }
376        let Some(assume) = rustc_transmute::Assume::from_const(self.infcx.tcx, assume) else {
377            return Err(SelectionError::Unimplemented);
378        };
379
380        let dst = predicate.trait_ref.args.type_at(0);
381        let src = predicate.trait_ref.args.type_at(1);
382
383        debug!(?src, ?dst);
384        let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx.tcx);
385        let maybe_transmutable =
386            transmute_env.is_transmutable(rustc_transmute::Types { dst, src }, assume);
387
388        let fully_flattened = match maybe_transmutable {
389            Answer::No(_) => Err(SelectionError::Unimplemented)?,
390            Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, cond, assume),
391            Answer::Yes => PredicateObligations::new(),
392        };
393
394        debug!(?fully_flattened);
395        Ok(fully_flattened)
396    }
397
398    /// This handles the case where an `auto trait Foo` impl is being used.
399    /// The idea is that the impl applies to `X : Foo` if the following conditions are met:
400    ///
401    /// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
402    /// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds.
403    fn confirm_auto_impl_candidate(
404        &mut self,
405        obligation: &PolyTraitObligation<'tcx>,
406    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
407        ensure_sufficient_stack(|| {
408            assert_eq!(obligation.predicate.polarity(), ty::PredicatePolarity::Positive);
409
410            let self_ty =
411                obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty));
412            let self_ty = self.infcx.enter_forall_and_leak_universe(self_ty);
413
414            let constituents = self.constituent_types_for_auto_trait(self_ty)?;
415            let constituents = self.infcx.enter_forall_and_leak_universe(constituents);
416
417            let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
418            let mut obligations = self.collect_predicates_for_types(
419                obligation.param_env,
420                cause.clone(),
421                obligation.recursion_depth + 1,
422                obligation.predicate.def_id(),
423                constituents.types,
424            );
425
426            // FIXME(coroutine_clone): We could uplift this into `collect_predicates_for_types`
427            // and do this for `Copy`/`Clone` too, but that's feature-gated so it doesn't really
428            // matter yet.
429            for assumption in constituents.assumptions {
430                let assumption = normalize_with_depth_to(
431                    self,
432                    obligation.param_env,
433                    cause.clone(),
434                    obligation.recursion_depth + 1,
435                    assumption,
436                    &mut obligations,
437                );
438                self.infcx.register_region_assumption(assumption);
439            }
440
441            Ok(obligations)
442        })
443    }
444
445    fn confirm_impl_candidate(
446        &mut self,
447        obligation: &PolyTraitObligation<'tcx>,
448        impl_def_id: DefId,
449    ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
450        debug!(?obligation, ?impl_def_id, "confirm_impl_candidate");
451
452        // First, create the generic parameters by matching the impl again,
453        // this time not in a probe.
454        let args = self.rematch_impl(impl_def_id, obligation);
455        debug!(?args, "impl args");
456        ensure_sufficient_stack(|| {
457            self.vtable_impl(
458                impl_def_id,
459                args,
460                &obligation.cause,
461                obligation.recursion_depth + 1,
462                obligation.param_env,
463                obligation.predicate,
464            )
465        })
466    }
467
468    fn vtable_impl(
469        &mut self,
470        impl_def_id: DefId,
471        args: Normalized<'tcx, GenericArgsRef<'tcx>>,
472        cause: &ObligationCause<'tcx>,
473        recursion_depth: usize,
474        param_env: ty::ParamEnv<'tcx>,
475        parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
476    ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
477        debug!(?impl_def_id, ?args, ?recursion_depth, "vtable_impl");
478
479        let mut impl_obligations = self.impl_or_trait_obligations(
480            cause,
481            recursion_depth,
482            param_env,
483            impl_def_id,
484            args.value,
485            parent_trait_pred,
486        );
487
488        debug!(?impl_obligations, "vtable_impl");
489
490        // Because of RFC447, the impl-trait-ref and obligations
491        // are sufficient to determine the impl args, without
492        // relying on projections in the impl-trait-ref.
493        //
494        // e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
495        impl_obligations.extend(args.obligations);
496
497        ImplSourceUserDefinedData { impl_def_id, args: args.value, nested: impl_obligations }
498    }
499
500    fn confirm_object_candidate(
501        &mut self,
502        obligation: &PolyTraitObligation<'tcx>,
503        index: usize,
504    ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
505        let tcx = self.tcx();
506        debug!(?obligation, ?index, "confirm_object_candidate");
507
508        let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
509        let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
510        let ty::Dynamic(data, ..) = *self_ty.kind() else {
511            span_bug!(obligation.cause.span, "object candidate with non-object");
512        };
513
514        let object_trait_ref = data.principal().unwrap_or_else(|| {
515            span_bug!(obligation.cause.span, "object candidate with no principal")
516        });
517        let object_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
518            obligation.cause.span,
519            BoundRegionConversionTime::HigherRankedType,
520            object_trait_ref,
521        );
522        let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty);
523
524        let mut nested = PredicateObligations::new();
525
526        let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref));
527        let unnormalized_upcast_trait_ref =
528            supertraits.nth(index).expect("supertraits iterator no longer has as many elements");
529
530        let upcast_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
531            obligation.cause.span,
532            BoundRegionConversionTime::HigherRankedType,
533            unnormalized_upcast_trait_ref,
534        );
535        let upcast_trait_ref = normalize_with_depth_to(
536            self,
537            obligation.param_env,
538            obligation.cause.clone(),
539            obligation.recursion_depth + 1,
540            upcast_trait_ref,
541            &mut nested,
542        );
543
544        nested.extend(
545            self.infcx
546                .at(&obligation.cause, obligation.param_env)
547                .eq(DefineOpaqueTypes::No, trait_predicate.trait_ref, upcast_trait_ref)
548                .map(|InferOk { obligations, .. }| obligations)
549                .map_err(|_| SelectionError::Unimplemented)?,
550        );
551
552        // Check supertraits hold. This is so that their associated type bounds
553        // will be checked in the code below.
554        for (supertrait, _) in tcx
555            .explicit_super_predicates_of(trait_predicate.def_id())
556            .iter_instantiated_copied(tcx, trait_predicate.trait_ref.args)
557        {
558            let normalized_supertrait = normalize_with_depth_to(
559                self,
560                obligation.param_env,
561                obligation.cause.clone(),
562                obligation.recursion_depth + 1,
563                supertrait,
564                &mut nested,
565            );
566            nested.push(obligation.with(tcx, normalized_supertrait));
567        }
568
569        let assoc_types: Vec<_> = tcx
570            .associated_items(trait_predicate.def_id())
571            .in_definition_order()
572            // Associated types that require `Self: Sized` do not show up in the built-in
573            // implementation of `Trait for dyn Trait`, and can be dropped here.
574            .filter(|item| !tcx.generics_require_sized_self(item.def_id))
575            .filter_map(|item| if item.is_type() { Some(item.def_id) } else { None })
576            .collect();
577
578        for assoc_type in assoc_types {
579            let defs: &ty::Generics = tcx.generics_of(assoc_type);
580
581            if !defs.own_params.is_empty() {
582                tcx.dcx().span_delayed_bug(
583                    obligation.cause.span,
584                    "GATs in trait object shouldn't have been considered",
585                );
586                return Err(SelectionError::TraitDynIncompatible(trait_predicate.trait_ref.def_id));
587            }
588
589            // This maybe belongs in wf, but that can't (doesn't) handle
590            // higher-ranked things.
591            // Prevent, e.g., `dyn Iterator<Item = str>`.
592            for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
593                let normalized_bound = normalize_with_depth_to(
594                    self,
595                    obligation.param_env,
596                    obligation.cause.clone(),
597                    obligation.recursion_depth + 1,
598                    bound.instantiate(tcx, trait_predicate.trait_ref.args),
599                    &mut nested,
600                );
601                nested.push(obligation.with(tcx, normalized_bound));
602            }
603        }
604
605        debug!(?nested, "object nested obligations");
606
607        Ok(ImplSource::Builtin(BuiltinImplSource::Object(index), nested))
608    }
609
610    fn confirm_fn_pointer_candidate(
611        &mut self,
612        obligation: &PolyTraitObligation<'tcx>,
613    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
614        debug!(?obligation, "confirm_fn_pointer_candidate");
615        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
616        let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
617
618        let tcx = self.tcx();
619        let sig = self_ty.fn_sig(tcx);
620        let trait_ref = closure_trait_ref_and_return_type(
621            tcx,
622            obligation.predicate.def_id(),
623            self_ty,
624            sig,
625            util::TupleArgumentsFlag::Yes,
626        )
627        .map_bound(|(trait_ref, _)| trait_ref);
628
629        let mut nested =
630            self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?;
631        let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
632
633        // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
634        let output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
635        let output_ty = normalize_with_depth_to(
636            self,
637            obligation.param_env,
638            cause.clone(),
639            obligation.recursion_depth,
640            output_ty,
641            &mut nested,
642        );
643        let tr = ty::TraitRef::new(
644            self.tcx(),
645            self.tcx().require_lang_item(LangItem::Sized, cause.span),
646            [output_ty],
647        );
648        nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
649
650        Ok(nested)
651    }
652
653    fn confirm_trait_alias_candidate(
654        &mut self,
655        obligation: &PolyTraitObligation<'tcx>,
656    ) -> PredicateObligations<'tcx> {
657        debug!(?obligation, "confirm_trait_alias_candidate");
658
659        let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
660        let trait_ref = predicate.trait_ref;
661        let trait_def_id = trait_ref.def_id;
662        let args = trait_ref.args;
663
664        let trait_obligations = self.impl_or_trait_obligations(
665            &obligation.cause,
666            obligation.recursion_depth,
667            obligation.param_env,
668            trait_def_id,
669            args,
670            obligation.predicate,
671        );
672
673        debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
674
675        trait_obligations
676    }
677
678    fn confirm_coroutine_candidate(
679        &mut self,
680        obligation: &PolyTraitObligation<'tcx>,
681    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
682        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
683        let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
684        let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
685            bug!("closure candidate for non-closure {:?}", obligation);
686        };
687
688        debug!(?obligation, ?coroutine_def_id, ?args, "confirm_coroutine_candidate");
689
690        let coroutine_sig = args.as_coroutine().sig();
691
692        let (trait_ref, _, _) = super::util::coroutine_trait_ref_and_outputs(
693            self.tcx(),
694            obligation.predicate.def_id(),
695            self_ty,
696            coroutine_sig,
697        );
698
699        let nested = self.equate_trait_refs(
700            obligation.with(self.tcx(), placeholder_predicate),
701            ty::Binder::dummy(trait_ref),
702        )?;
703        debug!(?trait_ref, ?nested, "coroutine candidate obligations");
704
705        Ok(nested)
706    }
707
708    fn confirm_future_candidate(
709        &mut self,
710        obligation: &PolyTraitObligation<'tcx>,
711    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
712        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
713        let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
714        let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
715            bug!("closure candidate for non-closure {:?}", obligation);
716        };
717
718        debug!(?obligation, ?coroutine_def_id, ?args, "confirm_future_candidate");
719
720        let coroutine_sig = args.as_coroutine().sig();
721
722        let (trait_ref, _) = super::util::future_trait_ref_and_outputs(
723            self.tcx(),
724            obligation.predicate.def_id(),
725            self_ty,
726            coroutine_sig,
727        );
728
729        let nested = self.equate_trait_refs(
730            obligation.with(self.tcx(), placeholder_predicate),
731            ty::Binder::dummy(trait_ref),
732        )?;
733        debug!(?trait_ref, ?nested, "future candidate obligations");
734
735        Ok(nested)
736    }
737
738    fn confirm_iterator_candidate(
739        &mut self,
740        obligation: &PolyTraitObligation<'tcx>,
741    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
742        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
743        let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
744        let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
745            bug!("closure candidate for non-closure {:?}", obligation);
746        };
747
748        debug!(?obligation, ?coroutine_def_id, ?args, "confirm_iterator_candidate");
749
750        let gen_sig = args.as_coroutine().sig();
751
752        let (trait_ref, _) = super::util::iterator_trait_ref_and_outputs(
753            self.tcx(),
754            obligation.predicate.def_id(),
755            self_ty,
756            gen_sig,
757        );
758
759        let nested = self.equate_trait_refs(
760            obligation.with(self.tcx(), placeholder_predicate),
761            ty::Binder::dummy(trait_ref),
762        )?;
763        debug!(?trait_ref, ?nested, "iterator candidate obligations");
764
765        Ok(nested)
766    }
767
768    fn confirm_async_iterator_candidate(
769        &mut self,
770        obligation: &PolyTraitObligation<'tcx>,
771    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
772        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
773        let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
774        let ty::Coroutine(coroutine_def_id, args) = *self_ty.kind() else {
775            bug!("closure candidate for non-closure {:?}", obligation);
776        };
777
778        debug!(?obligation, ?coroutine_def_id, ?args, "confirm_async_iterator_candidate");
779
780        let gen_sig = args.as_coroutine().sig();
781
782        let (trait_ref, _) = super::util::async_iterator_trait_ref_and_outputs(
783            self.tcx(),
784            obligation.predicate.def_id(),
785            self_ty,
786            gen_sig,
787        );
788
789        let nested = self.equate_trait_refs(
790            obligation.with(self.tcx(), placeholder_predicate),
791            ty::Binder::dummy(trait_ref),
792        )?;
793        debug!(?trait_ref, ?nested, "iterator candidate obligations");
794
795        Ok(nested)
796    }
797
798    #[instrument(skip(self), level = "debug")]
799    fn confirm_closure_candidate(
800        &mut self,
801        obligation: &PolyTraitObligation<'tcx>,
802    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
803        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
804        let self_ty: Ty<'_> = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
805
806        let trait_ref = match *self_ty.kind() {
807            ty::Closure(..) => {
808                self.closure_trait_ref_unnormalized(self_ty, obligation.predicate.def_id())
809            }
810            ty::CoroutineClosure(_, args) => {
811                args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
812                    ty::TraitRef::new(
813                        self.tcx(),
814                        obligation.predicate.def_id(),
815                        [self_ty, sig.tupled_inputs_ty],
816                    )
817                })
818            }
819            _ => {
820                bug!("closure candidate for non-closure {:?}", obligation);
821            }
822        };
823
824        self.equate_trait_refs(obligation.with(self.tcx(), placeholder_predicate), trait_ref)
825    }
826
827    #[instrument(skip(self), level = "debug")]
828    fn confirm_async_closure_candidate(
829        &mut self,
830        obligation: &PolyTraitObligation<'tcx>,
831    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
832        let placeholder_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
833        let self_ty = self.infcx.shallow_resolve(placeholder_predicate.self_ty());
834
835        let tcx = self.tcx();
836
837        let mut nested = PredicateObligations::new();
838        let (trait_ref, kind_ty) = match *self_ty.kind() {
839            ty::CoroutineClosure(_, args) => {
840                let args = args.as_coroutine_closure();
841                let trait_ref = args.coroutine_closure_sig().map_bound(|sig| {
842                    ty::TraitRef::new(
843                        self.tcx(),
844                        obligation.predicate.def_id(),
845                        [self_ty, sig.tupled_inputs_ty],
846                    )
847                });
848
849                // Note that unlike below, we don't need to check `Future + Sized` for
850                // the output coroutine because they are `Future + Sized` by construction.
851
852                (trait_ref, args.kind_ty())
853            }
854            ty::FnDef(..) | ty::FnPtr(..) => {
855                let sig = self_ty.fn_sig(tcx);
856                let trait_ref = sig.map_bound(|sig| {
857                    ty::TraitRef::new(
858                        self.tcx(),
859                        obligation.predicate.def_id(),
860                        [self_ty, Ty::new_tup(tcx, sig.inputs())],
861                    )
862                });
863
864                // We must additionally check that the return type impls `Future + Sized`.
865                let future_trait_def_id =
866                    tcx.require_lang_item(LangItem::Future, obligation.cause.span);
867                nested.push(obligation.with(
868                    tcx,
869                    sig.output().map_bound(|output_ty| {
870                        ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
871                    }),
872                ));
873                let sized_trait_def_id =
874                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span);
875                nested.push(obligation.with(
876                    tcx,
877                    sig.output().map_bound(|output_ty| {
878                        ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
879                    }),
880                ));
881
882                (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
883            }
884            ty::Closure(_, args) => {
885                let args = args.as_closure();
886                let sig = args.sig();
887                let trait_ref = sig.map_bound(|sig| {
888                    ty::TraitRef::new(
889                        self.tcx(),
890                        obligation.predicate.def_id(),
891                        [self_ty, sig.inputs()[0]],
892                    )
893                });
894
895                // We must additionally check that the return type impls `Future + Sized`.
896                let future_trait_def_id =
897                    tcx.require_lang_item(LangItem::Future, obligation.cause.span);
898                let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
899                nested.push(obligation.with(
900                    tcx,
901                    ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
902                ));
903                let sized_trait_def_id =
904                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span);
905                nested.push(obligation.with(
906                    tcx,
907                    sig.output().map_bound(|output_ty| {
908                        ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
909                    }),
910                ));
911
912                (trait_ref, args.kind_ty())
913            }
914            _ => bug!("expected callable type for AsyncFn candidate"),
915        };
916
917        nested.extend(
918            self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?,
919        );
920
921        let goal_kind =
922            self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
923
924        // If we have not yet determined the `ClosureKind` of the closure or coroutine-closure,
925        // then additionally register an `AsyncFnKindHelper` goal which will fail if the kind
926        // is constrained to an insufficient type later on.
927        if let Some(closure_kind) = self.infcx.shallow_resolve(kind_ty).to_opt_closure_kind() {
928            if !closure_kind.extends(goal_kind) {
929                return Err(SelectionError::Unimplemented);
930            }
931        } else {
932            nested.push(Obligation::new(
933                self.tcx(),
934                obligation.derived_cause(ObligationCauseCode::BuiltinDerived),
935                obligation.param_env,
936                ty::TraitRef::new(
937                    self.tcx(),
938                    self.tcx()
939                        .require_lang_item(LangItem::AsyncFnKindHelper, obligation.cause.span),
940                    [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
941                ),
942            ));
943        }
944
945        Ok(nested)
946    }
947
948    /// In the case of closure types and fn pointers,
949    /// we currently treat the input type parameters on the trait as
950    /// outputs. This means that when we have a match we have only
951    /// considered the self type, so we have to go back and make sure
952    /// to relate the argument types too. This is kind of wrong, but
953    /// since we control the full set of impls, also not that wrong,
954    /// and it DOES yield better error messages (since we don't report
955    /// errors as if there is no applicable impl, but rather report
956    /// errors are about mismatched argument types.
957    ///
958    /// Here is an example. Imagine we have a closure expression
959    /// and we desugared it so that the type of the expression is
960    /// `Closure`, and `Closure` expects `i32` as argument. Then it
961    /// is "as if" the compiler generated this impl:
962    /// ```ignore (illustrative)
963    /// impl Fn(i32) for Closure { ... }
964    /// ```
965    /// Now imagine our obligation is `Closure: Fn(usize)`. So far
966    /// we have matched the self type `Closure`. At this point we'll
967    /// compare the `i32` to `usize` and generate an error.
968    ///
969    /// Note that this checking occurs *after* the impl has selected,
970    /// because these output type parameters should not affect the
971    /// selection of the impl. Therefore, if there is a mismatch, we
972    /// report an error to the user.
973    #[instrument(skip(self), level = "trace")]
974    fn equate_trait_refs(
975        &mut self,
976        obligation: TraitObligation<'tcx>,
977        found_trait_ref: ty::PolyTraitRef<'tcx>,
978    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
979        let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
980            obligation.cause.span,
981            BoundRegionConversionTime::HigherRankedType,
982            found_trait_ref,
983        );
984        // Normalize the obligation and expected trait refs together, because why not
985        let Normalized { obligations: nested, value: (obligation_trait_ref, found_trait_ref) } =
986            ensure_sufficient_stack(|| {
987                normalize_with_depth(
988                    self,
989                    obligation.param_env,
990                    obligation.cause.clone(),
991                    obligation.recursion_depth + 1,
992                    (obligation.predicate.trait_ref, found_trait_ref),
993                )
994            });
995
996        // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
997        self.infcx
998            .at(&obligation.cause, obligation.param_env)
999            .eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref)
1000            .map(|InferOk { mut obligations, .. }| {
1001                obligations.extend(nested);
1002                obligations
1003            })
1004            .map_err(|terr| {
1005                SelectionError::SignatureMismatch(Box::new(SignatureMismatchData {
1006                    expected_trait_ref: obligation_trait_ref,
1007                    found_trait_ref,
1008                    terr,
1009                }))
1010            })
1011    }
1012
1013    fn confirm_trait_upcasting_unsize_candidate(
1014        &mut self,
1015        obligation: &PolyTraitObligation<'tcx>,
1016        idx: usize,
1017    ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1018        let tcx = self.tcx();
1019
1020        // `assemble_candidates_for_unsizing` should ensure there are no late-bound
1021        // regions here. See the comment there for more details.
1022        let predicate = obligation.predicate.no_bound_vars().unwrap();
1023        let a_ty = self.infcx.shallow_resolve(predicate.self_ty());
1024        let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1));
1025
1026        let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else {
1027            bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1028        };
1029        let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
1030            bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1031        };
1032
1033        let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty);
1034        let unnormalized_upcast_principal =
1035            util::supertraits(tcx, source_principal).nth(idx).unwrap();
1036
1037        let nested = self
1038            .match_upcast_principal(
1039                obligation,
1040                unnormalized_upcast_principal,
1041                a_data,
1042                b_data,
1043                a_region,
1044                b_region,
1045            )?
1046            .expect("did not expect ambiguity during confirmation");
1047
1048        Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting(idx), nested))
1049    }
1050
1051    fn confirm_builtin_unsize_candidate(
1052        &mut self,
1053        obligation: &PolyTraitObligation<'tcx>,
1054    ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1055        let tcx = self.tcx();
1056
1057        // `assemble_candidates_for_unsizing` should ensure there are no late-bound
1058        // regions here. See the comment there for more details.
1059        let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
1060        let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
1061        let target = self.infcx.shallow_resolve(target);
1062        debug!(?source, ?target, "confirm_builtin_unsize_candidate");
1063
1064        Ok(match (source.kind(), target.kind()) {
1065            // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
1066            (&ty::Dynamic(data_a, r_a, dyn_a), &ty::Dynamic(data_b, r_b, dyn_b))
1067                if dyn_a == dyn_b =>
1068            {
1069                // See `assemble_candidates_for_unsizing` for more info.
1070                // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
1071                let existential_predicates = if data_b.principal().is_some() {
1072                    tcx.mk_poly_existential_predicates_from_iter(
1073                        data_a
1074                            .principal()
1075                            .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
1076                            .into_iter()
1077                            .chain(
1078                                data_a
1079                                    .projection_bounds()
1080                                    .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
1081                            )
1082                            .chain(
1083                                data_b
1084                                    .auto_traits()
1085                                    .map(ty::ExistentialPredicate::AutoTrait)
1086                                    .map(ty::Binder::dummy),
1087                            ),
1088                    )
1089                } else {
1090                    // If we're unsizing to a dyn type that has no principal, then drop
1091                    // the principal and projections from the type. We use the auto traits
1092                    // from the RHS type since as we noted that we've checked for auto
1093                    // trait compatibility during unsizing.
1094                    tcx.mk_poly_existential_predicates_from_iter(
1095                        data_b
1096                            .auto_traits()
1097                            .map(ty::ExistentialPredicate::AutoTrait)
1098                            .map(ty::Binder::dummy),
1099                    )
1100                };
1101                let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
1102
1103                // Require that the traits involved in this upcast are **equal**;
1104                // only the **lifetime bound** is changed.
1105                let InferOk { mut obligations, .. } = self
1106                    .infcx
1107                    .at(&obligation.cause, obligation.param_env)
1108                    .sup(DefineOpaqueTypes::Yes, target, source_trait)
1109                    .map_err(|_| SelectionError::Unimplemented)?;
1110
1111                // Register one obligation for 'a: 'b.
1112                let outlives = ty::OutlivesPredicate(r_a, r_b);
1113                obligations.push(Obligation::with_depth(
1114                    tcx,
1115                    obligation.cause.clone(),
1116                    obligation.recursion_depth + 1,
1117                    obligation.param_env,
1118                    obligation.predicate.rebind(outlives),
1119                ));
1120
1121                ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1122            }
1123
1124            // `T` -> `dyn Trait`
1125            (_, &ty::Dynamic(data, r, ty::Dyn)) => {
1126                let mut object_dids = data.auto_traits().chain(data.principal_def_id());
1127                if let Some(did) = object_dids.find(|did| !tcx.is_dyn_compatible(*did)) {
1128                    return Err(SelectionError::TraitDynIncompatible(did));
1129                }
1130
1131                let predicate_to_obligation = |predicate| {
1132                    Obligation::with_depth(
1133                        tcx,
1134                        obligation.cause.clone(),
1135                        obligation.recursion_depth + 1,
1136                        obligation.param_env,
1137                        predicate,
1138                    )
1139                };
1140
1141                // Create obligations:
1142                //  - Casting `T` to `Trait`
1143                //  - For all the various builtin bounds attached to the object cast. (In other
1144                //  words, if the object type is `Foo + Send`, this would create an obligation for
1145                //  the `Send` check.)
1146                //  - Projection predicates
1147                let mut nested: PredicateObligations<'_> = data
1148                    .iter()
1149                    .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source)))
1150                    .collect();
1151
1152                // We can only make objects from sized types.
1153                let tr = ty::TraitRef::new(
1154                    tcx,
1155                    tcx.require_lang_item(LangItem::Sized, obligation.cause.span),
1156                    [source],
1157                );
1158                nested.push(predicate_to_obligation(tr.upcast(tcx)));
1159
1160                // If the type is `Foo + 'a`, ensure that the type
1161                // being cast to `Foo + 'a` outlives `'a`:
1162                let outlives = ty::OutlivesPredicate(source, r);
1163                nested.push(predicate_to_obligation(
1164                    ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
1165                ));
1166
1167                ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1168            }
1169
1170            // `[T; n]` -> `[T]`
1171            (&ty::Array(a, _), &ty::Slice(b)) => {
1172                let InferOk { obligations, .. } = self
1173                    .infcx
1174                    .at(&obligation.cause, obligation.param_env)
1175                    .eq(DefineOpaqueTypes::Yes, b, a)
1176                    .map_err(|_| SelectionError::Unimplemented)?;
1177
1178                ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1179            }
1180
1181            // `Struct<T>` -> `Struct<U>`
1182            (&ty::Adt(def, args_a), &ty::Adt(_, args_b)) => {
1183                let unsizing_params = tcx.unsizing_params_for_adt(def.did());
1184                if unsizing_params.is_empty() {
1185                    return Err(SelectionError::Unimplemented);
1186                }
1187
1188                let tail_field = def.non_enum_variant().tail();
1189                let tail_field_ty = tcx.type_of(tail_field.did);
1190
1191                let mut nested = PredicateObligations::new();
1192
1193                // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
1194                // normalizing in the process, since `type_of` returns something directly from
1195                // HIR ty lowering (which means it's un-normalized).
1196                let source_tail = normalize_with_depth_to(
1197                    self,
1198                    obligation.param_env,
1199                    obligation.cause.clone(),
1200                    obligation.recursion_depth + 1,
1201                    tail_field_ty.instantiate(tcx, args_a),
1202                    &mut nested,
1203                );
1204                let target_tail = normalize_with_depth_to(
1205                    self,
1206                    obligation.param_env,
1207                    obligation.cause.clone(),
1208                    obligation.recursion_depth + 1,
1209                    tail_field_ty.instantiate(tcx, args_b),
1210                    &mut nested,
1211                );
1212
1213                // Check that the source struct with the target's
1214                // unsizing parameters is equal to the target.
1215                let args =
1216                    tcx.mk_args_from_iter(args_a.iter().enumerate().map(|(i, k)| {
1217                        if unsizing_params.contains(i as u32) { args_b[i] } else { k }
1218                    }));
1219                let new_struct = Ty::new_adt(tcx, def, args);
1220                let InferOk { obligations, .. } = self
1221                    .infcx
1222                    .at(&obligation.cause, obligation.param_env)
1223                    .eq(DefineOpaqueTypes::Yes, target, new_struct)
1224                    .map_err(|_| SelectionError::Unimplemented)?;
1225                nested.extend(obligations);
1226
1227                // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate.
1228                let tail_unsize_obligation = obligation.with(
1229                    tcx,
1230                    ty::TraitRef::new(
1231                        tcx,
1232                        obligation.predicate.def_id(),
1233                        [source_tail, target_tail],
1234                    ),
1235                );
1236                nested.push(tail_unsize_obligation);
1237
1238                ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1239            }
1240
1241            _ => bug!("source: {source}, target: {target}"),
1242        })
1243    }
1244
1245    fn confirm_bikeshed_guaranteed_no_drop_candidate(
1246        &mut self,
1247        obligation: &PolyTraitObligation<'tcx>,
1248    ) -> ImplSource<'tcx, PredicateObligation<'tcx>> {
1249        let mut obligations = thin_vec![];
1250
1251        let tcx = self.tcx();
1252        let self_ty = obligation.predicate.self_ty();
1253        match *self_ty.skip_binder().kind() {
1254            // `&mut T` and `&T` always implement `BikeshedGuaranteedNoDrop`.
1255            ty::Ref(..) => {}
1256            // `ManuallyDrop<T>` always implements `BikeshedGuaranteedNoDrop`.
1257            ty::Adt(def, _) if def.is_manually_drop() => {}
1258            // Arrays and tuples implement `BikeshedGuaranteedNoDrop` only if
1259            // their constituent types implement `BikeshedGuaranteedNoDrop`.
1260            ty::Tuple(tys) => {
1261                obligations.extend(tys.iter().map(|elem_ty| {
1262                    obligation.with(
1263                        tcx,
1264                        self_ty.rebind(ty::TraitRef::new(
1265                            tcx,
1266                            obligation.predicate.def_id(),
1267                            [elem_ty],
1268                        )),
1269                    )
1270                }));
1271            }
1272            ty::Array(elem_ty, _) => {
1273                obligations.push(obligation.with(
1274                    tcx,
1275                    self_ty.rebind(ty::TraitRef::new(
1276                        tcx,
1277                        obligation.predicate.def_id(),
1278                        [elem_ty],
1279                    )),
1280                ));
1281            }
1282
1283            // All other types implement `BikeshedGuaranteedNoDrop` only if
1284            // they implement `Copy`. We could be smart here and short-circuit
1285            // some trivially `Copy`/`!Copy` types, but there's no benefit.
1286            ty::FnDef(..)
1287            | ty::FnPtr(..)
1288            | ty::Error(_)
1289            | ty::Uint(_)
1290            | ty::Int(_)
1291            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1292            | ty::Bool
1293            | ty::Float(_)
1294            | ty::Char
1295            | ty::RawPtr(..)
1296            | ty::Never
1297            | ty::Pat(..)
1298            | ty::Dynamic(..)
1299            | ty::Str
1300            | ty::Slice(_)
1301            | ty::Foreign(..)
1302            | ty::Adt(..)
1303            | ty::Alias(..)
1304            | ty::Param(_)
1305            | ty::Placeholder(..)
1306            | ty::Closure(..)
1307            | ty::CoroutineClosure(..)
1308            | ty::Coroutine(..)
1309            | ty::UnsafeBinder(_)
1310            | ty::CoroutineWitness(..)
1311            | ty::Bound(..) => {
1312                obligations.push(obligation.with(
1313                    tcx,
1314                    self_ty.map_bound(|ty| {
1315                        ty::TraitRef::new(
1316                            tcx,
1317                            tcx.require_lang_item(LangItem::Copy, obligation.cause.span),
1318                            [ty],
1319                        )
1320                    }),
1321                ));
1322            }
1323
1324            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1325                panic!("unexpected type `{self_ty:?}`")
1326            }
1327        }
1328
1329        ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1330    }
1331}