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