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