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, None),
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, Some(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 = tcx.require_lang_item(LangItem::Future, None);
881                nested.push(obligation.with(
882                    tcx,
883                    sig.output().map_bound(|output_ty| {
884                        ty::TraitRef::new(tcx, future_trait_def_id, [output_ty])
885                    }),
886                ));
887                let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
888                nested.push(obligation.with(
889                    tcx,
890                    sig.output().map_bound(|output_ty| {
891                        ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
892                    }),
893                ));
894
895                (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
896            }
897            ty::Closure(_, args) => {
898                let args = args.as_closure();
899                let sig = args.sig();
900                let trait_ref = sig.map_bound(|sig| {
901                    ty::TraitRef::new(
902                        self.tcx(),
903                        obligation.predicate.def_id(),
904                        [self_ty, sig.inputs()[0]],
905                    )
906                });
907
908                // We must additionally check that the return type impls `Future + Sized`.
909                let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None);
910                let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
911                nested.push(obligation.with(
912                    tcx,
913                    ty::TraitRef::new(tcx, future_trait_def_id, [placeholder_output_ty]),
914                ));
915                let sized_trait_def_id = tcx.require_lang_item(LangItem::Sized, None);
916                nested.push(obligation.with(
917                    tcx,
918                    sig.output().map_bound(|output_ty| {
919                        ty::TraitRef::new(tcx, sized_trait_def_id, [output_ty])
920                    }),
921                ));
922
923                (trait_ref, args.kind_ty())
924            }
925            _ => bug!("expected callable type for AsyncFn candidate"),
926        };
927
928        nested.extend(
929            self.equate_trait_refs(obligation.with(tcx, placeholder_predicate), trait_ref)?,
930        );
931
932        let goal_kind =
933            self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
934
935        // If we have not yet determiend the `ClosureKind` of the closure or coroutine-closure,
936        // then additionally register an `AsyncFnKindHelper` goal which will fail if the kind
937        // is constrained to an insufficient type later on.
938        if let Some(closure_kind) = self.infcx.shallow_resolve(kind_ty).to_opt_closure_kind() {
939            if !closure_kind.extends(goal_kind) {
940                return Err(SelectionError::Unimplemented);
941            }
942        } else {
943            nested.push(Obligation::new(
944                self.tcx(),
945                obligation.derived_cause(ObligationCauseCode::BuiltinDerived),
946                obligation.param_env,
947                ty::TraitRef::new(
948                    self.tcx(),
949                    self.tcx().require_lang_item(
950                        LangItem::AsyncFnKindHelper,
951                        Some(obligation.cause.span),
952                    ),
953                    [kind_ty, Ty::from_closure_kind(self.tcx(), goal_kind)],
954                ),
955            ));
956        }
957
958        Ok(nested)
959    }
960
961    /// In the case of closure types and fn pointers,
962    /// we currently treat the input type parameters on the trait as
963    /// outputs. This means that when we have a match we have only
964    /// considered the self type, so we have to go back and make sure
965    /// to relate the argument types too. This is kind of wrong, but
966    /// since we control the full set of impls, also not that wrong,
967    /// and it DOES yield better error messages (since we don't report
968    /// errors as if there is no applicable impl, but rather report
969    /// errors are about mismatched argument types.
970    ///
971    /// Here is an example. Imagine we have a closure expression
972    /// and we desugared it so that the type of the expression is
973    /// `Closure`, and `Closure` expects `i32` as argument. Then it
974    /// is "as if" the compiler generated this impl:
975    /// ```ignore (illustrative)
976    /// impl Fn(i32) for Closure { ... }
977    /// ```
978    /// Now imagine our obligation is `Closure: Fn(usize)`. So far
979    /// we have matched the self type `Closure`. At this point we'll
980    /// compare the `i32` to `usize` and generate an error.
981    ///
982    /// Note that this checking occurs *after* the impl has selected,
983    /// because these output type parameters should not affect the
984    /// selection of the impl. Therefore, if there is a mismatch, we
985    /// report an error to the user.
986    #[instrument(skip(self), level = "trace")]
987    fn equate_trait_refs(
988        &mut self,
989        obligation: TraitObligation<'tcx>,
990        found_trait_ref: ty::PolyTraitRef<'tcx>,
991    ) -> Result<PredicateObligations<'tcx>, SelectionError<'tcx>> {
992        let found_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
993            obligation.cause.span,
994            HigherRankedType,
995            found_trait_ref,
996        );
997        // Normalize the obligation and expected trait refs together, because why not
998        let Normalized { obligations: nested, value: (obligation_trait_ref, found_trait_ref) } =
999            ensure_sufficient_stack(|| {
1000                normalize_with_depth(
1001                    self,
1002                    obligation.param_env,
1003                    obligation.cause.clone(),
1004                    obligation.recursion_depth + 1,
1005                    (obligation.predicate.trait_ref, found_trait_ref),
1006                )
1007            });
1008
1009        // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
1010        self.infcx
1011            .at(&obligation.cause, obligation.param_env)
1012            .eq(DefineOpaqueTypes::Yes, obligation_trait_ref, found_trait_ref)
1013            .map(|InferOk { mut obligations, .. }| {
1014                obligations.extend(nested);
1015                obligations
1016            })
1017            .map_err(|terr| {
1018                SignatureMismatch(Box::new(SignatureMismatchData {
1019                    expected_trait_ref: obligation_trait_ref,
1020                    found_trait_ref,
1021                    terr,
1022                }))
1023            })
1024    }
1025
1026    fn confirm_trait_upcasting_unsize_candidate(
1027        &mut self,
1028        obligation: &PolyTraitObligation<'tcx>,
1029        idx: usize,
1030    ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1031        let tcx = self.tcx();
1032
1033        // `assemble_candidates_for_unsizing` should ensure there are no late-bound
1034        // regions here. See the comment there for more details.
1035        let predicate = obligation.predicate.no_bound_vars().unwrap();
1036        let a_ty = self.infcx.shallow_resolve(predicate.self_ty());
1037        let b_ty = self.infcx.shallow_resolve(predicate.trait_ref.args.type_at(1));
1038
1039        let ty::Dynamic(a_data, a_region, ty::Dyn) = *a_ty.kind() else {
1040            bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1041        };
1042        let ty::Dynamic(b_data, b_region, ty::Dyn) = *b_ty.kind() else {
1043            bug!("expected `dyn` type in `confirm_trait_upcasting_unsize_candidate`")
1044        };
1045
1046        let source_principal = a_data.principal().unwrap().with_self_ty(tcx, a_ty);
1047        let unnormalized_upcast_principal =
1048            util::supertraits(tcx, source_principal).nth(idx).unwrap();
1049
1050        let nested = self
1051            .match_upcast_principal(
1052                obligation,
1053                unnormalized_upcast_principal,
1054                a_data,
1055                b_data,
1056                a_region,
1057                b_region,
1058            )?
1059            .expect("did not expect ambiguity during confirmation");
1060
1061        Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting(idx), nested))
1062    }
1063
1064    fn confirm_builtin_unsize_candidate(
1065        &mut self,
1066        obligation: &PolyTraitObligation<'tcx>,
1067    ) -> Result<ImplSource<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1068        let tcx = self.tcx();
1069
1070        // `assemble_candidates_for_unsizing` should ensure there are no late-bound
1071        // regions here. See the comment there for more details.
1072        let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
1073        let target = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
1074        let target = self.infcx.shallow_resolve(target);
1075        debug!(?source, ?target, "confirm_builtin_unsize_candidate");
1076
1077        Ok(match (source.kind(), target.kind()) {
1078            // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
1079            (&ty::Dynamic(data_a, r_a, dyn_a), &ty::Dynamic(data_b, r_b, dyn_b))
1080                if dyn_a == dyn_b =>
1081            {
1082                // See `assemble_candidates_for_unsizing` for more info.
1083                // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
1084                let existential_predicates = if data_b.principal().is_some() {
1085                    tcx.mk_poly_existential_predicates_from_iter(
1086                        data_a
1087                            .principal()
1088                            .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
1089                            .into_iter()
1090                            .chain(
1091                                data_a
1092                                    .projection_bounds()
1093                                    .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
1094                            )
1095                            .chain(
1096                                data_b
1097                                    .auto_traits()
1098                                    .map(ty::ExistentialPredicate::AutoTrait)
1099                                    .map(ty::Binder::dummy),
1100                            ),
1101                    )
1102                } else {
1103                    // If we're unsizing to a dyn type that has no principal, then drop
1104                    // the principal and projections from the type. We use the auto traits
1105                    // from the RHS type since as we noted that we've checked for auto
1106                    // trait compatibility during unsizing.
1107                    tcx.mk_poly_existential_predicates_from_iter(
1108                        data_b
1109                            .auto_traits()
1110                            .map(ty::ExistentialPredicate::AutoTrait)
1111                            .map(ty::Binder::dummy),
1112                    )
1113                };
1114                let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
1115
1116                // Require that the traits involved in this upcast are **equal**;
1117                // only the **lifetime bound** is changed.
1118                let InferOk { mut obligations, .. } = self
1119                    .infcx
1120                    .at(&obligation.cause, obligation.param_env)
1121                    .sup(DefineOpaqueTypes::Yes, target, source_trait)
1122                    .map_err(|_| Unimplemented)?;
1123
1124                // Register one obligation for 'a: 'b.
1125                let outlives = ty::OutlivesPredicate(r_a, r_b);
1126                obligations.push(Obligation::with_depth(
1127                    tcx,
1128                    obligation.cause.clone(),
1129                    obligation.recursion_depth + 1,
1130                    obligation.param_env,
1131                    obligation.predicate.rebind(outlives),
1132                ));
1133
1134                ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1135            }
1136
1137            // `T` -> `dyn Trait`
1138            (_, &ty::Dynamic(data, r, ty::Dyn)) => {
1139                let mut object_dids = data.auto_traits().chain(data.principal_def_id());
1140                if let Some(did) = object_dids.find(|did| !tcx.is_dyn_compatible(*did)) {
1141                    return Err(TraitDynIncompatible(did));
1142                }
1143
1144                let predicate_to_obligation = |predicate| {
1145                    Obligation::with_depth(
1146                        tcx,
1147                        obligation.cause.clone(),
1148                        obligation.recursion_depth + 1,
1149                        obligation.param_env,
1150                        predicate,
1151                    )
1152                };
1153
1154                // Create obligations:
1155                //  - Casting `T` to `Trait`
1156                //  - For all the various builtin bounds attached to the object cast. (In other
1157                //  words, if the object type is `Foo + Send`, this would create an obligation for
1158                //  the `Send` check.)
1159                //  - Projection predicates
1160                let mut nested: PredicateObligations<'_> = data
1161                    .iter()
1162                    .map(|predicate| predicate_to_obligation(predicate.with_self_ty(tcx, source)))
1163                    .collect();
1164
1165                // We can only make objects from sized types.
1166                let tr = ty::TraitRef::new(
1167                    tcx,
1168                    tcx.require_lang_item(LangItem::Sized, Some(obligation.cause.span)),
1169                    [source],
1170                );
1171                nested.push(predicate_to_obligation(tr.upcast(tcx)));
1172
1173                // If the type is `Foo + 'a`, ensure that the type
1174                // being cast to `Foo + 'a` outlives `'a`:
1175                let outlives = ty::OutlivesPredicate(source, r);
1176                nested.push(predicate_to_obligation(
1177                    ty::ClauseKind::TypeOutlives(outlives).upcast(tcx),
1178                ));
1179
1180                // Require that all AFIT will return something that can be coerced into `dyn*`
1181                // -- a shim will be responsible for doing the actual coercion to `dyn*`.
1182                if let Some(principal) = data.principal() {
1183                    for supertrait in
1184                        elaborate::supertraits(tcx, principal.with_self_ty(tcx, source))
1185                    {
1186                        if tcx.is_trait_alias(supertrait.def_id()) {
1187                            continue;
1188                        }
1189
1190                        for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) {
1191                            if !tcx.is_impl_trait_in_trait(assoc_item) {
1192                                continue;
1193                            }
1194
1195                            // RPITITs with `Self: Sized` don't need to be checked.
1196                            if tcx.generics_require_sized_self(assoc_item) {
1197                                continue;
1198                            }
1199
1200                            let pointer_like_goal = pointer_like_goal_for_rpitit(
1201                                tcx,
1202                                supertrait,
1203                                assoc_item,
1204                                &obligation.cause,
1205                            );
1206
1207                            nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx)));
1208                        }
1209                    }
1210                }
1211
1212                ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1213            }
1214
1215            // `[T; n]` -> `[T]`
1216            (&ty::Array(a, _), &ty::Slice(b)) => {
1217                let InferOk { obligations, .. } = self
1218                    .infcx
1219                    .at(&obligation.cause, obligation.param_env)
1220                    .eq(DefineOpaqueTypes::Yes, b, a)
1221                    .map_err(|_| Unimplemented)?;
1222
1223                ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1224            }
1225
1226            // `Struct<T>` -> `Struct<U>`
1227            (&ty::Adt(def, args_a), &ty::Adt(_, args_b)) => {
1228                let unsizing_params = tcx.unsizing_params_for_adt(def.did());
1229                if unsizing_params.is_empty() {
1230                    return Err(Unimplemented);
1231                }
1232
1233                let tail_field = def.non_enum_variant().tail();
1234                let tail_field_ty = tcx.type_of(tail_field.did);
1235
1236                let mut nested = PredicateObligations::new();
1237
1238                // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
1239                // normalizing in the process, since `type_of` returns something directly from
1240                // HIR ty lowering (which means it's un-normalized).
1241                let source_tail = normalize_with_depth_to(
1242                    self,
1243                    obligation.param_env,
1244                    obligation.cause.clone(),
1245                    obligation.recursion_depth + 1,
1246                    tail_field_ty.instantiate(tcx, args_a),
1247                    &mut nested,
1248                );
1249                let target_tail = normalize_with_depth_to(
1250                    self,
1251                    obligation.param_env,
1252                    obligation.cause.clone(),
1253                    obligation.recursion_depth + 1,
1254                    tail_field_ty.instantiate(tcx, args_b),
1255                    &mut nested,
1256                );
1257
1258                // Check that the source struct with the target's
1259                // unsizing parameters is equal to the target.
1260                let args =
1261                    tcx.mk_args_from_iter(args_a.iter().enumerate().map(|(i, k)| {
1262                        if unsizing_params.contains(i as u32) { args_b[i] } else { k }
1263                    }));
1264                let new_struct = Ty::new_adt(tcx, def, args);
1265                let InferOk { obligations, .. } = self
1266                    .infcx
1267                    .at(&obligation.cause, obligation.param_env)
1268                    .eq(DefineOpaqueTypes::Yes, target, new_struct)
1269                    .map_err(|_| Unimplemented)?;
1270                nested.extend(obligations);
1271
1272                // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate.
1273                let tail_unsize_obligation = obligation.with(
1274                    tcx,
1275                    ty::TraitRef::new(
1276                        tcx,
1277                        obligation.predicate.def_id(),
1278                        [source_tail, target_tail],
1279                    ),
1280                );
1281                nested.push(tail_unsize_obligation);
1282
1283                ImplSource::Builtin(BuiltinImplSource::Misc, nested)
1284            }
1285
1286            _ => bug!("source: {source}, target: {target}"),
1287        })
1288    }
1289
1290    fn confirm_bikeshed_guaranteed_no_drop_candidate(
1291        &mut self,
1292        obligation: &PolyTraitObligation<'tcx>,
1293    ) -> ImplSource<'tcx, PredicateObligation<'tcx>> {
1294        let mut obligations = thin_vec![];
1295
1296        let tcx = self.tcx();
1297        let self_ty = obligation.predicate.self_ty();
1298        match *self_ty.skip_binder().kind() {
1299            // `&mut T` and `&T` always implement `BikeshedGuaranteedNoDrop`.
1300            ty::Ref(..) => {}
1301            // `ManuallyDrop<T>` always implements `BikeshedGuaranteedNoDrop`.
1302            ty::Adt(def, _) if def.is_manually_drop() => {}
1303            // Arrays and tuples implement `BikeshedGuaranteedNoDrop` only if
1304            // their constituent types implement `BikeshedGuaranteedNoDrop`.
1305            ty::Tuple(tys) => {
1306                obligations.extend(tys.iter().map(|elem_ty| {
1307                    obligation.with(
1308                        tcx,
1309                        self_ty.rebind(ty::TraitRef::new(
1310                            tcx,
1311                            obligation.predicate.def_id(),
1312                            [elem_ty],
1313                        )),
1314                    )
1315                }));
1316            }
1317            ty::Array(elem_ty, _) => {
1318                obligations.push(obligation.with(
1319                    tcx,
1320                    self_ty.rebind(ty::TraitRef::new(
1321                        tcx,
1322                        obligation.predicate.def_id(),
1323                        [elem_ty],
1324                    )),
1325                ));
1326            }
1327
1328            // All other types implement `BikeshedGuaranteedNoDrop` only if
1329            // they implement `Copy`. We could be smart here and short-circuit
1330            // some trivially `Copy`/`!Copy` types, but there's no benefit.
1331            ty::FnDef(..)
1332            | ty::FnPtr(..)
1333            | ty::Error(_)
1334            | ty::Uint(_)
1335            | ty::Int(_)
1336            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1337            | ty::Bool
1338            | ty::Float(_)
1339            | ty::Char
1340            | ty::RawPtr(..)
1341            | ty::Never
1342            | ty::Pat(..)
1343            | ty::Dynamic(..)
1344            | ty::Str
1345            | ty::Slice(_)
1346            | ty::Foreign(..)
1347            | ty::Adt(..)
1348            | ty::Alias(..)
1349            | ty::Param(_)
1350            | ty::Placeholder(..)
1351            | ty::Closure(..)
1352            | ty::CoroutineClosure(..)
1353            | ty::Coroutine(..)
1354            | ty::UnsafeBinder(_)
1355            | ty::CoroutineWitness(..)
1356            | ty::Bound(..) => {
1357                obligations.push(obligation.with(
1358                    tcx,
1359                    self_ty.map_bound(|ty| {
1360                        ty::TraitRef::new(
1361                            tcx,
1362                            tcx.require_lang_item(LangItem::Copy, Some(obligation.cause.span)),
1363                            [ty],
1364                        )
1365                    }),
1366                ));
1367            }
1368
1369            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1370                panic!("unexpected type `{self_ty:?}`")
1371            }
1372        }
1373
1374        ImplSource::Builtin(BuiltinImplSource::Misc, obligations)
1375    }
1376}
1377
1378/// Compute a goal that some RPITIT (right now, only RPITITs corresponding to Futures)
1379/// implements the `PointerLike` trait, which is a requirement for the RPITIT to be
1380/// coercible to `dyn* Future`, which is itself a requirement for the RPITIT's parent
1381/// trait to be coercible to `dyn Trait`.
1382///
1383/// We do this given a supertrait's substitutions, and then augment the substitutions
1384/// with bound variables to compute the goal universally. Given that `PointerLike` has
1385/// no region requirements (at least for the built-in pointer types), this shouldn't
1386/// *really* matter, but it is the best choice for soundness.
1387fn pointer_like_goal_for_rpitit<'tcx>(
1388    tcx: TyCtxt<'tcx>,
1389    supertrait: ty::PolyTraitRef<'tcx>,
1390    rpitit_item: DefId,
1391    cause: &ObligationCause<'tcx>,
1392) -> ty::PolyTraitRef<'tcx> {
1393    let mut bound_vars = supertrait.bound_vars().to_vec();
1394
1395    let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind {
1396        ty::GenericParamDefKind::Lifetime => {
1397            let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id));
1398            bound_vars.push(ty::BoundVariableKind::Region(kind));
1399            ty::Region::new_bound(
1400                tcx,
1401                ty::INNERMOST,
1402                ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind },
1403            )
1404            .into()
1405        }
1406        ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => {
1407            unreachable!()
1408        }
1409    });
1410
1411    ty::Binder::bind_with_vars(
1412        ty::TraitRef::new(
1413            tcx,
1414            tcx.require_lang_item(LangItem::PointerLike, Some(cause.span)),
1415            [Ty::new_projection_from_args(tcx, rpitit_item, args)],
1416        ),
1417        tcx.mk_bound_variable_kinds(&bound_vars),
1418    )
1419}