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