rustc_trait_selection/traits/select/
candidate_assembly.rs

1//! Candidate assembly.
2//!
3//! The selection process begins by examining all in-scope impls,
4//! caller obligations, and so forth and assembling a list of
5//! candidates. See the [rustc dev guide] for more details.
6//!
7//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
8
9use std::ops::ControlFlow;
10
11use hir::LangItem;
12use hir::def_id::DefId;
13use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
14use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind};
15use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
16use rustc_middle::ty::fast_reject::DeepRejectCtxt;
17use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode, elaborate};
18use rustc_middle::{bug, span_bug};
19use tracing::{debug, instrument, trace};
20
21use super::SelectionCandidate::*;
22use super::{BuiltinImplConditions, SelectionCandidateSet, SelectionContext, TraitObligationStack};
23use crate::traits::util;
24
25impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
26    #[instrument(skip(self, stack), level = "debug")]
27    pub(super) fn assemble_candidates<'o>(
28        &mut self,
29        stack: &TraitObligationStack<'o, 'tcx>,
30    ) -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>> {
31        let TraitObligationStack { obligation, .. } = *stack;
32        let obligation = &Obligation {
33            param_env: obligation.param_env,
34            cause: obligation.cause.clone(),
35            recursion_depth: obligation.recursion_depth,
36            predicate: self.infcx.resolve_vars_if_possible(obligation.predicate),
37        };
38
39        if obligation.predicate.skip_binder().self_ty().is_ty_var() {
40            debug!(ty = ?obligation.predicate.skip_binder().self_ty(), "ambiguous inference var or opaque type");
41            // Self is a type variable (e.g., `_: AsRef<str>`).
42            //
43            // This is somewhat problematic, as the current scheme can't really
44            // handle it turning to be a projection. This does end up as truly
45            // ambiguous in most cases anyway.
46            //
47            // Take the fast path out - this also improves
48            // performance by preventing assemble_candidates_from_impls from
49            // matching every impl for this trait.
50            return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true });
51        }
52
53        let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
54
55        // Negative trait predicates have different rules than positive trait predicates.
56        if obligation.polarity() == ty::PredicatePolarity::Negative {
57            self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
58            self.assemble_candidates_from_impls(obligation, &mut candidates);
59            self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
60        } else {
61            self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
62
63            // Other bounds. Consider both in-scope bounds from fn decl
64            // and applicable impls. There is a certain set of precedence rules here.
65            let def_id = obligation.predicate.def_id();
66            let tcx = self.tcx();
67
68            let lang_item = tcx.as_lang_item(def_id);
69            match lang_item {
70                Some(LangItem::Copy | LangItem::Clone) => {
71                    debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
72
73                    // User-defined copy impls are permitted, but only for
74                    // structs and enums.
75                    self.assemble_candidates_from_impls(obligation, &mut candidates);
76
77                    // For other types, we'll use the builtin rules.
78                    let copy_conditions = self.copy_clone_conditions(obligation);
79                    self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
80                }
81                Some(LangItem::DiscriminantKind) => {
82                    // `DiscriminantKind` is automatically implemented for every type.
83                    candidates.vec.push(BuiltinCandidate { has_nested: false });
84                }
85                Some(LangItem::PointeeTrait) => {
86                    // `Pointee` is automatically implemented for every type.
87                    candidates.vec.push(BuiltinCandidate { has_nested: false });
88                }
89                Some(LangItem::Sized) => {
90                    self.assemble_builtin_sized_candidate(obligation, &mut candidates);
91                }
92                Some(LangItem::Unsize) => {
93                    self.assemble_candidates_for_unsizing(obligation, &mut candidates);
94                }
95                Some(LangItem::Destruct) => {
96                    self.assemble_const_destruct_candidates(obligation, &mut candidates);
97                }
98                Some(LangItem::TransmuteTrait) => {
99                    // User-defined transmutability impls are permitted.
100                    self.assemble_candidates_from_impls(obligation, &mut candidates);
101                    self.assemble_candidates_for_transmutability(obligation, &mut candidates);
102                }
103                Some(LangItem::Tuple) => {
104                    self.assemble_candidate_for_tuple(obligation, &mut candidates);
105                }
106                Some(LangItem::FnPtrTrait) => {
107                    self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates);
108                }
109                Some(LangItem::BikeshedGuaranteedNoDrop) => {
110                    self.assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
111                        obligation,
112                        &mut candidates,
113                    );
114                }
115                _ => {
116                    // We re-match here for traits that can have both builtin impls and user written impls.
117                    // After the builtin impls we need to also add user written impls, which we do not want to
118                    // do in general because just checking if there are any is expensive.
119                    match lang_item {
120                        Some(LangItem::Coroutine) => {
121                            self.assemble_coroutine_candidates(obligation, &mut candidates);
122                        }
123                        Some(LangItem::Future) => {
124                            self.assemble_future_candidates(obligation, &mut candidates);
125                        }
126                        Some(LangItem::Iterator) => {
127                            self.assemble_iterator_candidates(obligation, &mut candidates);
128                        }
129                        Some(LangItem::FusedIterator) => {
130                            self.assemble_fused_iterator_candidates(obligation, &mut candidates);
131                        }
132                        Some(LangItem::AsyncIterator) => {
133                            self.assemble_async_iterator_candidates(obligation, &mut candidates);
134                        }
135                        Some(LangItem::AsyncFnKindHelper) => {
136                            self.assemble_async_fn_kind_helper_candidates(
137                                obligation,
138                                &mut candidates,
139                            );
140                        }
141                        Some(LangItem::AsyncFn | LangItem::AsyncFnMut | LangItem::AsyncFnOnce) => {
142                            self.assemble_async_closure_candidates(obligation, &mut candidates);
143                        }
144                        Some(LangItem::Fn | LangItem::FnMut | LangItem::FnOnce) => {
145                            self.assemble_closure_candidates(obligation, &mut candidates);
146                            self.assemble_fn_pointer_candidates(obligation, &mut candidates);
147                        }
148                        _ => {}
149                    }
150
151                    self.assemble_candidates_from_impls(obligation, &mut candidates);
152                    self.assemble_candidates_from_object_ty(obligation, &mut candidates);
153                }
154            }
155
156            self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
157            self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
158            self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
159        }
160        debug!("candidate list size: {}", candidates.vec.len());
161        Ok(candidates)
162    }
163
164    #[instrument(level = "debug", skip(self, candidates))]
165    fn assemble_candidates_from_projected_tys(
166        &mut self,
167        obligation: &PolyTraitObligation<'tcx>,
168        candidates: &mut SelectionCandidateSet<'tcx>,
169    ) {
170        // Before we go into the whole placeholder thing, just
171        // quickly check if the self-type is a projection at all.
172        match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
173            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
174            ty::Alias(ty::Projection | ty::Opaque, _) => {}
175            ty::Infer(ty::TyVar(_)) => {
176                span_bug!(
177                    obligation.cause.span,
178                    "Self=_ should have been handled by assemble_candidates"
179                );
180            }
181            _ => return,
182        }
183
184        self.infcx.probe(|_| {
185            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
186            let placeholder_trait_predicate =
187                self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
188
189            // The bounds returned by `item_bounds` may contain duplicates after
190            // normalization, so try to deduplicate when possible to avoid
191            // unnecessary ambiguity.
192            let mut distinct_normalized_bounds = FxHashSet::default();
193            let _ = self.for_each_item_bound::<!>(
194                placeholder_trait_predicate.self_ty(),
195                |selcx, bound, idx| {
196                    let Some(bound) = bound.as_trait_clause() else {
197                        return ControlFlow::Continue(());
198                    };
199                    if bound.polarity() != placeholder_trait_predicate.polarity {
200                        return ControlFlow::Continue(());
201                    }
202
203                    selcx.infcx.probe(|_| {
204                        // We checked the polarity already
205                        match selcx.match_normalize_trait_ref(
206                            obligation,
207                            placeholder_trait_predicate.trait_ref,
208                            bound.map_bound(|pred| pred.trait_ref),
209                        ) {
210                            Ok(None) => {
211                                candidates.vec.push(ProjectionCandidate(idx));
212                            }
213                            Ok(Some(normalized_trait))
214                                if distinct_normalized_bounds.insert(normalized_trait) =>
215                            {
216                                candidates.vec.push(ProjectionCandidate(idx));
217                            }
218                            _ => {}
219                        }
220                    });
221
222                    ControlFlow::Continue(())
223                },
224                // On ambiguity.
225                || candidates.ambiguous = true,
226            );
227        });
228    }
229
230    /// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
231    /// supplied to find out whether it is listed among them.
232    ///
233    /// Never affects the inference environment.
234    #[instrument(level = "debug", skip(self, stack, candidates))]
235    fn assemble_candidates_from_caller_bounds<'o>(
236        &mut self,
237        stack: &TraitObligationStack<'o, 'tcx>,
238        candidates: &mut SelectionCandidateSet<'tcx>,
239    ) -> Result<(), SelectionError<'tcx>> {
240        debug!(?stack.obligation);
241
242        let bounds = stack
243            .obligation
244            .param_env
245            .caller_bounds()
246            .iter()
247            .filter_map(|p| p.as_trait_clause())
248            // Micro-optimization: filter out predicates relating to different traits.
249            .filter(|p| p.def_id() == stack.obligation.predicate.def_id())
250            .filter(|p| p.polarity() == stack.obligation.predicate.polarity());
251
252        let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx());
253        let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args;
254        // Keep only those bounds which may apply, and propagate overflow if it occurs.
255        for bound in bounds {
256            let bound_trait_ref = bound.map_bound(|t| t.trait_ref);
257            if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) {
258                continue;
259            }
260            let wc = self.where_clause_may_apply(stack, bound_trait_ref)?;
261            if wc.may_apply() {
262                candidates.vec.push(ParamCandidate(bound));
263            }
264        }
265
266        Ok(())
267    }
268
269    fn assemble_coroutine_candidates(
270        &mut self,
271        obligation: &PolyTraitObligation<'tcx>,
272        candidates: &mut SelectionCandidateSet<'tcx>,
273    ) {
274        // Okay to skip binder because the args on coroutine types never
275        // touch bound regions, they just capture the in-scope
276        // type/region parameters.
277        let self_ty = obligation.self_ty().skip_binder();
278        match self_ty.kind() {
279            // `async`/`gen` constructs get lowered to a special kind of coroutine that
280            // should *not* `impl Coroutine`.
281            ty::Coroutine(did, ..) if self.tcx().is_general_coroutine(*did) => {
282                debug!(?self_ty, ?obligation, "assemble_coroutine_candidates",);
283
284                candidates.vec.push(CoroutineCandidate);
285            }
286            ty::Infer(ty::TyVar(_)) => {
287                debug!("assemble_coroutine_candidates: ambiguous self-type");
288                candidates.ambiguous = true;
289            }
290            _ => {}
291        }
292    }
293
294    fn assemble_future_candidates(
295        &mut self,
296        obligation: &PolyTraitObligation<'tcx>,
297        candidates: &mut SelectionCandidateSet<'tcx>,
298    ) {
299        let self_ty = obligation.self_ty().skip_binder();
300        if let ty::Coroutine(did, ..) = self_ty.kind() {
301            // async constructs get lowered to a special kind of coroutine that
302            // should directly `impl Future`.
303            if self.tcx().coroutine_is_async(*did) {
304                debug!(?self_ty, ?obligation, "assemble_future_candidates",);
305
306                candidates.vec.push(FutureCandidate);
307            }
308        }
309    }
310
311    fn assemble_iterator_candidates(
312        &mut self,
313        obligation: &PolyTraitObligation<'tcx>,
314        candidates: &mut SelectionCandidateSet<'tcx>,
315    ) {
316        let self_ty = obligation.self_ty().skip_binder();
317        // gen constructs get lowered to a special kind of coroutine that
318        // should directly `impl Iterator`.
319        if let ty::Coroutine(did, ..) = self_ty.kind()
320            && self.tcx().coroutine_is_gen(*did)
321        {
322            debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
323
324            candidates.vec.push(IteratorCandidate);
325        }
326    }
327
328    fn assemble_fused_iterator_candidates(
329        &mut self,
330        obligation: &PolyTraitObligation<'tcx>,
331        candidates: &mut SelectionCandidateSet<'tcx>,
332    ) {
333        let self_ty = obligation.self_ty().skip_binder();
334        // gen constructs get lowered to a special kind of coroutine that
335        // should directly `impl FusedIterator`.
336        if let ty::Coroutine(did, ..) = self_ty.kind()
337            && self.tcx().coroutine_is_gen(*did)
338        {
339            debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);
340
341            candidates.vec.push(BuiltinCandidate { has_nested: false });
342        }
343    }
344
345    fn assemble_async_iterator_candidates(
346        &mut self,
347        obligation: &PolyTraitObligation<'tcx>,
348        candidates: &mut SelectionCandidateSet<'tcx>,
349    ) {
350        let self_ty = obligation.self_ty().skip_binder();
351        if let ty::Coroutine(did, args) = *self_ty.kind() {
352            // gen constructs get lowered to a special kind of coroutine that
353            // should directly `impl AsyncIterator`.
354            if self.tcx().coroutine_is_async_gen(did) {
355                debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
356
357                // Can only confirm this candidate if we have constrained
358                // the `Yield` type to at least `Poll<Option<?0>>`..
359                let ty::Adt(_poll_def, args) = *args.as_coroutine().yield_ty().kind() else {
360                    candidates.ambiguous = true;
361                    return;
362                };
363                let ty::Adt(_option_def, _) = *args.type_at(0).kind() else {
364                    candidates.ambiguous = true;
365                    return;
366                };
367
368                candidates.vec.push(AsyncIteratorCandidate);
369            }
370        }
371    }
372
373    /// Checks for the artificial impl that the compiler will create for an obligation like `X :
374    /// FnMut<..>` where `X` is a closure type.
375    ///
376    /// Note: the type parameters on a closure candidate are modeled as *output* type
377    /// parameters and hence do not affect whether this trait is a match or not. They will be
378    /// unified during the confirmation step.
379    fn assemble_closure_candidates(
380        &mut self,
381        obligation: &PolyTraitObligation<'tcx>,
382        candidates: &mut SelectionCandidateSet<'tcx>,
383    ) {
384        let kind = self.tcx().fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
385
386        // Okay to skip binder because the args on closure types never
387        // touch bound regions, they just capture the in-scope
388        // type/region parameters
389        let self_ty = obligation.self_ty().skip_binder();
390        match *self_ty.kind() {
391            ty::Closure(def_id, _) => {
392                let is_const = self.tcx().is_const_fn(def_id);
393                debug!(?kind, ?obligation, "assemble_unboxed_candidates");
394                match self.infcx.closure_kind(self_ty) {
395                    Some(closure_kind) => {
396                        debug!(?closure_kind, "assemble_unboxed_candidates");
397                        if closure_kind.extends(kind) {
398                            candidates.vec.push(ClosureCandidate { is_const });
399                        }
400                    }
401                    None => {
402                        if kind == ty::ClosureKind::FnOnce {
403                            candidates.vec.push(ClosureCandidate { is_const });
404                        } else {
405                            candidates.ambiguous = true;
406                        }
407                    }
408                }
409            }
410            ty::CoroutineClosure(def_id, args) => {
411                let args = args.as_coroutine_closure();
412                let is_const = self.tcx().is_const_fn(def_id);
413                if let Some(closure_kind) = self.infcx.closure_kind(self_ty)
414                    // Ambiguity if upvars haven't been constrained yet
415                    && !args.tupled_upvars_ty().is_ty_var()
416                {
417                    // A coroutine-closure implements `FnOnce` *always*, since it may
418                    // always be called once. It additionally implements `Fn`/`FnMut`
419                    // only if it has no upvars referencing the closure-env lifetime,
420                    // and if the closure kind permits it.
421                    if closure_kind.extends(kind) && !args.has_self_borrows() {
422                        candidates.vec.push(ClosureCandidate { is_const });
423                    } else if kind == ty::ClosureKind::FnOnce {
424                        candidates.vec.push(ClosureCandidate { is_const });
425                    }
426                } else if kind == ty::ClosureKind::FnOnce {
427                    candidates.vec.push(ClosureCandidate { is_const });
428                } else {
429                    // This stays ambiguous until kind+upvars are determined.
430                    candidates.ambiguous = true;
431                }
432            }
433            ty::Infer(ty::TyVar(_)) => {
434                debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
435                candidates.ambiguous = true;
436            }
437            _ => {}
438        }
439    }
440
441    #[instrument(level = "debug", skip(self, candidates))]
442    fn assemble_async_closure_candidates(
443        &mut self,
444        obligation: &PolyTraitObligation<'tcx>,
445        candidates: &mut SelectionCandidateSet<'tcx>,
446    ) {
447        let goal_kind =
448            self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
449
450        debug!("self_ty = {:?}", obligation.self_ty().skip_binder().kind());
451        match *obligation.self_ty().skip_binder().kind() {
452            ty::CoroutineClosure(def_id, args) => {
453                if let Some(closure_kind) =
454                    args.as_coroutine_closure().kind_ty().to_opt_closure_kind()
455                    && !closure_kind.extends(goal_kind)
456                {
457                    return;
458                }
459
460                // Make sure this is actually an async closure.
461                let Some(coroutine_kind) =
462                    self.tcx().coroutine_kind(self.tcx().coroutine_for_closure(def_id))
463                else {
464                    bug!("coroutine with no kind");
465                };
466
467                debug!(?coroutine_kind);
468                match coroutine_kind {
469                    CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
470                        candidates.vec.push(AsyncClosureCandidate);
471                    }
472                    _ => (),
473                }
474            }
475            // Closures and fn pointers implement `AsyncFn*` if their return types
476            // implement `Future`, which is checked later.
477            ty::Closure(_, args) => {
478                if let Some(closure_kind) = args.as_closure().kind_ty().to_opt_closure_kind()
479                    && !closure_kind.extends(goal_kind)
480                {
481                    return;
482                }
483                candidates.vec.push(AsyncClosureCandidate);
484            }
485            // Provide an impl, but only for suitable `fn` pointers.
486            ty::FnPtr(sig_tys, hdr) => {
487                if sig_tys.with(hdr).is_fn_trait_compatible() {
488                    candidates.vec.push(AsyncClosureCandidate);
489                }
490            }
491            // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
492            ty::FnDef(def_id, _) => {
493                let tcx = self.tcx();
494                if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
495                    && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
496                {
497                    candidates.vec.push(AsyncClosureCandidate);
498                }
499            }
500            _ => {}
501        }
502    }
503
504    fn assemble_async_fn_kind_helper_candidates(
505        &mut self,
506        obligation: &PolyTraitObligation<'tcx>,
507        candidates: &mut SelectionCandidateSet<'tcx>,
508    ) {
509        let self_ty = obligation.self_ty().skip_binder();
510        let target_kind_ty = obligation.predicate.skip_binder().trait_ref.args.type_at(1);
511
512        // `to_opt_closure_kind` is kind of ICEy when it sees non-int types.
513        if !(self_ty.is_integral() || self_ty.is_ty_var()) {
514            return;
515        }
516        if !(target_kind_ty.is_integral() || self_ty.is_ty_var()) {
517            return;
518        }
519
520        // Check that the self kind extends the goal kind. If it does,
521        // then there's nothing else to check.
522        if let Some(closure_kind) = self_ty.to_opt_closure_kind()
523            && let Some(goal_kind) = target_kind_ty.to_opt_closure_kind()
524            && closure_kind.extends(goal_kind)
525        {
526            candidates.vec.push(AsyncFnKindHelperCandidate);
527        }
528    }
529
530    /// Implements one of the `Fn()` family for a fn pointer.
531    fn assemble_fn_pointer_candidates(
532        &mut self,
533        obligation: &PolyTraitObligation<'tcx>,
534        candidates: &mut SelectionCandidateSet<'tcx>,
535    ) {
536        // Keep this function in sync with extract_tupled_inputs_and_output_from_callable
537        // until the old solver (and thus this function) is removed.
538
539        // Okay to skip binder because what we are inspecting doesn't involve bound regions.
540        let self_ty = obligation.self_ty().skip_binder();
541        match *self_ty.kind() {
542            ty::Infer(ty::TyVar(_)) => {
543                debug!("assemble_fn_pointer_candidates: ambiguous self-type");
544                candidates.ambiguous = true; // Could wind up being a fn() type.
545            }
546            // Provide an impl, but only for suitable `fn` pointers.
547            ty::FnPtr(sig_tys, hdr) => {
548                if sig_tys.with(hdr).is_fn_trait_compatible() {
549                    candidates.vec.push(FnPointerCandidate);
550                }
551            }
552            // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
553            ty::FnDef(def_id, _) => {
554                let tcx = self.tcx();
555                if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
556                    && tcx.codegen_fn_attrs(def_id).target_features.is_empty()
557                {
558                    candidates.vec.push(FnPointerCandidate);
559                }
560            }
561            _ => {}
562        }
563    }
564
565    /// Searches for impls that might apply to `obligation`.
566    #[instrument(level = "debug", skip(self, candidates))]
567    fn assemble_candidates_from_impls(
568        &mut self,
569        obligation: &PolyTraitObligation<'tcx>,
570        candidates: &mut SelectionCandidateSet<'tcx>,
571    ) {
572        let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
573        let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
574        self.tcx().for_each_relevant_impl(
575            obligation.predicate.def_id(),
576            obligation.predicate.skip_binder().trait_ref.self_ty(),
577            |impl_def_id| {
578                // Before we create the generic parameters and everything, first
579                // consider a "quick reject". This avoids creating more types
580                // and so forth that we need to.
581                let impl_trait_header = self.tcx().impl_trait_header(impl_def_id).unwrap();
582                if !drcx
583                    .args_may_unify(obligation_args, impl_trait_header.trait_ref.skip_binder().args)
584                {
585                    return;
586                }
587
588                // For every `default impl`, there's always a non-default `impl`
589                // that will *also* apply. There's no reason to register a candidate
590                // for this impl, since it is *not* proof that the trait goal holds.
591                if self.tcx().defaultness(impl_def_id).is_default() {
592                    return;
593                }
594
595                if self.reject_fn_ptr_impls(
596                    impl_def_id,
597                    obligation,
598                    impl_trait_header.trait_ref.skip_binder().self_ty(),
599                ) {
600                    return;
601                }
602
603                self.infcx.probe(|_| {
604                    if let Ok(_args) = self.match_impl(impl_def_id, impl_trait_header, obligation) {
605                        candidates.vec.push(ImplCandidate(impl_def_id));
606                    }
607                });
608            },
609        );
610    }
611
612    /// The various `impl<T: FnPtr> Trait for T` in libcore are more like builtin impls for all function items
613    /// and function pointers and less like blanket impls. Rejecting them when they can't possibly apply (because
614    /// the obligation's self-type does not implement `FnPtr`) avoids reporting that the self type does not implement
615    /// `FnPtr`, when we wanted to report that it doesn't implement `Trait`.
616    #[instrument(level = "trace", skip(self), ret)]
617    fn reject_fn_ptr_impls(
618        &mut self,
619        impl_def_id: DefId,
620        obligation: &PolyTraitObligation<'tcx>,
621        impl_self_ty: Ty<'tcx>,
622    ) -> bool {
623        // Let `impl<T: FnPtr> Trait for Vec<T>` go through the normal rejection path.
624        if !matches!(impl_self_ty.kind(), ty::Param(..)) {
625            return false;
626        }
627        let Some(fn_ptr_trait) = self.tcx().lang_items().fn_ptr_trait() else {
628            return false;
629        };
630
631        for &(predicate, _) in self.tcx().predicates_of(impl_def_id).predicates {
632            let ty::ClauseKind::Trait(pred) = predicate.kind().skip_binder() else { continue };
633            if fn_ptr_trait != pred.trait_ref.def_id {
634                continue;
635            }
636            trace!(?pred);
637            // Not the bound we're looking for
638            if pred.self_ty() != impl_self_ty {
639                continue;
640            }
641
642            let self_ty = obligation.self_ty().skip_binder();
643            match self_ty.kind() {
644                // Fast path to avoid evaluating an obligation that trivially holds.
645                // There may be more bounds, but these are checked by the regular path.
646                ty::FnPtr(..) => return false,
647
648                // These may potentially implement `FnPtr`
649                ty::Placeholder(..)
650                | ty::Dynamic(_, _, _)
651                | ty::Alias(_, _)
652                | ty::Infer(_)
653                | ty::Param(..)
654                | ty::Bound(_, _) => {}
655
656                // These can't possibly implement `FnPtr` as they are concrete types
657                // and not `FnPtr`
658                ty::Bool
659                | ty::Char
660                | ty::Int(_)
661                | ty::Uint(_)
662                | ty::Float(_)
663                | ty::Adt(_, _)
664                | ty::Foreign(_)
665                | ty::Str
666                | ty::Array(_, _)
667                | ty::Pat(_, _)
668                | ty::Slice(_)
669                | ty::RawPtr(_, _)
670                | ty::Ref(_, _, _)
671                | ty::Closure(..)
672                | ty::CoroutineClosure(..)
673                | ty::Coroutine(_, _)
674                | ty::CoroutineWitness(..)
675                | ty::UnsafeBinder(_)
676                | ty::Never
677                | ty::Tuple(_)
678                | ty::Error(_) => return true,
679                // FIXME: Function definitions could actually implement `FnPtr` by
680                // casting the ZST function def to a function pointer.
681                ty::FnDef(_, _) => return true,
682            }
683
684            // Generic params can implement `FnPtr` if the predicate
685            // holds within its own environment.
686            let obligation = Obligation::new(
687                self.tcx(),
688                obligation.cause.clone(),
689                obligation.param_env,
690                self.tcx().mk_predicate(obligation.predicate.map_bound(|mut pred| {
691                    pred.trait_ref =
692                        ty::TraitRef::new(self.tcx(), fn_ptr_trait, [pred.trait_ref.self_ty()]);
693                    ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred))
694                })),
695            );
696            if let Ok(r) = self.evaluate_root_obligation(&obligation) {
697                if !r.may_apply() {
698                    return true;
699                }
700            }
701        }
702        false
703    }
704
705    fn assemble_candidates_from_auto_impls(
706        &mut self,
707        obligation: &PolyTraitObligation<'tcx>,
708        candidates: &mut SelectionCandidateSet<'tcx>,
709    ) {
710        // Okay to skip binder here because the tests we do below do not involve bound regions.
711        let self_ty = obligation.self_ty().skip_binder();
712        debug!(?self_ty, "assemble_candidates_from_auto_impls");
713
714        let def_id = obligation.predicate.def_id();
715
716        let mut check_impls = || {
717            // Only consider auto impls if there are no manual impls for the root of `self_ty`.
718            //
719            // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
720            // for `&SomeType: Auto` exists. Due to E0321 the only crate where impls
721            // for `&SomeType: Auto` can be defined is the crate where `Auto` has been defined.
722            //
723            // Generally, we have to guarantee that for all `SimplifiedType`s the only crate
724            // which may define impls for that type is either the crate defining the type
725            // or the trait. This should be guaranteed by the orphan check.
726            let mut has_impl = false;
727            self.tcx().for_each_relevant_impl(def_id, self_ty, |_| has_impl = true);
728            if !has_impl {
729                candidates.vec.push(AutoImplCandidate)
730            }
731        };
732
733        if self.tcx().trait_is_auto(def_id) {
734            match *self_ty.kind() {
735                ty::Dynamic(..) => {
736                    // For object types, we don't know what the closed
737                    // over types are. This means we conservatively
738                    // say nothing; a candidate may be added by
739                    // `assemble_candidates_from_object_ty`.
740                }
741                ty::Foreign(..) => {
742                    // Since the contents of foreign types is unknown,
743                    // we don't add any `..` impl. Default traits could
744                    // still be provided by a manual implementation for
745                    // this trait and type.
746
747                    // Backward compatibility for default auto traits.
748                    // Test: ui/traits/default_auto_traits/extern-types.rs
749                    if self.tcx().is_default_trait(def_id) {
750                        check_impls()
751                    }
752                }
753                ty::Param(..)
754                | ty::Alias(ty::Projection | ty::Inherent | ty::Free, ..)
755                | ty::Placeholder(..)
756                | ty::Bound(..) => {
757                    // In these cases, we don't know what the actual
758                    // type is. Therefore, we cannot break it down
759                    // into its constituent types. So we don't
760                    // consider the `..` impl but instead just add no
761                    // candidates: this means that typeck will only
762                    // succeed if there is another reason to believe
763                    // that this obligation holds. That could be a
764                    // where-clause or, in the case of an object type,
765                    // it could be that the object type lists the
766                    // trait (e.g., `Foo+Send : Send`). See
767                    // `ui/typeck/typeck-default-trait-impl-send-param.rs`
768                    // for an example of a test case that exercises
769                    // this path.
770                }
771                ty::Infer(ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_)) => {
772                    // The auto impl might apply; we don't know.
773                    candidates.ambiguous = true;
774                }
775                ty::Coroutine(coroutine_def_id, _)
776                    if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
777                {
778                    match self.tcx().coroutine_movability(coroutine_def_id) {
779                        hir::Movability::Static => {
780                            // Immovable coroutines are never `Unpin`, so
781                            // suppress the normal auto-impl candidate for it.
782                        }
783                        hir::Movability::Movable => {
784                            // Movable coroutines are always `Unpin`, so add an
785                            // unconditional builtin candidate.
786                            candidates.vec.push(BuiltinCandidate { has_nested: false });
787                        }
788                    }
789                }
790
791                ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
792                    bug!(
793                        "asked to assemble auto trait candidates of unexpected type: {:?}",
794                        self_ty
795                    );
796                }
797
798                ty::Alias(ty::Opaque, alias) => {
799                    if candidates.vec.iter().any(|c| matches!(c, ProjectionCandidate(_))) {
800                        // We do not generate an auto impl candidate for `impl Trait`s which already
801                        // reference our auto trait.
802                        //
803                        // For example during candidate assembly for `impl Send: Send`, we don't have
804                        // to look at the constituent types for this opaque types to figure out that this
805                        // trivially holds.
806                        //
807                        // Note that this is only sound as projection candidates of opaque types
808                        // are always applicable for auto traits.
809                    } else if let TypingMode::Coherence = self.infcx.typing_mode() {
810                        // We do not emit auto trait candidates for opaque types in coherence.
811                        // Doing so can result in weird dependency cycles.
812                        candidates.ambiguous = true;
813                    } else if self.infcx.can_define_opaque_ty(alias.def_id) {
814                        // We do not emit auto trait candidates for opaque types in their defining scope, as
815                        // we need to know the hidden type first, which we can't reliably know within the defining
816                        // scope.
817                        candidates.ambiguous = true;
818                    } else {
819                        candidates.vec.push(AutoImplCandidate)
820                    }
821                }
822
823                ty::Bool
824                | ty::Char
825                | ty::Int(_)
826                | ty::Uint(_)
827                | ty::Float(_)
828                | ty::Str
829                | ty::Array(_, _)
830                | ty::Pat(_, _)
831                | ty::Slice(_)
832                | ty::Adt(..)
833                | ty::RawPtr(_, _)
834                | ty::Ref(..)
835                | ty::FnDef(..)
836                | ty::FnPtr(..)
837                | ty::Closure(..)
838                | ty::CoroutineClosure(..)
839                | ty::Coroutine(..)
840                | ty::Never
841                | ty::Tuple(_)
842                | ty::CoroutineWitness(..)
843                | ty::UnsafeBinder(_) => {
844                    // Only consider auto impls of unsafe traits when there are
845                    // no unsafe fields.
846                    if self.tcx().trait_def(def_id).safety.is_unsafe()
847                        && self_ty.has_unsafe_fields()
848                    {
849                        return;
850                    }
851
852                    check_impls();
853                }
854                ty::Error(_) => {
855                    candidates.vec.push(AutoImplCandidate);
856                }
857            }
858        }
859    }
860
861    /// Searches for impls that might apply to `obligation`.
862    fn assemble_candidates_from_object_ty(
863        &mut self,
864        obligation: &PolyTraitObligation<'tcx>,
865        candidates: &mut SelectionCandidateSet<'tcx>,
866    ) {
867        debug!(
868            self_ty = ?obligation.self_ty().skip_binder(),
869            "assemble_candidates_from_object_ty",
870        );
871
872        if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object {
873            return;
874        }
875
876        self.infcx.probe(|_snapshot| {
877            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
878            self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| {
879                let self_ty = placeholder_trait_predicate.self_ty();
880                let principal_trait_ref = match self_ty.kind() {
881                    ty::Dynamic(data, ..) => {
882                        if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
883                            debug!(
884                                "assemble_candidates_from_object_ty: matched builtin bound, \
885                             pushing candidate"
886                            );
887                            candidates.vec.push(BuiltinObjectCandidate);
888                            return;
889                        }
890
891                        if let Some(principal) = data.principal() {
892                            principal.with_self_ty(self.tcx(), self_ty)
893                        } else {
894                            // Only auto trait bounds exist.
895                            return;
896                        }
897                    }
898                    ty::Infer(ty::TyVar(_)) => {
899                        debug!("assemble_candidates_from_object_ty: ambiguous");
900                        candidates.ambiguous = true; // could wind up being an object type
901                        return;
902                    }
903                    _ => return,
904                };
905
906                debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
907
908                // Count only those upcast versions that match the trait-ref
909                // we are looking for. Specifically, do not only check for the
910                // correct trait, but also the correct type parameters.
911                // For example, we may be trying to upcast `Foo` to `Bar<i32>`,
912                // but `Foo` is declared as `trait Foo: Bar<u32>`.
913                let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
914                    .enumerate()
915                    .filter(|&(_, upcast_trait_ref)| {
916                        self.infcx.probe(|_| {
917                            self.match_normalize_trait_ref(
918                                obligation,
919                                placeholder_trait_predicate.trait_ref,
920                                upcast_trait_ref,
921                            )
922                            .is_ok()
923                        })
924                    })
925                    .map(|(idx, _)| ObjectCandidate(idx));
926
927                candidates.vec.extend(candidate_supertraits);
928            })
929        })
930    }
931
932    /// Searches for unsizing that might apply to `obligation`.
933    fn assemble_candidates_for_unsizing(
934        &mut self,
935        obligation: &PolyTraitObligation<'tcx>,
936        candidates: &mut SelectionCandidateSet<'tcx>,
937    ) {
938        // We currently never consider higher-ranked obligations e.g.
939        // `for<'a> &'a T: Unsize<Trait+'a>` to be implemented. This is not
940        // because they are a priori invalid, and we could potentially add support
941        // for them later, it's just that there isn't really a strong need for it.
942        // A `T: Unsize<U>` obligation is always used as part of a `T: CoerceUnsize<U>`
943        // impl, and those are generally applied to concrete types.
944        //
945        // That said, one might try to write a fn with a where clause like
946        //     for<'a> Foo<'a, T>: Unsize<Foo<'a, Trait>>
947        // where the `'a` is kind of orthogonal to the relevant part of the `Unsize`.
948        // Still, you'd be more likely to write that where clause as
949        //     T: Trait
950        // so it seems ok if we (conservatively) fail to accept that `Unsize`
951        // obligation above. Should be possible to extend this in the future.
952        let Some(trait_pred) = obligation.predicate.no_bound_vars() else {
953            // Don't add any candidates if there are bound regions.
954            return;
955        };
956        let source = trait_pred.self_ty();
957        let target = trait_pred.trait_ref.args.type_at(1);
958
959        debug!(?source, ?target, "assemble_candidates_for_unsizing");
960
961        match (source.kind(), target.kind()) {
962            // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
963            (&ty::Dynamic(a_data, a_region, ty::Dyn), &ty::Dynamic(b_data, b_region, ty::Dyn)) => {
964                // Upcast coercions permit several things:
965                //
966                // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
967                // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b`
968                // 3. Tightening trait to its super traits, eg. `Foo` to `Bar` if `Foo: Bar`
969                //
970                // Note that neither of the first two of these changes requires any
971                // change at runtime. The third needs to change pointer metadata at runtime.
972                //
973                // We always perform upcasting coercions when we can because of reason
974                // #2 (region bounds).
975                let principal_def_id_a = a_data.principal_def_id();
976                let principal_def_id_b = b_data.principal_def_id();
977                if principal_def_id_a == principal_def_id_b || principal_def_id_b.is_none() {
978                    // We may upcast to auto traits that are either explicitly listed in
979                    // the object type's bounds, or implied by the principal trait ref's
980                    // supertraits.
981                    let a_auto_traits: FxIndexSet<DefId> = a_data
982                        .auto_traits()
983                        .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| {
984                            elaborate::supertrait_def_ids(self.tcx(), principal_def_id)
985                                .filter(|def_id| self.tcx().trait_is_auto(*def_id))
986                        }))
987                        .collect();
988                    let auto_traits_compatible = b_data
989                        .auto_traits()
990                        // All of a's auto traits need to be in b's auto traits.
991                        .all(|b| a_auto_traits.contains(&b));
992                    if auto_traits_compatible {
993                        candidates.vec.push(BuiltinUnsizeCandidate);
994                    }
995                } else if principal_def_id_a.is_some() && principal_def_id_b.is_some() {
996                    // not casual unsizing, now check whether this is trait upcasting coercion.
997                    let principal_a = a_data.principal().unwrap();
998                    let target_trait_did = principal_def_id_b.unwrap();
999                    let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
1000
1001                    for (idx, upcast_trait_ref) in
1002                        util::supertraits(self.tcx(), source_trait_ref).enumerate()
1003                    {
1004                        self.infcx.probe(|_| {
1005                            if upcast_trait_ref.def_id() == target_trait_did
1006                                && let Ok(nested) = self.match_upcast_principal(
1007                                    obligation,
1008                                    upcast_trait_ref,
1009                                    a_data,
1010                                    b_data,
1011                                    a_region,
1012                                    b_region,
1013                                )
1014                            {
1015                                if nested.is_none() {
1016                                    candidates.ambiguous = true;
1017                                }
1018                                candidates.vec.push(TraitUpcastingUnsizeCandidate(idx));
1019                            }
1020                        })
1021                    }
1022                }
1023            }
1024
1025            // `T` -> `Trait`
1026            (_, &ty::Dynamic(_, _, ty::Dyn)) => {
1027                candidates.vec.push(BuiltinUnsizeCandidate);
1028            }
1029
1030            // Ambiguous handling is below `T` -> `Trait`, because inference
1031            // variables can still implement `Unsize<Trait>` and nested
1032            // obligations will have the final say (likely deferred).
1033            (&ty::Infer(ty::TyVar(_)), _) | (_, &ty::Infer(ty::TyVar(_))) => {
1034                debug!("assemble_candidates_for_unsizing: ambiguous");
1035                candidates.ambiguous = true;
1036            }
1037
1038            // `[T; n]` -> `[T]`
1039            (&ty::Array(..), &ty::Slice(_)) => {
1040                candidates.vec.push(BuiltinUnsizeCandidate);
1041            }
1042
1043            // `Struct<T>` -> `Struct<U>`
1044            (&ty::Adt(def_id_a, _), &ty::Adt(def_id_b, _)) if def_id_a.is_struct() => {
1045                if def_id_a == def_id_b {
1046                    candidates.vec.push(BuiltinUnsizeCandidate);
1047                }
1048            }
1049
1050            _ => {}
1051        };
1052    }
1053
1054    #[instrument(level = "debug", skip(self, obligation, candidates))]
1055    fn assemble_candidates_for_transmutability(
1056        &mut self,
1057        obligation: &PolyTraitObligation<'tcx>,
1058        candidates: &mut SelectionCandidateSet<'tcx>,
1059    ) {
1060        if obligation.predicate.has_non_region_param() {
1061            return;
1062        }
1063
1064        if obligation.has_non_region_infer() {
1065            candidates.ambiguous = true;
1066            return;
1067        }
1068
1069        candidates.vec.push(TransmutabilityCandidate);
1070    }
1071
1072    #[instrument(level = "debug", skip(self, obligation, candidates))]
1073    fn assemble_candidates_for_trait_alias(
1074        &mut self,
1075        obligation: &PolyTraitObligation<'tcx>,
1076        candidates: &mut SelectionCandidateSet<'tcx>,
1077    ) {
1078        // Okay to skip binder here because the tests we do below do not involve bound regions.
1079        let self_ty = obligation.self_ty().skip_binder();
1080        debug!(?self_ty);
1081
1082        let def_id = obligation.predicate.def_id();
1083
1084        if self.tcx().is_trait_alias(def_id) {
1085            candidates.vec.push(TraitAliasCandidate);
1086        }
1087    }
1088
1089    /// Assembles the trait which are built-in to the language itself:
1090    /// `Copy`, `Clone` and `Sized`.
1091    #[instrument(level = "debug", skip(self, candidates))]
1092    fn assemble_builtin_sized_candidate(
1093        &mut self,
1094        obligation: &PolyTraitObligation<'tcx>,
1095        candidates: &mut SelectionCandidateSet<'tcx>,
1096    ) {
1097        match self.sized_conditions(obligation) {
1098            BuiltinImplConditions::Where(nested) => {
1099                candidates
1100                    .vec
1101                    .push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() });
1102            }
1103            BuiltinImplConditions::None => {}
1104            BuiltinImplConditions::Ambiguous => {
1105                candidates.ambiguous = true;
1106            }
1107        }
1108    }
1109
1110    /// Assembles the trait which are built-in to the language itself:
1111    /// e.g. `Copy` and `Clone`.
1112    #[instrument(level = "debug", skip(self, candidates))]
1113    fn assemble_builtin_bound_candidates(
1114        &mut self,
1115        conditions: BuiltinImplConditions<'tcx>,
1116        candidates: &mut SelectionCandidateSet<'tcx>,
1117    ) {
1118        match conditions {
1119            BuiltinImplConditions::Where(nested) => {
1120                candidates
1121                    .vec
1122                    .push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() });
1123            }
1124            BuiltinImplConditions::None => {}
1125            BuiltinImplConditions::Ambiguous => {
1126                candidates.ambiguous = true;
1127            }
1128        }
1129    }
1130
1131    fn assemble_const_destruct_candidates(
1132        &mut self,
1133        _obligation: &PolyTraitObligation<'tcx>,
1134        candidates: &mut SelectionCandidateSet<'tcx>,
1135    ) {
1136        candidates.vec.push(BuiltinCandidate { has_nested: false });
1137    }
1138
1139    fn assemble_candidate_for_tuple(
1140        &mut self,
1141        obligation: &PolyTraitObligation<'tcx>,
1142        candidates: &mut SelectionCandidateSet<'tcx>,
1143    ) {
1144        let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
1145        match self_ty.kind() {
1146            ty::Tuple(_) => {
1147                candidates.vec.push(BuiltinCandidate { has_nested: false });
1148            }
1149            ty::Infer(ty::TyVar(_)) => {
1150                candidates.ambiguous = true;
1151            }
1152            ty::Bool
1153            | ty::Char
1154            | ty::Int(_)
1155            | ty::Uint(_)
1156            | ty::Float(_)
1157            | ty::Adt(_, _)
1158            | ty::Foreign(_)
1159            | ty::Str
1160            | ty::Array(_, _)
1161            | ty::Slice(_)
1162            | ty::RawPtr(_, _)
1163            | ty::Ref(_, _, _)
1164            | ty::FnDef(_, _)
1165            | ty::Pat(_, _)
1166            | ty::FnPtr(..)
1167            | ty::UnsafeBinder(_)
1168            | ty::Dynamic(_, _, _)
1169            | ty::Closure(..)
1170            | ty::CoroutineClosure(..)
1171            | ty::Coroutine(_, _)
1172            | ty::CoroutineWitness(..)
1173            | ty::Never
1174            | ty::Alias(..)
1175            | ty::Param(_)
1176            | ty::Bound(_, _)
1177            | ty::Error(_)
1178            | ty::Infer(_)
1179            | ty::Placeholder(_) => {}
1180        }
1181    }
1182
1183    fn assemble_candidates_for_fn_ptr_trait(
1184        &mut self,
1185        obligation: &PolyTraitObligation<'tcx>,
1186        candidates: &mut SelectionCandidateSet<'tcx>,
1187    ) {
1188        let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());
1189
1190        match self_ty.skip_binder().kind() {
1191            ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
1192            ty::Bool
1193            | ty::Char
1194            | ty::Int(_)
1195            | ty::Uint(_)
1196            | ty::Float(_)
1197            | ty::Adt(..)
1198            | ty::Foreign(..)
1199            | ty::Str
1200            | ty::Array(..)
1201            | ty::Pat(..)
1202            | ty::Slice(_)
1203            | ty::RawPtr(_, _)
1204            | ty::Ref(..)
1205            | ty::FnDef(..)
1206            | ty::Placeholder(..)
1207            | ty::Dynamic(..)
1208            | ty::Closure(..)
1209            | ty::CoroutineClosure(..)
1210            | ty::Coroutine(..)
1211            | ty::CoroutineWitness(..)
1212            | ty::UnsafeBinder(_)
1213            | ty::Never
1214            | ty::Tuple(..)
1215            | ty::Alias(..)
1216            | ty::Param(..)
1217            | ty::Bound(..)
1218            | ty::Error(_)
1219            | ty::Infer(
1220                ty::InferTy::IntVar(_)
1221                | ty::InferTy::FloatVar(_)
1222                | ty::InferTy::FreshIntTy(_)
1223                | ty::InferTy::FreshFloatTy(_),
1224            ) => {}
1225            ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) => {
1226                candidates.ambiguous = true;
1227            }
1228        }
1229    }
1230
1231    fn assemble_candidates_for_bikeshed_guaranteed_no_drop_trait(
1232        &mut self,
1233        obligation: &PolyTraitObligation<'tcx>,
1234        candidates: &mut SelectionCandidateSet<'tcx>,
1235    ) {
1236        match obligation.predicate.self_ty().skip_binder().kind() {
1237            ty::Ref(..)
1238            | ty::Adt(..)
1239            | ty::Tuple(_)
1240            | ty::Array(..)
1241            | ty::FnDef(..)
1242            | ty::FnPtr(..)
1243            | ty::Error(_)
1244            | ty::Uint(_)
1245            | ty::Int(_)
1246            | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
1247            | ty::Bool
1248            | ty::Float(_)
1249            | ty::Char
1250            | ty::RawPtr(..)
1251            | ty::Never
1252            | ty::Pat(..)
1253            | ty::Dynamic(..)
1254            | ty::Str
1255            | ty::Slice(_)
1256            | ty::Foreign(..)
1257            | ty::Alias(..)
1258            | ty::Param(_)
1259            | ty::Placeholder(..)
1260            | ty::Closure(..)
1261            | ty::CoroutineClosure(..)
1262            | ty::Coroutine(..)
1263            | ty::UnsafeBinder(_)
1264            | ty::CoroutineWitness(..)
1265            | ty::Bound(..) => {
1266                candidates.vec.push(BikeshedGuaranteedNoDropCandidate);
1267            }
1268
1269            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
1270                candidates.ambiguous = true;
1271            }
1272        }
1273    }
1274}