]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Rollup merge of #95016 - janpaul123:patch-1, r=dtolnay
[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, Subst, SubstsRef};
15 use rustc_middle::ty::{self, 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             if !tcx.generics_of(assoc_type).params.is_empty() {
491                 tcx.sess.delay_span_bug(
492                     obligation.cause.span,
493                     "GATs in trait object shouldn't have been considered",
494                 );
495                 return Err(SelectionError::Unimplemented);
496             }
497             // This maybe belongs in wf, but that can't (doesn't) handle
498             // higher-ranked things.
499             // Prevent, e.g., `dyn Iterator<Item = str>`.
500             for bound in self.tcx().item_bounds(assoc_type) {
501                 let subst_bound = bound.subst(tcx, trait_predicate.trait_ref.substs);
502                 let normalized_bound = normalize_with_depth_to(
503                     self,
504                     obligation.param_env,
505                     obligation.cause.clone(),
506                     obligation.recursion_depth + 1,
507                     subst_bound,
508                     &mut nested,
509                 );
510                 nested.push(Obligation::new(
511                     obligation.cause.clone(),
512                     obligation.param_env,
513                     normalized_bound,
514                 ));
515             }
516         }
517
518         debug!(?nested, "object nested obligations");
519
520         let vtable_base = super::super::vtable_trait_first_method_offset(
521             tcx,
522             (unnormalized_upcast_trait_ref, ty::Binder::dummy(object_trait_ref)),
523         );
524
525         Ok(ImplSourceObjectData { upcast_trait_ref, vtable_base, nested })
526     }
527
528     fn confirm_fn_pointer_candidate(
529         &mut self,
530         obligation: &TraitObligation<'tcx>,
531     ) -> Result<ImplSourceFnPointerData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
532     {
533         debug!(?obligation, "confirm_fn_pointer_candidate");
534
535         // Okay to skip binder; it is reintroduced below.
536         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
537         let sig = self_ty.fn_sig(self.tcx());
538         let trait_ref = closure_trait_ref_and_return_type(
539             self.tcx(),
540             obligation.predicate.def_id(),
541             self_ty,
542             sig,
543             util::TupleArgumentsFlag::Yes,
544         )
545         .map_bound(|(trait_ref, _)| trait_ref);
546
547         let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
548         Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
549     }
550
551     fn confirm_trait_alias_candidate(
552         &mut self,
553         obligation: &TraitObligation<'tcx>,
554         alias_def_id: DefId,
555     ) -> ImplSourceTraitAliasData<'tcx, PredicateObligation<'tcx>> {
556         debug!(?obligation, ?alias_def_id, "confirm_trait_alias_candidate");
557
558         self.infcx.commit_unconditionally(|_| {
559             let predicate = self.infcx().replace_bound_vars_with_placeholders(obligation.predicate);
560             let trait_ref = predicate.trait_ref;
561             let trait_def_id = trait_ref.def_id;
562             let substs = trait_ref.substs;
563
564             let trait_obligations = self.impl_or_trait_obligations(
565                 &obligation.cause,
566                 obligation.recursion_depth,
567                 obligation.param_env,
568                 trait_def_id,
569                 &substs,
570                 obligation.predicate,
571             );
572
573             debug!(?trait_def_id, ?trait_obligations, "trait alias obligations");
574
575             ImplSourceTraitAliasData { alias_def_id, substs, nested: trait_obligations }
576         })
577     }
578
579     fn confirm_generator_candidate(
580         &mut self,
581         obligation: &TraitObligation<'tcx>,
582     ) -> Result<ImplSourceGeneratorData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
583     {
584         // Okay to skip binder because the substs on generator types never
585         // touch bound regions, they just capture the in-scope
586         // type/region parameters.
587         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
588         let ty::Generator(generator_def_id, substs, _) = *self_ty.kind() else {
589             bug!("closure candidate for non-closure {:?}", obligation);
590         };
591
592         debug!(?obligation, ?generator_def_id, ?substs, "confirm_generator_candidate");
593
594         let trait_ref = self.generator_trait_ref_unnormalized(obligation, substs);
595
596         let nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
597         debug!(?trait_ref, ?nested, "generator candidate obligations");
598
599         Ok(ImplSourceGeneratorData { generator_def_id, substs, nested })
600     }
601
602     #[instrument(skip(self), level = "debug")]
603     fn confirm_closure_candidate(
604         &mut self,
605         obligation: &TraitObligation<'tcx>,
606     ) -> Result<ImplSourceClosureData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>> {
607         let kind = self
608             .tcx()
609             .fn_trait_kind_from_lang_item(obligation.predicate.def_id())
610             .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation));
611
612         // Okay to skip binder because the substs on closure types never
613         // touch bound regions, they just capture the in-scope
614         // type/region parameters.
615         let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
616         let ty::Closure(closure_def_id, substs) = *self_ty.kind() else {
617             bug!("closure candidate for non-closure {:?}", obligation);
618         };
619
620         let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
621         let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
622
623         debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations");
624
625         // FIXME: Chalk
626
627         if !self.tcx().sess.opts.debugging_opts.chalk {
628             nested.push(Obligation::new(
629                 obligation.cause.clone(),
630                 obligation.param_env,
631                 ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
632                     .to_predicate(self.tcx()),
633             ));
634         }
635
636         Ok(ImplSourceClosureData { closure_def_id, substs, nested })
637     }
638
639     /// In the case of closure types and fn pointers,
640     /// we currently treat the input type parameters on the trait as
641     /// outputs. This means that when we have a match we have only
642     /// considered the self type, so we have to go back and make sure
643     /// to relate the argument types too. This is kind of wrong, but
644     /// since we control the full set of impls, also not that wrong,
645     /// and it DOES yield better error messages (since we don't report
646     /// errors as if there is no applicable impl, but rather report
647     /// errors are about mismatched argument types.
648     ///
649     /// Here is an example. Imagine we have a closure expression
650     /// and we desugared it so that the type of the expression is
651     /// `Closure`, and `Closure` expects `i32` as argument. Then it
652     /// is "as if" the compiler generated this impl:
653     ///
654     ///     impl Fn(i32) for Closure { ... }
655     ///
656     /// Now imagine our obligation is `Closure: Fn(usize)`. So far
657     /// we have matched the self type `Closure`. At this point we'll
658     /// compare the `i32` to `usize` and generate an error.
659     ///
660     /// Note that this checking occurs *after* the impl has selected,
661     /// because these output type parameters should not affect the
662     /// selection of the impl. Therefore, if there is a mismatch, we
663     /// report an error to the user.
664     #[instrument(skip(self), level = "trace")]
665     fn confirm_poly_trait_refs(
666         &mut self,
667         obligation: &TraitObligation<'tcx>,
668         expected_trait_ref: ty::PolyTraitRef<'tcx>,
669     ) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
670         let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
671         // Normalize the obligation and expected trait refs together, because why not
672         let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
673             ensure_sufficient_stack(|| {
674                 self.infcx.commit_unconditionally(|_| {
675                     normalize_with_depth(
676                         self,
677                         obligation.param_env,
678                         obligation.cause.clone(),
679                         obligation.recursion_depth + 1,
680                         (obligation_trait_ref, expected_trait_ref),
681                     )
682                 })
683             });
684
685         self.infcx
686             .at(&obligation.cause, obligation.param_env)
687             .sup(obligation_trait_ref, expected_trait_ref)
688             .map(|InferOk { mut obligations, .. }| {
689                 obligations.extend(nested);
690                 obligations
691             })
692             .map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
693     }
694
695     fn confirm_trait_upcasting_unsize_candidate(
696         &mut self,
697         obligation: &TraitObligation<'tcx>,
698         idx: usize,
699     ) -> Result<ImplSourceTraitUpcastingData<'tcx, PredicateObligation<'tcx>>, SelectionError<'tcx>>
700     {
701         let tcx = self.tcx();
702
703         // `assemble_candidates_for_unsizing` should ensure there are no late-bound
704         // regions here. See the comment there for more details.
705         let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
706         let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
707         let target = self.infcx.shallow_resolve(target);
708
709         debug!(?source, ?target, "confirm_trait_upcasting_unsize_candidate");
710
711         let mut nested = vec![];
712         let source_trait_ref;
713         let upcast_trait_ref;
714         match (source.kind(), target.kind()) {
715             // TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion).
716             (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
717                 // See `assemble_candidates_for_unsizing` for more info.
718                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
719                 let principal_a = data_a.principal().unwrap();
720                 source_trait_ref = principal_a.with_self_ty(tcx, source);
721                 upcast_trait_ref = util::supertraits(tcx, source_trait_ref).nth(idx).unwrap();
722                 assert_eq!(data_b.principal_def_id(), Some(upcast_trait_ref.def_id()));
723                 let existential_predicate = upcast_trait_ref.map_bound(|trait_ref| {
724                     ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(
725                         tcx, trait_ref,
726                     ))
727                 });
728                 let iter = Some(existential_predicate)
729                     .into_iter()
730                     .chain(
731                         data_a
732                             .projection_bounds()
733                             .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
734                     )
735                     .chain(
736                         data_b
737                             .auto_traits()
738                             .map(ty::ExistentialPredicate::AutoTrait)
739                             .map(ty::Binder::dummy),
740                     );
741                 let existential_predicates = tcx.mk_poly_existential_predicates(iter);
742                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
743
744                 // Require that the traits involved in this upcast are **equal**;
745                 // only the **lifetime bound** is changed.
746                 let InferOk { obligations, .. } = self
747                     .infcx
748                     .at(&obligation.cause, obligation.param_env)
749                     .sup(target, source_trait)
750                     .map_err(|_| Unimplemented)?;
751                 nested.extend(obligations);
752
753                 // Register one obligation for 'a: 'b.
754                 let cause = ObligationCause::new(
755                     obligation.cause.span,
756                     obligation.cause.body_id,
757                     ObjectCastObligation(target),
758                 );
759                 let outlives = ty::OutlivesPredicate(r_a, r_b);
760                 nested.push(Obligation::with_depth(
761                     cause,
762                     obligation.recursion_depth + 1,
763                     obligation.param_env,
764                     obligation.predicate.rebind(outlives).to_predicate(tcx),
765                 ));
766             }
767             _ => bug!(),
768         };
769
770         let vtable_segment_callback = {
771             let mut vptr_offset = 0;
772             move |segment| {
773                 match segment {
774                     VtblSegment::MetadataDSA => {
775                         vptr_offset += ty::COMMON_VTABLE_ENTRIES.len();
776                     }
777                     VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
778                         vptr_offset += util::count_own_vtable_entries(tcx, trait_ref);
779                         if trait_ref == upcast_trait_ref {
780                             if emit_vptr {
781                                 return ControlFlow::Break(Some(vptr_offset));
782                             } else {
783                                 return ControlFlow::Break(None);
784                             }
785                         }
786
787                         if emit_vptr {
788                             vptr_offset += 1;
789                         }
790                     }
791                 }
792                 ControlFlow::Continue(())
793             }
794         };
795
796         let vtable_vptr_slot =
797             super::super::prepare_vtable_segments(tcx, source_trait_ref, vtable_segment_callback)
798                 .unwrap();
799
800         Ok(ImplSourceTraitUpcastingData { upcast_trait_ref, vtable_vptr_slot, nested })
801     }
802
803     fn confirm_builtin_unsize_candidate(
804         &mut self,
805         obligation: &TraitObligation<'tcx>,
806     ) -> Result<ImplSourceBuiltinData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
807         let tcx = self.tcx();
808
809         // `assemble_candidates_for_unsizing` should ensure there are no late-bound
810         // regions here. See the comment there for more details.
811         let source = self.infcx.shallow_resolve(obligation.self_ty().no_bound_vars().unwrap());
812         let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
813         let target = self.infcx.shallow_resolve(target);
814
815         debug!(?source, ?target, "confirm_builtin_unsize_candidate");
816
817         let mut nested = vec![];
818         match (source.kind(), target.kind()) {
819             // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping).
820             (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
821                 // See `assemble_candidates_for_unsizing` for more info.
822                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
823                 let iter = data_a
824                     .principal()
825                     .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
826                     .into_iter()
827                     .chain(
828                         data_a
829                             .projection_bounds()
830                             .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)),
831                     )
832                     .chain(
833                         data_b
834                             .auto_traits()
835                             .map(ty::ExistentialPredicate::AutoTrait)
836                             .map(ty::Binder::dummy),
837                     );
838                 let existential_predicates = tcx.mk_poly_existential_predicates(iter);
839                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
840
841                 // Require that the traits involved in this upcast are **equal**;
842                 // only the **lifetime bound** is changed.
843                 let InferOk { obligations, .. } = self
844                     .infcx
845                     .at(&obligation.cause, obligation.param_env)
846                     .sup(target, source_trait)
847                     .map_err(|_| Unimplemented)?;
848                 nested.extend(obligations);
849
850                 // Register one obligation for 'a: 'b.
851                 let cause = ObligationCause::new(
852                     obligation.cause.span,
853                     obligation.cause.body_id,
854                     ObjectCastObligation(target),
855                 );
856                 let outlives = ty::OutlivesPredicate(r_a, r_b);
857                 nested.push(Obligation::with_depth(
858                     cause,
859                     obligation.recursion_depth + 1,
860                     obligation.param_env,
861                     obligation.predicate.rebind(outlives).to_predicate(tcx),
862                 ));
863             }
864
865             // `T` -> `Trait`
866             (_, &ty::Dynamic(ref data, r)) => {
867                 let mut object_dids = data.auto_traits().chain(data.principal_def_id());
868                 if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
869                     return Err(TraitNotObjectSafe(did));
870                 }
871
872                 let cause = ObligationCause::new(
873                     obligation.cause.span,
874                     obligation.cause.body_id,
875                     ObjectCastObligation(target),
876                 );
877
878                 let predicate_to_obligation = |predicate| {
879                     Obligation::with_depth(
880                         cause.clone(),
881                         obligation.recursion_depth + 1,
882                         obligation.param_env,
883                         predicate,
884                     )
885                 };
886
887                 // Create obligations:
888                 //  - Casting `T` to `Trait`
889                 //  - For all the various builtin bounds attached to the object cast. (In other
890                 //  words, if the object type is `Foo + Send`, this would create an obligation for
891                 //  the `Send` check.)
892                 //  - Projection predicates
893                 nested.extend(
894                     data.iter().map(|predicate| {
895                         predicate_to_obligation(predicate.with_self_ty(tcx, source))
896                     }),
897                 );
898
899                 // We can only make objects from sized types.
900                 let tr = ty::Binder::dummy(ty::TraitRef::new(
901                     tcx.require_lang_item(LangItem::Sized, None),
902                     tcx.mk_substs_trait(source, &[]),
903                 ));
904                 nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
905
906                 // If the type is `Foo + 'a`, ensure that the type
907                 // being cast to `Foo + 'a` outlives `'a`:
908                 let outlives = ty::OutlivesPredicate(source, r);
909                 nested.push(predicate_to_obligation(ty::Binder::dummy(outlives).to_predicate(tcx)));
910             }
911
912             // `[T; n]` -> `[T]`
913             (&ty::Array(a, _), &ty::Slice(b)) => {
914                 let InferOk { obligations, .. } = self
915                     .infcx
916                     .at(&obligation.cause, obligation.param_env)
917                     .eq(b, a)
918                     .map_err(|_| Unimplemented)?;
919                 nested.extend(obligations);
920             }
921
922             // `Struct<T>` -> `Struct<U>`
923             (&ty::Adt(def, substs_a), &ty::Adt(_, substs_b)) => {
924                 let maybe_unsizing_param_idx = |arg: GenericArg<'tcx>| match arg.unpack() {
925                     GenericArgKind::Type(ty) => match ty.kind() {
926                         ty::Param(p) => Some(p.index),
927                         _ => None,
928                     },
929
930                     // Lifetimes aren't allowed to change during unsizing.
931                     GenericArgKind::Lifetime(_) => None,
932
933                     GenericArgKind::Const(ct) => match ct.val() {
934                         ty::ConstKind::Param(p) => Some(p.index),
935                         _ => None,
936                     },
937                 };
938
939                 // FIXME(eddyb) cache this (including computing `unsizing_params`)
940                 // by putting it in a query; it would only need the `DefId` as it
941                 // looks at declared field types, not anything substituted.
942
943                 // The last field of the structure has to exist and contain type/const parameters.
944                 let (tail_field, prefix_fields) =
945                     def.non_enum_variant().fields.split_last().ok_or(Unimplemented)?;
946                 let tail_field_ty = tcx.type_of(tail_field.did);
947
948                 let mut unsizing_params = GrowableBitSet::new_empty();
949                 for arg in tail_field_ty.walk() {
950                     if let Some(i) = maybe_unsizing_param_idx(arg) {
951                         unsizing_params.insert(i);
952                     }
953                 }
954
955                 // Ensure none of the other fields mention the parameters used
956                 // in unsizing.
957                 for field in prefix_fields {
958                     for arg in tcx.type_of(field.did).walk() {
959                         if let Some(i) = maybe_unsizing_param_idx(arg) {
960                             unsizing_params.remove(i);
961                         }
962                     }
963                 }
964
965                 if unsizing_params.is_empty() {
966                     return Err(Unimplemented);
967                 }
968
969                 // Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`.
970                 let source_tail = tail_field_ty.subst(tcx, substs_a);
971                 let target_tail = tail_field_ty.subst(tcx, substs_b);
972
973                 // Check that the source struct with the target's
974                 // unsizing parameters is equal to the target.
975                 let substs = tcx.mk_substs(substs_a.iter().enumerate().map(|(i, k)| {
976                     if unsizing_params.contains(i as u32) { substs_b[i] } else { k }
977                 }));
978                 let new_struct = tcx.mk_adt(def, substs);
979                 let InferOk { obligations, .. } = self
980                     .infcx
981                     .at(&obligation.cause, obligation.param_env)
982                     .eq(target, new_struct)
983                     .map_err(|_| Unimplemented)?;
984                 nested.extend(obligations);
985
986                 // Construct the nested `TailField<T>: Unsize<TailField<U>>` predicate.
987                 nested.push(predicate_for_trait_def(
988                     tcx,
989                     obligation.param_env,
990                     obligation.cause.clone(),
991                     obligation.predicate.def_id(),
992                     obligation.recursion_depth + 1,
993                     source_tail,
994                     &[target_tail.into()],
995                 ));
996             }
997
998             // `(.., T)` -> `(.., U)`
999             (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
1000                 assert_eq!(tys_a.len(), tys_b.len());
1001
1002                 // The last field of the tuple has to exist.
1003                 let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?;
1004                 let &b_last = tys_b.last().unwrap();
1005
1006                 // Check that the source tuple with the target's
1007                 // last element is equal to the target.
1008                 let new_tuple = tcx.mk_tup(a_mid.iter().copied().chain(iter::once(b_last)));
1009                 let InferOk { obligations, .. } = self
1010                     .infcx
1011                     .at(&obligation.cause, obligation.param_env)
1012                     .eq(target, new_tuple)
1013                     .map_err(|_| Unimplemented)?;
1014                 nested.extend(obligations);
1015
1016                 // Construct the nested `T: Unsize<U>` predicate.
1017                 nested.push(ensure_sufficient_stack(|| {
1018                     predicate_for_trait_def(
1019                         tcx,
1020                         obligation.param_env,
1021                         obligation.cause.clone(),
1022                         obligation.predicate.def_id(),
1023                         obligation.recursion_depth + 1,
1024                         a_last,
1025                         &[b_last.into()],
1026                     )
1027                 }));
1028             }
1029
1030             _ => bug!(),
1031         };
1032
1033         Ok(ImplSourceBuiltinData { nested })
1034     }
1035
1036     fn confirm_const_destruct_candidate(
1037         &mut self,
1038         obligation: &TraitObligation<'tcx>,
1039         impl_def_id: Option<DefId>,
1040     ) -> Result<ImplSourceConstDestructData<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
1041         // `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
1042         if !obligation.is_const() {
1043             return Ok(ImplSourceConstDestructData { nested: vec![] });
1044         }
1045
1046         let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None);
1047         // FIXME: remove if statement below when beta is bumped
1048         #[cfg(bootstrap)]
1049         {}
1050
1051         if obligation.predicate.skip_binder().def_id() == drop_trait {
1052             return Ok(ImplSourceConstDestructData { nested: vec![] });
1053         }
1054
1055         let tcx = self.tcx();
1056         let self_ty = self.infcx.shallow_resolve(obligation.self_ty());
1057
1058         let mut nested = vec![];
1059         let cause = obligation.derived_cause(BuiltinDerivedObligation);
1060
1061         // If we have a custom `impl const Drop`, then
1062         // first check it like a regular impl candidate.
1063         // This is copied from confirm_impl_candidate but remaps the predicate to `~const Drop` beforehand.
1064         if let Some(impl_def_id) = impl_def_id {
1065             let obligations = self.infcx.commit_unconditionally(|_| {
1066                 let mut new_obligation = obligation.clone();
1067                 new_obligation.predicate = new_obligation.predicate.map_bound(|mut trait_pred| {
1068                     trait_pred.trait_ref.def_id = drop_trait;
1069                     trait_pred
1070                 });
1071                 let substs = self.rematch_impl(impl_def_id, &new_obligation);
1072                 debug!(?substs, "impl substs");
1073
1074                 let derived = DerivedObligationCause {
1075                     parent_trait_pred: obligation.predicate,
1076                     parent_code: obligation.cause.clone_code(),
1077                 };
1078                 let derived_code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
1079                     derived,
1080                     impl_def_id,
1081                     span: obligation.cause.span,
1082                 }));
1083
1084                 let cause = ObligationCause::new(
1085                     obligation.cause.span,
1086                     obligation.cause.body_id,
1087                     derived_code,
1088                 );
1089                 ensure_sufficient_stack(|| {
1090                     self.vtable_impl(
1091                         impl_def_id,
1092                         substs,
1093                         &cause,
1094                         new_obligation.recursion_depth + 1,
1095                         new_obligation.param_env,
1096                         obligation.predicate,
1097                     )
1098                 })
1099             });
1100             nested.extend(obligations.nested);
1101         }
1102
1103         // We want to confirm the ADT's fields if we have an ADT
1104         let mut stack = match *self_ty.skip_binder().kind() {
1105             ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(tcx, substs)).collect(),
1106             _ => vec![self_ty.skip_binder()],
1107         };
1108
1109         while let Some(nested_ty) = stack.pop() {
1110             match *nested_ty.kind() {
1111                 // We know these types are trivially drop
1112                 ty::Bool
1113                 | ty::Char
1114                 | ty::Int(_)
1115                 | ty::Uint(_)
1116                 | ty::Float(_)
1117                 | ty::Infer(ty::IntVar(_))
1118                 | ty::Infer(ty::FloatVar(_))
1119                 | ty::Str
1120                 | ty::RawPtr(_)
1121                 | ty::Ref(..)
1122                 | ty::FnDef(..)
1123                 | ty::FnPtr(_)
1124                 | ty::Never
1125                 | ty::Foreign(_) => {}
1126
1127                 // These types are built-in, so we can fast-track by registering
1128                 // nested predicates for their constituent type(s)
1129                 ty::Array(ty, _) | ty::Slice(ty) => {
1130                     stack.push(ty);
1131                 }
1132                 ty::Tuple(tys) => {
1133                     stack.extend(tys.iter());
1134                 }
1135                 ty::Closure(_, substs) => {
1136                     stack.push(substs.as_closure().tupled_upvars_ty());
1137                 }
1138                 ty::Generator(_, substs, _) => {
1139                     let generator = substs.as_generator();
1140                     stack.extend([generator.tupled_upvars_ty(), generator.witness()]);
1141                 }
1142                 ty::GeneratorWitness(tys) => {
1143                     stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
1144                 }
1145
1146                 // If we have a projection type, make sure to normalize it so we replace it
1147                 // with a fresh infer variable
1148                 ty::Projection(..) => {
1149                     self.infcx.commit_unconditionally(|_| {
1150                         let predicate = normalize_with_depth_to(
1151                             self,
1152                             obligation.param_env,
1153                             cause.clone(),
1154                             obligation.recursion_depth + 1,
1155                             self_ty
1156                                 .rebind(ty::TraitPredicate {
1157                                     trait_ref: ty::TraitRef {
1158                                         def_id: self
1159                                             .tcx()
1160                                             .require_lang_item(LangItem::Destruct, None),
1161                                         substs: self.tcx().mk_substs_trait(nested_ty, &[]),
1162                                     },
1163                                     constness: ty::BoundConstness::ConstIfConst,
1164                                     polarity: ty::ImplPolarity::Positive,
1165                                 })
1166                                 .to_predicate(tcx),
1167                             &mut nested,
1168                         );
1169
1170                         nested.push(Obligation::with_depth(
1171                             cause.clone(),
1172                             obligation.recursion_depth + 1,
1173                             obligation.param_env,
1174                             predicate,
1175                         ));
1176                     });
1177                 }
1178
1179                 // If we have any other type (e.g. an ADT), just register a nested obligation
1180                 // since it's either not `const Drop` (and we raise an error during selection),
1181                 // or it's an ADT (and we need to check for a custom impl during selection)
1182                 _ => {
1183                     let predicate = self_ty
1184                         .rebind(ty::TraitPredicate {
1185                             trait_ref: ty::TraitRef {
1186                                 def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
1187                                 substs: self.tcx().mk_substs_trait(nested_ty, &[]),
1188                             },
1189                             constness: ty::BoundConstness::ConstIfConst,
1190                             polarity: ty::ImplPolarity::Positive,
1191                         })
1192                         .to_predicate(tcx);
1193
1194                     nested.push(Obligation::with_depth(
1195                         cause.clone(),
1196                         obligation.recursion_depth + 1,
1197                         obligation.param_env,
1198                         predicate,
1199                     ));
1200                 }
1201             }
1202         }
1203
1204         Ok(ImplSourceConstDestructData { nested })
1205     }
1206 }