rustc_trait_selection/traits/select/
confirmation.rs

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