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