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