• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 use rustc_ast::Mutability;
10 use rustc_data_structures::stack::ensure_sufficient_stack;
11 use rustc_hir::lang_items::LangItem;
12 use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
13 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
14 use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
15 use rustc_middle::ty::{
16     self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
17     TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt,
18 };
19 use rustc_span::def_id::DefId;
20 
21 use crate::traits::project::{normalize_with_depth, normalize_with_depth_to};
22 use crate::traits::util::{self, closure_trait_ref_and_return_type};
23 use crate::traits::vtable::{
24     count_own_vtable_entries, prepare_vtable_segments, vtable_trait_first_method_offset,
25     VtblSegment,
26 };
27 use crate::traits::{
28     BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
29     ImplSourceObjectData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
30     Obligation, ObligationCause, OutputTypeParameterMismatch, PolyTraitObligation,
31     PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, Unimplemented,
32 };
33 
34 use super::BuiltinImplConditions;
35 use super::SelectionCandidate::{self, *};
36 use super::SelectionContext;
37 
38 use std::iter;
39 use std::ops::ControlFlow;
40 
41 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
42     #[instrument(level = "debug", skip(self))]
confirm_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, candidate: SelectionCandidate<'tcx>, ) -> Result<Selection<'tcx>, SelectionError<'tcx>>43     pub(super) fn confirm_candidate(
44         &mut self,
45         obligation: &PolyTraitObligation<'tcx>,
46         candidate: SelectionCandidate<'tcx>,
47     ) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
48         let mut impl_src = match candidate {
49             BuiltinCandidate { has_nested } => {
50                 let data = self.confirm_builtin_candidate(obligation, has_nested);
51                 ImplSource::Builtin(data)
52             }
53 
54             TransmutabilityCandidate => {
55                 let data = self.confirm_transmutability_candidate(obligation)?;
56                 ImplSource::Builtin(data)
57             }
58 
59             ParamCandidate(param) => {
60                 let obligations =
61                     self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
62                 ImplSource::Param(obligations, param.skip_binder().constness)
63             }
64 
65             ImplCandidate(impl_def_id) => {
66                 ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))
67             }
68 
69             AutoImplCandidate => {
70                 let data = self.confirm_auto_impl_candidate(obligation)?;
71                 ImplSource::Builtin(data)
72             }
73 
74             ProjectionCandidate(idx, constness) => {
75                 let obligations = self.confirm_projection_candidate(obligation, idx)?;
76                 ImplSource::Param(obligations, constness)
77             }
78 
79             ObjectCandidate(idx) => {
80                 let data = self.confirm_object_candidate(obligation, idx)?;
81                 ImplSource::Object(data)
82             }
83 
84             ClosureCandidate { .. } => {
85                 let vtable_closure = self.confirm_closure_candidate(obligation)?;
86                 ImplSource::Builtin(vtable_closure)
87             }
88 
89             GeneratorCandidate => {
90                 let vtable_generator = self.confirm_generator_candidate(obligation)?;
91                 ImplSource::Builtin(vtable_generator)
92             }
93 
94             FutureCandidate => {
95                 let vtable_future = self.confirm_future_candidate(obligation)?;
96                 ImplSource::Builtin(vtable_future)
97             }
98 
99             FnPointerCandidate { is_const } => {
100                 let data = self.confirm_fn_pointer_candidate(obligation, is_const)?;
101                 ImplSource::Builtin(data)
102             }
103 
104             TraitAliasCandidate => {
105                 let data = self.confirm_trait_alias_candidate(obligation);
106                 ImplSource::Builtin(data)
107             }
108 
109             BuiltinObjectCandidate => {
110                 // This indicates something like `Trait + Send: Send`. In this case, we know that
111                 // this holds because that's what the object type is telling us, and there's really
112                 // no additional obligations to prove and no types in particular to unify, etc.
113                 ImplSource::Builtin(Vec::new())
114             }
115 
116             BuiltinUnsizeCandidate => {
117                 let data = self.confirm_builtin_unsize_candidate(obligation)?;
118                 ImplSource::Builtin(data)
119             }
120 
121             TraitUpcastingUnsizeCandidate(idx) => {
122                 let data = self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?;
123                 ImplSource::TraitUpcasting(data)
124             }
125 
126             ConstDestructCandidate(def_id) => {
127                 let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
128                 ImplSource::Builtin(data)
129             }
130         };
131 
132         // The obligations returned by confirmation are recursively evaluated
133         // so we need to make sure they have the correct depth.
134         for subobligation in impl_src.borrow_nested_obligations_mut() {
135             subobligation.set_depth_from_parent(obligation.recursion_depth);
136         }
137 
138         if !obligation.predicate.is_const_if_const() {
139             // normalize nested predicates according to parent predicate's constness.
140             impl_src = impl_src.map(|mut o| {
141                 o.predicate = o.predicate.without_const(self.tcx());
142                 o
143             });
144         }
145 
146         Ok(impl_src)
147     }
148 
confirm_projection_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>149     fn confirm_projection_candidate(
150         &mut self,
151         obligation: &PolyTraitObligation<'tcx>,
152         idx: usize,
153     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
154         let tcx = self.tcx();
155 
156         let trait_predicate = self.infcx.shallow_resolve(obligation.predicate);
157         let placeholder_trait_predicate =
158             self.infcx.instantiate_binder_with_placeholders(trait_predicate).trait_ref;
159         let placeholder_self_ty = placeholder_trait_predicate.self_ty();
160         let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
161         let (def_id, substs) = match *placeholder_self_ty.kind() {
162             // Excluding IATs and type aliases here as they don't have meaningful item bounds.
163             ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
164                 (def_id, substs)
165             }
166             _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
167         };
168 
169         let candidate_predicate = tcx.item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs);
170         let candidate = candidate_predicate
171             .as_trait_clause()
172             .expect("projection candidate is not a trait predicate")
173             .map_bound(|t| t.trait_ref);
174         let mut obligations = Vec::new();
175         let candidate = normalize_with_depth_to(
176             self,
177             obligation.param_env,
178             obligation.cause.clone(),
179             obligation.recursion_depth + 1,
180             candidate,
181             &mut obligations,
182         );
183 
184         obligations.extend(self.infcx.commit_if_ok(|_| {
185             self.infcx
186                 .at(&obligation.cause, obligation.param_env)
187                 .sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
188                 .map(|InferOk { obligations, .. }| obligations)
189                 .map_err(|_| Unimplemented)
190         })?);
191 
192         if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
193             let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
194             for (predicate, _) in predicates {
195                 let normalized = normalize_with_depth_to(
196                     self,
197                     obligation.param_env,
198                     obligation.cause.clone(),
199                     obligation.recursion_depth + 1,
200                     predicate,
201                     &mut obligations,
202                 );
203                 obligations.push(Obligation::with_depth(
204                     self.tcx(),
205                     obligation.cause.clone(),
206                     obligation.recursion_depth + 1,
207                     obligation.param_env,
208                     normalized,
209                 ));
210             }
211         }
212 
213         Ok(obligations)
214     }
215 
confirm_param_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, param: ty::PolyTraitRef<'tcx>, ) -> Vec<PredicateObligation<'tcx>>216     fn confirm_param_candidate(
217         &mut self,
218         obligation: &PolyTraitObligation<'tcx>,
219         param: ty::PolyTraitRef<'tcx>,
220     ) -> Vec<PredicateObligation<'tcx>> {
221         debug!(?obligation, ?param, "confirm_param_candidate");
222 
223         // During evaluation, we already checked that this
224         // where-clause trait-ref could be unified with the obligation
225         // trait-ref. Repeat that unification now without any
226         // transactional boundary; it should not fail.
227         match self.match_where_clause_trait_ref(obligation, param) {
228             Ok(obligations) => obligations,
229             Err(()) => {
230                 bug!(
231                     "Where clause `{:?}` was applicable to `{:?}` but now is not",
232                     param,
233                     obligation
234                 );
235             }
236         }
237     }
238 
confirm_builtin_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, has_nested: bool, ) -> Vec<PredicateObligation<'tcx>>239     fn confirm_builtin_candidate(
240         &mut self,
241         obligation: &PolyTraitObligation<'tcx>,
242         has_nested: bool,
243     ) -> Vec<PredicateObligation<'tcx>> {
244         debug!(?obligation, ?has_nested, "confirm_builtin_candidate");
245 
246         let lang_items = self.tcx().lang_items();
247         let obligations = if has_nested {
248             let trait_def = obligation.predicate.def_id();
249             let conditions = if Some(trait_def) == lang_items.sized_trait() {
250                 self.sized_conditions(obligation)
251             } else if Some(trait_def) == lang_items.copy_trait() {
252                 self.copy_clone_conditions(obligation)
253             } else if Some(trait_def) == lang_items.clone_trait() {
254                 self.copy_clone_conditions(obligation)
255             } else {
256                 bug!("unexpected builtin trait {:?}", trait_def)
257             };
258             let BuiltinImplConditions::Where(nested) = conditions else {
259                 bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
260             };
261 
262             let cause = obligation.derived_cause(BuiltinDerivedObligation);
263             self.collect_predicates_for_types(
264                 obligation.param_env,
265                 cause,
266                 obligation.recursion_depth + 1,
267                 trait_def,
268                 nested,
269             )
270         } else {
271             vec![]
272         };
273 
274         debug!(?obligations);
275 
276         obligations
277     }
278 
279     #[instrument(level = "debug", skip(self))]
confirm_transmutability_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>280     fn confirm_transmutability_candidate(
281         &mut self,
282         obligation: &PolyTraitObligation<'tcx>,
283     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
284         use rustc_transmute::{Answer, Condition};
285         #[instrument(level = "debug", skip(tcx, obligation, predicate))]
286         fn flatten_answer_tree<'tcx>(
287             tcx: TyCtxt<'tcx>,
288             obligation: &PolyTraitObligation<'tcx>,
289             predicate: TraitPredicate<'tcx>,
290             cond: Condition<rustc_transmute::layout::rustc::Ref<'tcx>>,
291         ) -> Vec<PredicateObligation<'tcx>> {
292             match cond {
293                 // FIXME(bryangarza): Add separate `IfAny` case, instead of treating as `IfAll`
294                 // Not possible until the trait solver supports disjunctions of obligations
295                 Condition::IfAll(conds) | Condition::IfAny(conds) => conds
296                     .into_iter()
297                     .flat_map(|cond| flatten_answer_tree(tcx, obligation, predicate, cond))
298                     .collect(),
299                 Condition::IfTransmutable { src, dst } => {
300                     let trait_def_id = obligation.predicate.def_id();
301                     let scope = predicate.trait_ref.substs.type_at(2);
302                     let assume_const = predicate.trait_ref.substs.const_at(3);
303                     let make_obl = |from_ty, to_ty| {
304                         let trait_ref1 = ty::TraitRef::new(
305                             tcx,
306                             trait_def_id,
307                             [
308                                 ty::GenericArg::from(to_ty),
309                                 ty::GenericArg::from(from_ty),
310                                 ty::GenericArg::from(scope),
311                                 ty::GenericArg::from(assume_const),
312                             ],
313                         );
314                         Obligation::with_depth(
315                             tcx,
316                             obligation.cause.clone(),
317                             obligation.recursion_depth + 1,
318                             obligation.param_env,
319                             trait_ref1,
320                         )
321                     };
322 
323                     // If Dst is mutable, check bidirectionally.
324                     // For example, transmuting bool -> u8 is OK as long as you can't update that u8
325                     // to be > 1, because you could later transmute the u8 back to a bool and get UB.
326                     match dst.mutability {
327                         Mutability::Not => vec![make_obl(src.ty, dst.ty)],
328                         Mutability::Mut => vec![make_obl(src.ty, dst.ty), make_obl(dst.ty, src.ty)],
329                     }
330                 }
331             }
332         }
333 
334         // We erase regions here because transmutability calls layout queries,
335         // which does not handle inference regions and doesn't particularly
336         // care about other regions. Erasing late-bound regions is equivalent
337         // to instantiating the binder with placeholders then erasing those
338         // placeholder regions.
339         let predicate =
340             self.tcx().erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate));
341 
342         let Some(assume) = rustc_transmute::Assume::from_const(
343             self.infcx.tcx,
344             obligation.param_env,
345             predicate.trait_ref.substs.const_at(3)
346         ) else {
347             return Err(Unimplemented);
348         };
349 
350         let dst = predicate.trait_ref.substs.type_at(0);
351         let src = predicate.trait_ref.substs.type_at(1);
352         debug!(?src, ?dst);
353         let mut transmute_env = rustc_transmute::TransmuteTypeEnv::new(self.infcx);
354         let maybe_transmutable = transmute_env.is_transmutable(
355             obligation.cause.clone(),
356             rustc_transmute::Types { dst, src },
357             predicate.trait_ref.substs.type_at(2),
358             assume,
359         );
360 
361         let fully_flattened = match maybe_transmutable {
362             Answer::No(_) => Err(Unimplemented)?,
363             Answer::If(cond) => flatten_answer_tree(self.tcx(), obligation, predicate, cond),
364             Answer::Yes => vec![],
365         };
366 
367         debug!(?fully_flattened);
368         Ok(fully_flattened)
369     }
370 
371     /// This handles the case where an `auto trait Foo` impl is being used.
372     /// The idea is that the impl applies to `X : Foo` if the following conditions are met:
373     ///
374     /// 1. For each constituent type `Y` in `X`, `Y : Foo` holds
375     /// 2. For each where-clause `C` declared on `Foo`, `[Self => X] C` holds.
confirm_auto_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>376     fn confirm_auto_impl_candidate(
377         &mut self,
378         obligation: &PolyTraitObligation<'tcx>,
379     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
380         debug!(?obligation, "confirm_auto_impl_candidate");
381 
382         let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty());
383         let types = self.constituent_types_for_ty(self_ty)?;
384         Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types))
385     }
386 
387     /// See `confirm_auto_impl_candidate`.
vtable_auto_impl( &mut self, obligation: &PolyTraitObligation<'tcx>, trait_def_id: DefId, nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>, ) -> Vec<PredicateObligation<'tcx>>388     fn vtable_auto_impl(
389         &mut self,
390         obligation: &PolyTraitObligation<'tcx>,
391         trait_def_id: DefId,
392         nested: ty::Binder<'tcx, Vec<Ty<'tcx>>>,
393     ) -> Vec<PredicateObligation<'tcx>> {
394         debug!(?nested, "vtable_auto_impl");
395         ensure_sufficient_stack(|| {
396             let cause = obligation.derived_cause(BuiltinDerivedObligation);
397 
398             let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
399             let trait_ref = self.infcx.instantiate_binder_with_placeholders(poly_trait_ref);
400             let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations(
401                 &cause,
402                 obligation.recursion_depth + 1,
403                 obligation.param_env,
404                 trait_def_id,
405                 &trait_ref.substs,
406                 obligation.predicate,
407             );
408 
409             let mut obligations = self.collect_predicates_for_types(
410                 obligation.param_env,
411                 cause,
412                 obligation.recursion_depth + 1,
413                 trait_def_id,
414                 nested,
415             );
416 
417             // Adds the predicates from the trait. Note that this contains a `Self: Trait`
418             // predicate as usual. It won't have any effect since auto traits are coinductive.
419             obligations.extend(trait_obligations);
420 
421             debug!(?obligations, "vtable_auto_impl");
422 
423             obligations
424         })
425     }
426 
confirm_impl_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: DefId, ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>427     fn confirm_impl_candidate(
428         &mut self,
429         obligation: &PolyTraitObligation<'tcx>,
430         impl_def_id: DefId,
431     ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
432         debug!(?obligation, ?impl_def_id, "confirm_impl_candidate");
433 
434         // First, create the substitutions by matching the impl again,
435         // this time not in a probe.
436         let substs = self.rematch_impl(impl_def_id, obligation);
437         debug!(?substs, "impl substs");
438         ensure_sufficient_stack(|| {
439             self.vtable_impl(
440                 impl_def_id,
441                 substs,
442                 &obligation.cause,
443                 obligation.recursion_depth + 1,
444                 obligation.param_env,
445                 obligation.predicate,
446             )
447         })
448     }
449 
vtable_impl( &mut self, impl_def_id: DefId, substs: Normalized<'tcx, SubstsRef<'tcx>>, cause: &ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>>450     fn vtable_impl(
451         &mut self,
452         impl_def_id: DefId,
453         substs: Normalized<'tcx, SubstsRef<'tcx>>,
454         cause: &ObligationCause<'tcx>,
455         recursion_depth: usize,
456         param_env: ty::ParamEnv<'tcx>,
457         parent_trait_pred: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
458     ) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
459         debug!(?impl_def_id, ?substs, ?recursion_depth, "vtable_impl");
460 
461         let mut impl_obligations = self.impl_or_trait_obligations(
462             cause,
463             recursion_depth,
464             param_env,
465             impl_def_id,
466             &substs.value,
467             parent_trait_pred,
468         );
469 
470         debug!(?impl_obligations, "vtable_impl");
471 
472         // Because of RFC447, the impl-trait-ref and obligations
473         // are sufficient to determine the impl substs, without
474         // relying on projections in the impl-trait-ref.
475         //
476         // e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
477         impl_obligations.extend(substs.obligations);
478 
479         ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: impl_obligations }
480     }
481 
confirm_object_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, index: usize, ) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>>482     fn confirm_object_candidate(
483         &mut self,
484         obligation: &PolyTraitObligation<'tcx>,
485         index: usize,
486     ) -> Result<ImplSourceObjectData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
487         let tcx = self.tcx();
488         debug!(?obligation, ?index, "confirm_object_candidate");
489 
490         let trait_predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
491         let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
492         let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
493         let ty::Dynamic(data, ..) = *self_ty.kind() else {
494             span_bug!(obligation.cause.span, "object candidate with non-object");
495         };
496 
497         let object_trait_ref = data.principal().unwrap_or_else(|| {
498             span_bug!(obligation.cause.span, "object candidate with no principal")
499         });
500         let object_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
501             obligation.cause.span,
502             HigherRankedType,
503             object_trait_ref,
504         );
505         let object_trait_ref = object_trait_ref.with_self_ty(self.tcx(), self_ty);
506 
507         let mut nested = vec![];
508 
509         let mut supertraits = util::supertraits(tcx, ty::Binder::dummy(object_trait_ref));
510         let unnormalized_upcast_trait_ref =
511             supertraits.nth(index).expect("supertraits iterator no longer has as many elements");
512 
513         let upcast_trait_ref = normalize_with_depth_to(
514             self,
515             obligation.param_env,
516             obligation.cause.clone(),
517             obligation.recursion_depth + 1,
518             unnormalized_upcast_trait_ref,
519             &mut nested,
520         );
521 
522         nested.extend(self.infcx.commit_if_ok(|_| {
523             self.infcx
524                 .at(&obligation.cause, obligation.param_env)
525                 .sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref)
526                 .map(|InferOk { obligations, .. }| obligations)
527                 .map_err(|_| Unimplemented)
528         })?);
529 
530         // Check supertraits hold. This is so that their associated type bounds
531         // will be checked in the code below.
532         for super_trait in tcx
533             .super_predicates_of(trait_predicate.def_id())
534             .instantiate(tcx, trait_predicate.trait_ref.substs)
535             .predicates
536             .into_iter()
537         {
538             let normalized_super_trait = normalize_with_depth_to(
539                 self,
540                 obligation.param_env,
541                 obligation.cause.clone(),
542                 obligation.recursion_depth + 1,
543                 super_trait,
544                 &mut nested,
545             );
546             nested.push(obligation.with(tcx, normalized_super_trait));
547         }
548 
549         let assoc_types: Vec<_> = tcx
550             .associated_items(trait_predicate.def_id())
551             .in_definition_order()
552             .filter_map(
553                 |item| if item.kind == ty::AssocKind::Type { Some(item.def_id) } else { None },
554             )
555             .collect();
556 
557         for assoc_type in assoc_types {
558             let defs: &ty::Generics = tcx.generics_of(assoc_type);
559 
560             if !defs.params.is_empty() && !tcx.features().generic_associated_types_extended {
561                 tcx.sess.delay_span_bug(
562                     obligation.cause.span,
563                     "GATs in trait object shouldn't have been considered",
564                 );
565                 return Err(SelectionError::Unimplemented);
566             }
567 
568             // This maybe belongs in wf, but that can't (doesn't) handle
569             // higher-ranked things.
570             // Prevent, e.g., `dyn Iterator<Item = str>`.
571             for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
572                 let subst_bound =
573                     if defs.count() == 0 {
574                         bound.subst(tcx, trait_predicate.trait_ref.substs)
575                     } else {
576                         let mut substs = smallvec::SmallVec::with_capacity(defs.count());
577                         substs.extend(trait_predicate.trait_ref.substs.iter());
578                         let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
579                             smallvec::SmallVec::with_capacity(
580                                 bound.skip_binder().kind().bound_vars().len() + defs.count(),
581                             );
582                         bound_vars.extend(bound.skip_binder().kind().bound_vars().into_iter());
583                         InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
584                             .kind
585                         {
586                             GenericParamDefKind::Type { .. } => {
587                                 let kind = ty::BoundTyKind::Param(param.def_id, param.name);
588                                 let bound_var = ty::BoundVariableKind::Ty(kind);
589                                 bound_vars.push(bound_var);
590                                 Ty::new_bound(
591                                     tcx,
592                                     ty::INNERMOST,
593                                     ty::BoundTy {
594                                         var: ty::BoundVar::from_usize(bound_vars.len() - 1),
595                                         kind,
596                                     },
597                                 )
598                                 .into()
599                             }
600                             GenericParamDefKind::Lifetime => {
601                                 let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name);
602                                 let bound_var = ty::BoundVariableKind::Region(kind);
603                                 bound_vars.push(bound_var);
604                                 ty::Region::new_late_bound(
605                                     tcx,
606                                     ty::INNERMOST,
607                                     ty::BoundRegion {
608                                         var: ty::BoundVar::from_usize(bound_vars.len() - 1),
609                                         kind,
610                                     },
611                                 )
612                                 .into()
613                             }
614                             GenericParamDefKind::Const { .. } => {
615                                 let bound_var = ty::BoundVariableKind::Const;
616                                 bound_vars.push(bound_var);
617                                 ty::Const::new_bound(
618                                     tcx,
619                                     ty::INNERMOST,
620                                     ty::BoundVar::from_usize(bound_vars.len() - 1),
621                                     tcx.type_of(param.def_id)
622                                         .no_bound_vars()
623                                         .expect("const parameter types cannot be generic"),
624                                 )
625                                 .into()
626                             }
627                         });
628                         let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars);
629                         let assoc_ty_substs = tcx.mk_substs(&substs);
630                         let bound =
631                             bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs);
632                         ty::Binder::bind_with_vars(bound, bound_vars).to_predicate(tcx)
633                     };
634                 let normalized_bound = normalize_with_depth_to(
635                     self,
636                     obligation.param_env,
637                     obligation.cause.clone(),
638                     obligation.recursion_depth + 1,
639                     subst_bound,
640                     &mut nested,
641                 );
642                 nested.push(obligation.with(tcx, normalized_bound));
643             }
644         }
645 
646         debug!(?nested, "object nested obligations");
647 
648         let vtable_base = vtable_trait_first_method_offset(
649             tcx,
650             (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
651         );
652 
653         Ok(ImplSourceObjectData { vtable_base, nested })
654     }
655 
confirm_fn_pointer_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, is_const: bool, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>656     fn confirm_fn_pointer_candidate(
657         &mut self,
658         obligation: &PolyTraitObligation<'tcx>,
659         is_const: bool,
660     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
661         debug!(?obligation, "confirm_fn_pointer_candidate");
662 
663         let tcx = self.tcx();
664 
665         let Some(self_ty) = self
666             .infcx
667             .shallow_resolve(obligation.self_ty().no_bound_vars()) else
668         {
669             // FIXME: Ideally we'd support `for<'a> fn(&'a ()): Fn(&'a ())`,
670             // but we do not currently. Luckily, such a bound is not
671             // particularly useful, so we don't expect users to write
672             // them often.
673             return Err(SelectionError::Unimplemented);
674         };
675 
676         let sig = self_ty.fn_sig(tcx);
677         let trait_ref = closure_trait_ref_and_return_type(
678             tcx,
679             obligation.predicate.def_id(),
680             self_ty,
681             sig,
682             util::TupleArgumentsFlag::Yes,
683         )
684         .map_bound(|(trait_ref, _)| trait_ref);
685 
686         let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
687         let cause = obligation.derived_cause(BuiltinDerivedObligation);
688 
689         if obligation.is_const() && !is_const {
690             // function is a trait method
691             if let ty::FnDef(def_id, substs) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {
692                 let trait_ref = TraitRef::from_method(tcx, trait_id, *substs);
693                 let poly_trait_pred = Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst);
694                 let obligation = Obligation::new(tcx, cause.clone(), obligation.param_env, poly_trait_pred);
695                 nested.push(obligation);
696             }
697         }
698 
699         // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
700         let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output());
701         let output_ty = normalize_with_depth_to(
702             self,
703             obligation.param_env,
704             cause.clone(),
705             obligation.recursion_depth,
706             output_ty,
707             &mut nested,
708         );
709         let tr = ty::TraitRef::from_lang_item(self.tcx(), LangItem::Sized, cause.span, [output_ty]);
710         nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
711 
712         Ok(nested)
713     }
714 
confirm_trait_alias_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Vec<PredicateObligation<'tcx>>715     fn confirm_trait_alias_candidate(
716         &mut self,
717         obligation: &PolyTraitObligation<'tcx>,
718     ) -> Vec<PredicateObligation<'tcx>> {
719         debug!(?obligation, "confirm_trait_alias_candidate");
720 
721         let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
722         let trait_ref = predicate.trait_ref;
723         let trait_def_id = trait_ref.def_id;
724         let substs = trait_ref.substs;
725 
726         let trait_obligations = self.impl_or_trait_obligations(
727             &obligation.cause,
728             obligation.recursion_depth,
729             obligation.param_env,
730             trait_def_id,
731             &substs,
732             obligation.predicate,
733         );
734 
735         debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
736 
737         trait_obligations
738     }
739 
confirm_generator_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>740     fn confirm_generator_candidate(
741         &mut self,
742         obligation: &PolyTraitObligation<'tcx>,
743     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
744         // Okay to skip binder because the substs on generator types never
745         // touch bound regions, they just capture the in-scope
746         // type/region parameters.
747         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
748         let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else {
749             bug!("closure candidate for non-closure {:?}", obligation);
750         };
751 
752         debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
753 
754         let gen_sig = substs.as_generator().poly_sig();
755 
756         // NOTE: The self-type is a generator type and hence is
757         // in fact unparameterized (or at least does not reference any
758         // regions bound in the obligation).
759         let self_ty = obligation
760             .predicate
761             .self_ty()
762             .no_bound_vars()
763             .expect("unboxed closure type should not capture bound vars from the predicate");
764 
765         let trait_ref = super::util::generator_trait_ref_and_outputs(
766             self.tcx(),
767             obligation.predicate.def_id(),
768             self_ty,
769             gen_sig,
770         )
771         .map_bound(|(trait_ref, ..)| trait_ref);
772 
773         let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
774         debug!(?trait_ref, ?nested, "generator candidate obligations");
775 
776         Ok(nested)
777     }
778 
confirm_future_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>779     fn confirm_future_candidate(
780         &mut self,
781         obligation: &PolyTraitObligation<'tcx>,
782     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
783         // Okay to skip binder because the substs on generator types never
784         // touch bound regions, they just capture the in-scope
785         // type/region parameters.
786         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
787         let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else {
788             bug!("closure candidate for non-closure {:?}", obligation);
789         };
790 
791         debug!(?obligation, ?generator_def_id, ?substs, "confirm_future_candidate");
792 
793         let gen_sig = substs.as_generator().poly_sig();
794 
795         let trait_ref = super::util::future_trait_ref_and_outputs(
796             self.tcx(),
797             obligation.predicate.def_id(),
798             obligation.predicate.no_bound_vars().expect("future has no bound vars").self_ty(),
799             gen_sig,
800         )
801         .map_bound(|(trait_ref, ..)| trait_ref);
802 
803         let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
804         debug!(?trait_ref, ?nested, "future candidate obligations");
805 
806         Ok(nested)
807     }
808 
809     #[instrument(skip(self), level = "debug")]
confirm_closure_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>810     fn confirm_closure_candidate(
811         &mut self,
812         obligation: &PolyTraitObligation<'tcx>,
813     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
814         let kind = self
815             .tcx()
816             .fn_trait_kind_from_def_id(obligation.predicate.def_id())
817             .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
818 
819         // Okay to skip binder because the substs on closure types never
820         // touch bound regions, they just capture the in-scope
821         // type/region parameters.
822         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
823         let ty::Closure(closure_def_id, substs) = *self_ty.kind() else {
824             bug!("closure candidate for non-closure {:?}", obligation);
825         };
826 
827         let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
828         let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
829 
830         debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
831 
832         nested.push(obligation.with(
833             self.tcx(),
834             ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)),
835         ));
836 
837         Ok(nested)
838     }
839 
840     /// In the case of closure types and fn pointers,
841     /// we currently treat the input type parameters on the trait as
842     /// outputs. This means that when we have a match we have only
843     /// considered the self type, so we have to go back and make sure
844     /// to relate the argument types too. This is kind of wrong, but
845     /// since we control the full set of impls, also not that wrong,
846     /// and it DOES yield better error messages (since we don't report
847     /// errors as if there is no applicable impl, but rather report
848     /// errors are about mismatched argument types.
849     ///
850     /// Here is an example. Imagine we have a closure expression
851     /// and we desugared it so that the type of the expression is
852     /// `Closure`, and `Closure` expects `i32` as argument. Then it
853     /// is "as if" the compiler generated this impl:
854     /// ```ignore (illustrative)
855     /// impl Fn(i32) for Closure { ... }
856     /// ```
857     /// Now imagine our obligation is `Closure: Fn(usize)`. So far
858     /// we have matched the self type `Closure`. At this point we'll
859     /// compare the `i32` to `usize` and generate an error.
860     ///
861     /// Note that this checking occurs *after* the impl has selected,
862     /// because these output type parameters should not affect the
863     /// selection of the impl. Therefore, if there is a mismatch, we
864     /// report an error to the user.
865     #[instrument(skip(self), level = "trace")]
confirm_poly_trait_refs( &mut self, obligation: &PolyTraitObligation<'tcx>, self_ty_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>866     fn confirm_poly_trait_refs(
867         &mut self,
868         obligation: &PolyTraitObligation<'tcx>,
869         self_ty_trait_ref: ty::PolyTraitRef<'tcx>,
870     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
871         let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
872         // Normalize the obligation and expected trait refs together, because why not
873         let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
874             ensure_sufficient_stack(|| {
875                 normalize_with_depth(
876                     self,
877                     obligation.param_env,
878                     obligation.cause.clone(),
879                     obligation.recursion_depth + 1,
880                     (obligation_trait_ref, self_ty_trait_ref),
881                 )
882             });
883 
884         // needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
885         self.infcx
886             .at(&obligation.cause, obligation.param_env)
887             .sup(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref)
888             .map(|InferOk { mut obligations, .. }| {
889                 obligations.extend(nested);
890                 obligations
891             })
892             .map_err(|terr| {
893                 OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch {
894                     expected_trait_ref: obligation_trait_ref,
895                     found_trait_ref: expected_trait_ref,
896                     terr,
897                 }))
898             })
899     }
900 
confirm_trait_upcasting_unsize_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, idx: usize, ) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>>901     fn confirm_trait_upcasting_unsize_candidate(
902         &mut self,
903         obligation: &PolyTraitObligation<'tcx>,
904         idx: usize,
905     ) -> Result<ImplSourceTraitUpcastingData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
906         let tcx = self.tcx();
907 
908         // `assemble_candidates_for_unsizing` should ensure there are no late-bound
909         // regions here. See the comment there for more details.
910         let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
911         let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
912         let target = self.infcx.shallow_resolve(target);
913 
914         debug!(?source, ?target, "confirm_trait_upcasting_unsize_candidate");
915 
916         let mut nested = vec![];
917         let source_trait_ref;
918         let upcast_trait_ref;
919         match (source.kind(), target.kind()) {
920             // TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
921             (
922                 &ty::Dynamic(ref data_a, r_a, repr_a @ ty::Dyn),
923                 &ty::Dynamic(ref data_b, r_b, ty::Dyn),
924             ) => {
925                 // See `assemble_candidates_for_unsizing` for more info.
926                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
927                 let principal_a = data_a.principal().unwrap();
928                 source_trait_ref = principal_a.with_self_ty(tcx, source);
929                 upcast_trait_ref = util::supertraits(tcx, source_trait_ref).nth(idx).unwrap();
930                 assert_eq!(data_b.principal_def_id(), Some(upcast_trait_ref.def_id()));
931                 let existential_predicate = upcast_trait_ref.map_bound(|trait_ref| {
932                     ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(
933                         tcx, trait_ref,
934                     ))
935                 });
936                 let iter = Some(existential_predicate)
937                     .into_iter()
938                     .chain(
939                         data_a
940                             .projection_bounds()
941                             .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
942                     )
943                     .chain(
944                         data_b
945                             .auto_traits()
946                             .map(ty::ExistentialPredicate::AutoTrait)
947                             .map(ty::Binder::dummy),
948                     );
949                 let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
950                 let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, repr_a);
951 
952                 // Require that the traits involved in this upcast are **equal**;
953                 // only the **lifetime bound** is changed.
954                 let InferOk { obligations, .. } = self
955                     .infcx
956                     .at(&obligation.cause, obligation.param_env)
957                     .sup(DefineOpaqueTypes::No, target, source_trait)
958                     .map_err(|_| Unimplemented)?;
959                 nested.extend(obligations);
960 
961                 let outlives = ty::OutlivesPredicate(r_a, r_b);
962                 nested.push(Obligation::with_depth(
963                     tcx,
964                     obligation.cause.clone(),
965                     obligation.recursion_depth + 1,
966                     obligation.param_env,
967                     obligation.predicate.rebind(outlives),
968                 ));
969             }
970             _ => bug!(),
971         };
972 
973         let vtable_segment_callback = {
974             let mut vptr_offset = 0;
975             move |segment| {
976                 match segment {
977                     VtblSegment::MetadataDSA => {
978                         vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
979                     }
980                     VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
981                         vptr_offset += count_own_vtable_entries(tcx, trait_ref);
982                         if trait_ref == upcast_trait_ref {
983                             if emit_vptr {
984                                 return ControlFlow::Break(Some(vptr_offset));
985                             } else {
986                                 return ControlFlow::Break(None);
987                             }
988                         }
989 
990                         if emit_vptr {
991                             vptr_offset += 1;
992                         }
993                     }
994                 }
995                 ControlFlow::Continue(())
996             }
997         };
998 
999         let vtable_vptr_slot =
1000             prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback).unwrap();
1001 
1002         Ok(ImplSourceTraitUpcastingData { vtable_vptr_slot, nested })
1003     }
1004 
confirm_builtin_unsize_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>1005     fn confirm_builtin_unsize_candidate(
1006         &mut self,
1007         obligation: &PolyTraitObligation<'tcx>,
1008     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1009         let tcx = self.tcx();
1010 
1011         // `assemble_candidates_for_unsizing` should ensure there are no late-bound
1012         // regions here. See the comment there for more details.
1013         let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
1014         let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
1015         let target = self.infcx.shallow_resolve(target);
1016 
1017         debug!(?source, ?target, "confirm_builtin_unsize_candidate");
1018 
1019         let mut nested = vec![];
1020         match (source.kind(), target.kind()) {
1021             // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
1022             (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b))
1023                 if dyn_a == dyn_b =>
1024             {
1025                 // See `assemble_candidates_for_unsizing` for more info.
1026                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
1027                 let iter = data_a
1028                     .principal()
1029                     .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
1030                     .into_iter()
1031                     .chain(
1032                         data_a
1033                             .projection_bounds()
1034                             .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
1035                     )
1036                     .chain(
1037                         data_b
1038                             .auto_traits()
1039                             .map(ty::ExistentialPredicate::AutoTrait)
1040                             .map(ty::Binder::dummy),
1041                     );
1042                 let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter);
1043                 let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a);
1044 
1045                 // Require that the traits involved in this upcast are **equal**;
1046                 // only the **lifetime bound** is changed.
1047                 let InferOk { obligations, .. } = self
1048                     .infcx
1049                     .at(&obligation.cause, obligation.param_env)
1050                     .sup(DefineOpaqueTypes::No, target, source_trait)
1051                     .map_err(|_| Unimplemented)?;
1052                 nested.extend(obligations);
1053 
1054                 // Register one obligation for 'a: 'b.
1055                 let outlives = ty::OutlivesPredicate(r_a, r_b);
1056                 nested.push(Obligation::with_depth(
1057                     tcx,
1058                     obligation.cause.clone(),
1059                     obligation.recursion_depth + 1,
1060                     obligation.param_env,
1061                     obligation.predicate.rebind(outlives),
1062                 ));
1063             }
1064 
1065             // `T` -> `Trait`
1066             (_, &ty::Dynamic(ref data, r, ty::Dyn)) => {
1067                 let mut object_dids = data.auto_traits().chain(data.principal_def_id());
1068                 if let Some(did) = object_dids.find(|did| !tcx.check_is_object_safe(*did)) {
1069                     return Err(TraitNotObjectSafe(did));
1070                 }
1071 
1072                 let predicate_to_obligation = |predicate| {
1073                     Obligation::with_depth(
1074                         tcx,
1075                         obligation.cause.clone(),
1076                         obligation.recursion_depth + 1,
1077                         obligation.param_env,
1078                         predicate,
1079                     )
1080                 };
1081 
1082                 // Create obligations:
1083                 //  - Casting `T` to `Trait`
1084                 //  - For all the various builtin bounds attached to the object cast. (In other
1085                 //  words, if the object type is `Foo + Send`, this would create an obligation for
1086                 //  the `Send` check.)
1087                 //  - Projection predicates
1088                 nested.extend(
1089                     data.iter().map(|predicate| {
1090                         predicate_to_obligation(predicate.with_self_ty(tcx, source))
1091                     }),
1092                 );
1093 
1094                 // We can only make objects from sized types.
1095                 let tr = ty::TraitRef::from_lang_item(
1096                     tcx,
1097                     LangItem::Sized,
1098                     obligation.cause.span,
1099                     [source],
1100                 );
1101                 nested.push(predicate_to_obligation(tr.to_predicate(tcx)));
1102 
1103                 // If the type is `Foo + 'a`, ensure that the type
1104                 // being cast to `Foo + 'a` outlives `'a`:
1105                 let outlives = ty::OutlivesPredicate(source, r);
1106                 nested.push(predicate_to_obligation(
1107                     ty::Binder::dummy(ty::ClauseKind::TypeOutlives(outlives)).to_predicate(tcx),
1108                 ));
1109             }
1110 
1111             // `[T; n]` -> `[T]`
1112             (&ty::Array(a, _), &ty::Slice(b)) => {
1113                 let InferOk { obligations, .. } = self
1114                     .infcx
1115                     .at(&obligation.cause, obligation.param_env)
1116                     .eq(DefineOpaqueTypes::No, b, a)
1117                     .map_err(|_| Unimplemented)?;
1118                 nested.extend(obligations);
1119             }
1120 
1121             // `Struct<T>` -> `Struct<U>`
1122             (&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => {
1123                 let unsizing_params = tcx.unsizing_params_for_adt(def.did());
1124                 if unsizing_params.is_empty() {
1125                     return Err(Unimplemented);
1126                 }
1127 
1128                 let tail_field = def.non_enum_variant().tail();
1129                 let tail_field_ty = tcx.type_of(tail_field.did);
1130 
1131                 // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
1132                 // normalizing in the process, since `type_of` returns something directly from
1133                 // astconv (which means it's un-normalized).
1134                 let source_tail = normalize_with_depth_to(
1135                     self,
1136                     obligation.param_env,
1137                     obligation.cause.clone(),
1138                     obligation.recursion_depth + 1,
1139                     tail_field_ty.subst(tcx, substs_a),
1140                     &mut nested,
1141                 );
1142                 let target_tail = normalize_with_depth_to(
1143                     self,
1144                     obligation.param_env,
1145                     obligation.cause.clone(),
1146                     obligation.recursion_depth + 1,
1147                     tail_field_ty.subst(tcx, substs_b),
1148                     &mut nested,
1149                 );
1150 
1151                 // Check that the source struct with the target's
1152                 // unsizing parameters is equal to the target.
1153                 let substs = tcx.mk_substs_from_iter(substs_a.iter().enumerate().map(|(i, k)| {
1154                     if unsizing_params.contains(i as u32) { substs_b[i] } else { k }
1155                 }));
1156                 let new_struct = Ty::new_adt(tcx, def, substs);
1157                 let InferOk { obligations, .. } = self
1158                     .infcx
1159                     .at(&obligation.cause, obligation.param_env)
1160                     .eq(DefineOpaqueTypes::No, target, new_struct)
1161                     .map_err(|_| Unimplemented)?;
1162                 nested.extend(obligations);
1163 
1164                 // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate.
1165                 let tail_unsize_obligation = obligation.with(
1166                     tcx,
1167                     ty::TraitRef::new(
1168                         tcx,
1169                         obligation.predicate.def_id(),
1170                         [source_tail, target_tail],
1171                     ),
1172                 );
1173                 nested.push(tail_unsize_obligation);
1174             }
1175 
1176             // `(.., T)` -> `(.., U)`
1177             (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
1178                 assert_eq!(tys_a.len(), tys_b.len());
1179 
1180                 // The last field of the tuple has to exist.
1181                 let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?;
1182                 let &b_last = tys_b.last().unwrap();
1183 
1184                 // Check that the source tuple with the target's
1185                 // last element is equal to the target.
1186                 let new_tuple =
1187                     Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last)));
1188                 let InferOk { obligations, .. } = self
1189                     .infcx
1190                     .at(&obligation.cause, obligation.param_env)
1191                     .eq(DefineOpaqueTypes::No, target, new_tuple)
1192                     .map_err(|_| Unimplemented)?;
1193                 nested.extend(obligations);
1194 
1195                 // Add a nested `T: Unsize<U>` predicate.
1196                 let last_unsize_obligation = obligation.with(
1197                     tcx,
1198                     ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]),
1199                 );
1200                 nested.push(last_unsize_obligation);
1201             }
1202 
1203             _ => bug!("source: {source}, target: {target}"),
1204         };
1205 
1206         Ok(nested)
1207     }
1208 
confirm_const_destruct_candidate( &mut self, obligation: &PolyTraitObligation<'tcx>, impl_def_id: Option<DefId>, ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>>1209     fn confirm_const_destruct_candidate(
1210         &mut self,
1211         obligation: &PolyTraitObligation<'tcx>,
1212         impl_def_id: Option<DefId>,
1213     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1214         // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
1215         if !obligation.is_const() {
1216             return Ok(vec![]);
1217         }
1218 
1219         let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
1220 
1221         let tcx = self.tcx();
1222         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
1223 
1224         let mut nested = vec![];
1225         let cause = obligation.derived_cause(BuiltinDerivedObligation);
1226 
1227         // If we have a custom `impl const Drop`, then
1228         // first check it like a regular impl candidate.
1229         // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
1230         if let Some(impl_def_id) = impl_def_id {
1231             let mut new_obligation = obligation.clone();
1232             new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| {
1233                 trait_pred.trait_ref.def_id = drop_trait;
1234                 trait_pred
1235             });
1236             let substs = self.rematch_impl(impl_def_id, &new_obligation);
1237             debug!(?substs, "impl substs");
1238 
1239             let cause = obligation.derived_cause(|derived| {
1240                 ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
1241                     derived,
1242                     impl_or_alias_def_id: impl_def_id,
1243                     impl_def_predicate_index: None,
1244                     span: obligation.cause.span,
1245                 }))
1246             });
1247             let obligations = ensure_sufficient_stack(|| {
1248                 self.vtable_impl(
1249                     impl_def_id,
1250                     substs,
1251                     &cause,
1252                     new_obligation.recursion_depth + 1,
1253                     new_obligation.param_env,
1254                     obligation.predicate,
1255                 )
1256             });
1257             nested.extend(obligations.nested);
1258         }
1259 
1260         // We want to confirm the ADT's fields if we have an ADT
1261         let mut stack = match *self_ty.skip_binder().kind() {
1262             ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(tcx, substs)).collect(),
1263             _ => vec![self_ty.skip_binder()],
1264         };
1265 
1266         while let Some(nested_ty) = stack.pop() {
1267             match *nested_ty.kind() {
1268                 // We know these types are trivially drop
1269                 ty::Bool
1270                 | ty::Char
1271                 | ty::Int(_)
1272                 | ty::Uint(_)
1273                 | ty::Float(_)
1274                 | ty::Infer(ty::IntVar(_))
1275                 | ty::Infer(ty::FloatVar(_))
1276                 | ty::Str
1277                 | ty::RawPtr(_)
1278                 | ty::Ref(..)
1279                 | ty::FnDef(..)
1280                 | ty::FnPtr(_)
1281                 | ty::Never
1282                 | ty::Foreign(_) => {}
1283 
1284                 // `ManuallyDrop` is trivially drop
1285                 ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().manually_drop() => {}
1286 
1287                 // These types are built-in, so we can fast-track by registering
1288                 // nested predicates for their constituent type(s)
1289                 ty::Array(ty, _) | ty::Slice(ty) => {
1290                     stack.push(ty);
1291                 }
1292                 ty::Tuple(tys) => {
1293                     stack.extend(tys.iter());
1294                 }
1295                 ty::Closure(_, substs) => {
1296                     stack.push(substs.as_closure().tupled_upvars_ty());
1297                 }
1298                 ty::Generator(_, substs, _) => {
1299                     let generator = substs.as_generator();
1300                     stack.extend([generator.tupled_upvars_ty(), generator.witness()]);
1301                 }
1302                 ty::GeneratorWitness(tys) => {
1303                     stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
1304                 }
1305                 ty::GeneratorWitnessMIR(def_id, substs) => {
1306                     let tcx = self.tcx();
1307                     stack.extend(tcx.generator_hidden_types(def_id).map(|bty| {
1308                         let ty = bty.subst(tcx, substs);
1309                         debug_assert!(!ty.has_late_bound_regions());
1310                         ty
1311                     }))
1312                 }
1313 
1314                 // If we have a projection type, make sure to normalize it so we replace it
1315                 // with a fresh infer variable
1316                 ty::Alias(ty::Projection | ty::Inherent, ..) => {
1317                     let predicate = normalize_with_depth_to(
1318                         self,
1319                         obligation.param_env,
1320                         cause.clone(),
1321                         obligation.recursion_depth + 1,
1322                         self_ty.rebind(ty::TraitPredicate {
1323                             trait_ref: ty::TraitRef::from_lang_item(
1324                                 self.tcx(),
1325                                 LangItem::Destruct,
1326                                 cause.span,
1327                                 [nested_ty],
1328                             ),
1329                             constness: ty::BoundConstness::ConstIfConst,
1330                             polarity: ty::ImplPolarity::Positive,
1331                         }),
1332                         &mut nested,
1333                     );
1334 
1335                     nested.push(Obligation::with_depth(
1336                         tcx,
1337                         cause.clone(),
1338                         obligation.recursion_depth + 1,
1339                         obligation.param_env,
1340                         predicate,
1341                     ));
1342                 }
1343 
1344                 // If we have any other type (e.g. an ADT), just register a nested obligation
1345                 // since it's either not `const Drop` (and we raise an error during selection),
1346                 // or it's an ADT (and we need to check for a custom impl during selection)
1347                 _ => {
1348                     let predicate = self_ty.rebind(ty::TraitPredicate {
1349                         trait_ref: ty::TraitRef::from_lang_item(
1350                             self.tcx(),
1351                             LangItem::Destruct,
1352                             cause.span,
1353                             [nested_ty],
1354                         ),
1355                         constness: ty::BoundConstness::ConstIfConst,
1356                         polarity: ty::ImplPolarity::Positive,
1357                     });
1358 
1359                     nested.push(Obligation::with_depth(
1360                         tcx,
1361                         cause.clone(),
1362                         obligation.recursion_depth + 1,
1363                         obligation.param_env,
1364                         predicate,
1365                     ));
1366                 }
1367             }
1368         }
1369 
1370         Ok(nested)
1371     }
1372 }
1373