]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
Rollup merge of #93019 - 5225225:uppercase-suffix, r=wesleywiser
[rust.git] / compiler / rustc_trait_selection / src / 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 use rustc_hir as hir;
9 use rustc_hir::def_id::DefId;
10 use rustc_infer::traits::TraitEngine;
11 use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
12 use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
13 use rustc_middle::ty::print::with_no_trimmed_paths;
14 use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable};
15 use rustc_target::spec::abi::Abi;
16
17 use crate::traits;
18 use crate::traits::coherence::Conflict;
19 use crate::traits::query::evaluate_obligation::InferCtxtExt;
20 use crate::traits::{util, SelectionResult};
21 use crate::traits::{Ambiguous, ErrorReporting, Overflow, Unimplemented};
22
23 use super::BuiltinImplConditions;
24 use super::IntercrateAmbiguityCause;
25 use super::OverflowError;
26 use super::SelectionCandidate::{self, *};
27 use super::{EvaluatedCandidate, SelectionCandidateSet, SelectionContext, TraitObligationStack};
28
29 impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
30     #[instrument(level = "debug", skip(self))]
31     pub(super) fn candidate_from_obligation<'o>(
32         &mut self,
33         stack: &TraitObligationStack<'o, 'tcx>,
34     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
35         // Watch out for overflow. This intentionally bypasses (and does
36         // not update) the cache.
37         self.check_recursion_limit(&stack.obligation, &stack.obligation)?;
38
39         // Check the cache. Note that we freshen the trait-ref
40         // separately rather than using `stack.fresh_trait_ref` --
41         // this is because we want the unbound variables to be
42         // replaced with fresh types starting from index 0.
43         let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate);
44         debug!(?cache_fresh_trait_pred);
45         debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars());
46
47         if let Some(c) =
48             self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred)
49         {
50             debug!(candidate = ?c, "CACHE HIT");
51             return c;
52         }
53
54         // If no match, compute result and insert into cache.
55         //
56         // FIXME(nikomatsakis) -- this cache is not taking into
57         // account cycles that may have occurred in forming the
58         // candidate. I don't know of any specific problems that
59         // result but it seems awfully suspicious.
60         let (candidate, dep_node) =
61             self.in_task(|this| this.candidate_from_obligation_no_cache(stack));
62
63         debug!(?candidate, "CACHE MISS");
64         self.insert_candidate_cache(
65             stack.obligation.param_env,
66             cache_fresh_trait_pred,
67             dep_node,
68             candidate.clone(),
69         );
70         candidate
71     }
72
73     fn candidate_from_obligation_no_cache<'o>(
74         &mut self,
75         stack: &TraitObligationStack<'o, 'tcx>,
76     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
77         if let Some(conflict) = self.is_knowable(stack) {
78             debug!("coherence stage: not knowable");
79             if self.intercrate_ambiguity_causes.is_some() {
80                 debug!("evaluate_stack: intercrate_ambiguity_causes is some");
81                 // Heuristics: show the diagnostics when there are no candidates in crate.
82                 if let Ok(candidate_set) = self.assemble_candidates(stack) {
83                     let mut no_candidates_apply = true;
84
85                     for c in candidate_set.vec.iter() {
86                         if self.evaluate_candidate(stack, &c)?.may_apply() {
87                             no_candidates_apply = false;
88                             break;
89                         }
90                     }
91
92                     if !candidate_set.ambiguous && no_candidates_apply {
93                         let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
94                         let self_ty = trait_ref.self_ty();
95                         let (trait_desc, self_desc) = with_no_trimmed_paths(|| {
96                             let trait_desc = trait_ref.print_only_trait_path().to_string();
97                             let self_desc = if self_ty.has_concrete_skeleton() {
98                                 Some(self_ty.to_string())
99                             } else {
100                                 None
101                             };
102                             (trait_desc, self_desc)
103                         });
104                         let cause = if let Conflict::Upstream = conflict {
105                             IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
106                         } else {
107                             IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
108                         };
109                         debug!(?cause, "evaluate_stack: pushing cause");
110                         self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
111                     }
112                 }
113             }
114             return Ok(None);
115         }
116
117         let candidate_set = self.assemble_candidates(stack)?;
118
119         if candidate_set.ambiguous {
120             debug!("candidate set contains ambig");
121             return Ok(None);
122         }
123
124         let candidates = candidate_set.vec;
125
126         debug!(?stack, ?candidates, "assembled {} candidates", candidates.len());
127
128         // At this point, we know that each of the entries in the
129         // candidate set is *individually* applicable. Now we have to
130         // figure out if they contain mutual incompatibilities. This
131         // frequently arises if we have an unconstrained input type --
132         // for example, we are looking for `$0: Eq` where `$0` is some
133         // unconstrained type variable. In that case, we'll get a
134         // candidate which assumes $0 == int, one that assumes `$0 ==
135         // usize`, etc. This spells an ambiguity.
136
137         let mut candidates = self.filter_impls(candidates, stack.obligation);
138
139         // If there is more than one candidate, first winnow them down
140         // by considering extra conditions (nested obligations and so
141         // forth). We don't winnow if there is exactly one
142         // candidate. This is a relatively minor distinction but it
143         // can lead to better inference and error-reporting. An
144         // example would be if there was an impl:
145         //
146         //     impl<T:Clone> Vec<T> { fn push_clone(...) { ... } }
147         //
148         // and we were to see some code `foo.push_clone()` where `boo`
149         // is a `Vec<Bar>` and `Bar` does not implement `Clone`.  If
150         // we were to winnow, we'd wind up with zero candidates.
151         // Instead, we select the right impl now but report "`Bar` does
152         // not implement `Clone`".
153         if candidates.len() == 1 {
154             return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation);
155         }
156
157         // Winnow, but record the exact outcome of evaluation, which
158         // is needed for specialization. Propagate overflow if it occurs.
159         let mut candidates = candidates
160             .into_iter()
161             .map(|c| match self.evaluate_candidate(stack, &c) {
162                 Ok(eval) if eval.may_apply() => {
163                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
164                 }
165                 Ok(_) => Ok(None),
166                 Err(OverflowError::Canonical) => Err(Overflow),
167                 Err(OverflowError::ErrorReporting) => Err(ErrorReporting),
168             })
169             .flat_map(Result::transpose)
170             .collect::<Result<Vec<_>, _>>()?;
171
172         debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len());
173
174         let needs_infer = stack.obligation.predicate.has_infer_types_or_consts();
175
176         let sized_predicate = self.tcx().lang_items().sized_trait()
177             == Some(stack.obligation.predicate.skip_binder().def_id());
178
179         // If there are STILL multiple candidates, we can further
180         // reduce the list by dropping duplicates -- including
181         // resolving specializations.
182         if candidates.len() > 1 {
183             let mut i = 0;
184             while i < candidates.len() {
185                 let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| {
186                     self.candidate_should_be_dropped_in_favor_of(
187                         sized_predicate,
188                         &candidates[i],
189                         &candidates[j],
190                         needs_infer,
191                     )
192                 });
193                 if is_dup {
194                     debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len());
195                     candidates.swap_remove(i);
196                 } else {
197                     debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len());
198                     i += 1;
199
200                     // If there are *STILL* multiple candidates, give up
201                     // and report ambiguity.
202                     if i > 1 {
203                         debug!("multiple matches, ambig");
204                         return Err(Ambiguous(
205                             candidates
206                                 .into_iter()
207                                 .filter_map(|c| match c.candidate {
208                                     SelectionCandidate::ImplCandidate(def_id) => Some(def_id),
209                                     _ => None,
210                                 })
211                                 .collect(),
212                         ));
213                     }
214                 }
215             }
216         }
217
218         // If there are *NO* candidates, then there are no impls --
219         // that we know of, anyway. Note that in the case where there
220         // are unbound type variables within the obligation, it might
221         // be the case that you could still satisfy the obligation
222         // from another crate by instantiating the type variables with
223         // a type from another crate that does have an impl. This case
224         // is checked for in `evaluate_stack` (and hence users
225         // who might care about this case, like coherence, should use
226         // that function).
227         if candidates.is_empty() {
228             // If there's an error type, 'downgrade' our result from
229             // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid
230             // emitting additional spurious errors, since we're guaranteed
231             // to have emitted at least one.
232             if stack.obligation.references_error() {
233                 debug!("no results for error type, treating as ambiguous");
234                 return Ok(None);
235             }
236             return Err(Unimplemented);
237         }
238
239         // Just one candidate left.
240         self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation)
241     }
242
243     #[instrument(skip(self, stack), level = "debug")]
244     pub(super) fn assemble_candidates<'o>(
245         &mut self,
246         stack: &TraitObligationStack<'o, 'tcx>,
247     ) -> Result<SelectionCandidateSet<'tcx>, SelectionError<'tcx>> {
248         let TraitObligationStack { obligation, .. } = *stack;
249         let obligation = &Obligation {
250             param_env: obligation.param_env,
251             cause: obligation.cause.clone(),
252             recursion_depth: obligation.recursion_depth,
253             predicate: self.infcx().resolve_vars_if_possible(obligation.predicate),
254         };
255
256         if obligation.predicate.skip_binder().self_ty().is_ty_var() {
257             // Self is a type variable (e.g., `_: AsRef<str>`).
258             //
259             // This is somewhat problematic, as the current scheme can't really
260             // handle it turning to be a projection. This does end up as truly
261             // ambiguous in most cases anyway.
262             //
263             // Take the fast path out - this also improves
264             // performance by preventing assemble_candidates_from_impls from
265             // matching every impl for this trait.
266             return Ok(SelectionCandidateSet { vec: vec![], ambiguous: true });
267         }
268
269         let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
270
271         // The only way to prove a NotImplemented(T: Foo) predicate is via a negative impl.
272         // There are no compiler built-in rules for this.
273         if obligation.polarity() == ty::ImplPolarity::Negative {
274             self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
275             self.assemble_candidates_from_impls(obligation, &mut candidates);
276         } else {
277             self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
278
279             // Other bounds. Consider both in-scope bounds from fn decl
280             // and applicable impls. There is a certain set of precedence rules here.
281             let def_id = obligation.predicate.def_id();
282             let lang_items = self.tcx().lang_items();
283
284             if lang_items.copy_trait() == Some(def_id) {
285                 debug!(obligation_self_ty = ?obligation.predicate.skip_binder().self_ty());
286
287                 // User-defined copy impls are permitted, but only for
288                 // structs and enums.
289                 self.assemble_candidates_from_impls(obligation, &mut candidates);
290
291                 // For other types, we'll use the builtin rules.
292                 let copy_conditions = self.copy_clone_conditions(obligation);
293                 self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
294             } else if lang_items.discriminant_kind_trait() == Some(def_id) {
295                 // `DiscriminantKind` is automatically implemented for every type.
296                 candidates.vec.push(DiscriminantKindCandidate);
297             } else if lang_items.pointee_trait() == Some(def_id) {
298                 // `Pointee` is automatically implemented for every type.
299                 candidates.vec.push(PointeeCandidate);
300             } else if lang_items.sized_trait() == Some(def_id) {
301                 // Sized is never implementable by end-users, it is
302                 // always automatically computed.
303                 let sized_conditions = self.sized_conditions(obligation);
304                 self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
305             } else if lang_items.unsize_trait() == Some(def_id) {
306                 self.assemble_candidates_for_unsizing(obligation, &mut candidates);
307             } else if lang_items.drop_trait() == Some(def_id)
308                 && obligation.predicate.is_const_if_const()
309             {
310                 self.assemble_const_drop_candidates(obligation, &mut candidates);
311             } else {
312                 if lang_items.clone_trait() == Some(def_id) {
313                     // Same builtin conditions as `Copy`, i.e., every type which has builtin support
314                     // for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
315                     // types have builtin support for `Clone`.
316                     let clone_conditions = self.copy_clone_conditions(obligation);
317                     self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates);
318                 }
319
320                 self.assemble_generator_candidates(obligation, &mut candidates);
321                 self.assemble_closure_candidates(obligation, &mut candidates);
322                 self.assemble_fn_pointer_candidates(obligation, &mut candidates);
323                 self.assemble_candidates_from_impls(obligation, &mut candidates);
324                 self.assemble_candidates_from_object_ty(obligation, &mut candidates);
325             }
326
327             self.assemble_candidates_from_projected_tys(obligation, &mut candidates);
328             self.assemble_candidates_from_caller_bounds(stack, &mut candidates)?;
329             // Auto implementations have lower priority, so we only
330             // consider triggering a default if there is no other impl that can apply.
331             if candidates.vec.is_empty() {
332                 self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
333             }
334         }
335         debug!("candidate list size: {}", candidates.vec.len());
336         Ok(candidates)
337     }
338
339     #[tracing::instrument(level = "debug", skip(self, candidates))]
340     fn assemble_candidates_from_projected_tys(
341         &mut self,
342         obligation: &TraitObligation<'tcx>,
343         candidates: &mut SelectionCandidateSet<'tcx>,
344     ) {
345         // Before we go into the whole placeholder thing, just
346         // quickly check if the self-type is a projection at all.
347         match obligation.predicate.skip_binder().trait_ref.self_ty().kind() {
348             ty::Projection(_) | ty::Opaque(..) => {}
349             ty::Infer(ty::TyVar(_)) => {
350                 span_bug!(
351                     obligation.cause.span,
352                     "Self=_ should have been handled by assemble_candidates"
353                 );
354             }
355             _ => return,
356         }
357
358         let result = self
359             .infcx
360             .probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
361
362         candidates.vec.extend(result.into_iter().map(ProjectionCandidate));
363     }
364
365     /// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
366     /// supplied to find out whether it is listed among them.
367     ///
368     /// Never affects the inference environment.
369     #[tracing::instrument(level = "debug", skip(self, stack, candidates))]
370     fn assemble_candidates_from_caller_bounds<'o>(
371         &mut self,
372         stack: &TraitObligationStack<'o, 'tcx>,
373         candidates: &mut SelectionCandidateSet<'tcx>,
374     ) -> Result<(), SelectionError<'tcx>> {
375         debug!(?stack.obligation);
376
377         let all_bounds = stack
378             .obligation
379             .param_env
380             .caller_bounds()
381             .iter()
382             .filter_map(|o| o.to_opt_poly_trait_pred());
383
384         // Micro-optimization: filter out predicates relating to different traits.
385         let matching_bounds =
386             all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());
387
388         // Keep only those bounds which may apply, and propagate overflow if it occurs.
389         for bound in matching_bounds {
390             // FIXME(oli-obk): it is suspicious that we are dropping the constness and
391             // polarity here.
392             let wc = self.evaluate_where_clause(stack, bound.map_bound(|t| t.trait_ref))?;
393             if wc.may_apply() {
394                 candidates.vec.push(ParamCandidate(bound));
395             }
396         }
397
398         Ok(())
399     }
400
401     fn assemble_generator_candidates(
402         &mut self,
403         obligation: &TraitObligation<'tcx>,
404         candidates: &mut SelectionCandidateSet<'tcx>,
405     ) {
406         if self.tcx().lang_items().gen_trait() != Some(obligation.predicate.def_id()) {
407             return;
408         }
409
410         // Okay to skip binder because the substs on generator types never
411         // touch bound regions, they just capture the in-scope
412         // type/region parameters.
413         let self_ty = obligation.self_ty().skip_binder();
414         match self_ty.kind() {
415             ty::Generator(..) => {
416                 debug!(?self_ty, ?obligation, "assemble_generator_candidates",);
417
418                 candidates.vec.push(GeneratorCandidate);
419             }
420             ty::Infer(ty::TyVar(_)) => {
421                 debug!("assemble_generator_candidates: ambiguous self-type");
422                 candidates.ambiguous = true;
423             }
424             _ => {}
425         }
426     }
427
428     /// Checks for the artificial impl that the compiler will create for an obligation like `X :
429     /// FnMut<..>` where `X` is a closure type.
430     ///
431     /// Note: the type parameters on a closure candidate are modeled as *output* type
432     /// parameters and hence do not affect whether this trait is a match or not. They will be
433     /// unified during the confirmation step.
434     fn assemble_closure_candidates(
435         &mut self,
436         obligation: &TraitObligation<'tcx>,
437         candidates: &mut SelectionCandidateSet<'tcx>,
438     ) {
439         let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) {
440             Some(k) => k,
441             None => {
442                 return;
443             }
444         };
445
446         // Okay to skip binder because the substs on closure types never
447         // touch bound regions, they just capture the in-scope
448         // type/region parameters
449         match *obligation.self_ty().skip_binder().kind() {
450             ty::Closure(_, closure_substs) => {
451                 debug!(?kind, ?obligation, "assemble_unboxed_candidates");
452                 match self.infcx.closure_kind(closure_substs) {
453                     Some(closure_kind) => {
454                         debug!(?closure_kind, "assemble_unboxed_candidates");
455                         if closure_kind.extends(kind) {
456                             candidates.vec.push(ClosureCandidate);
457                         }
458                     }
459                     None => {
460                         debug!("assemble_unboxed_candidates: closure_kind not yet known");
461                         candidates.vec.push(ClosureCandidate);
462                     }
463                 }
464             }
465             ty::Infer(ty::TyVar(_)) => {
466                 debug!("assemble_unboxed_closure_candidates: ambiguous self-type");
467                 candidates.ambiguous = true;
468             }
469             _ => {}
470         }
471     }
472
473     /// Implements one of the `Fn()` family for a fn pointer.
474     fn assemble_fn_pointer_candidates(
475         &mut self,
476         obligation: &TraitObligation<'tcx>,
477         candidates: &mut SelectionCandidateSet<'tcx>,
478     ) {
479         // We provide impl of all fn traits for fn pointers.
480         if self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()).is_none() {
481             return;
482         }
483
484         // Okay to skip binder because what we are inspecting doesn't involve bound regions.
485         let self_ty = obligation.self_ty().skip_binder();
486         match *self_ty.kind() {
487             ty::Infer(ty::TyVar(_)) => {
488                 debug!("assemble_fn_pointer_candidates: ambiguous self-type");
489                 candidates.ambiguous = true; // Could wind up being a fn() type.
490             }
491             // Provide an impl, but only for suitable `fn` pointers.
492             ty::FnPtr(_) => {
493                 if let ty::FnSig {
494                     unsafety: hir::Unsafety::Normal,
495                     abi: Abi::Rust,
496                     c_variadic: false,
497                     ..
498                 } = self_ty.fn_sig(self.tcx()).skip_binder()
499                 {
500                     candidates.vec.push(FnPointerCandidate { is_const: false });
501                 }
502             }
503             // Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
504             ty::FnDef(def_id, _) => {
505                 if let ty::FnSig {
506                     unsafety: hir::Unsafety::Normal,
507                     abi: Abi::Rust,
508                     c_variadic: false,
509                     ..
510                 } = self_ty.fn_sig(self.tcx()).skip_binder()
511                 {
512                     if self.tcx().codegen_fn_attrs(def_id).target_features.is_empty() {
513                         candidates
514                             .vec
515                             .push(FnPointerCandidate { is_const: self.tcx().is_const_fn(def_id) });
516                     }
517                 }
518             }
519             _ => {}
520         }
521     }
522
523     /// Searches for impls that might apply to `obligation`.
524     fn assemble_candidates_from_impls(
525         &mut self,
526         obligation: &TraitObligation<'tcx>,
527         candidates: &mut SelectionCandidateSet<'tcx>,
528     ) {
529         debug!(?obligation, "assemble_candidates_from_impls");
530
531         // Essentially any user-written impl will match with an error type,
532         // so creating `ImplCandidates` isn't useful. However, we might
533         // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized)
534         // This helps us avoid overflow: see issue #72839
535         // Since compilation is already guaranteed to fail, this is just
536         // to try to show the 'nicest' possible errors to the user.
537         // We don't check for errors in the `ParamEnv` - in practice,
538         // it seems to cause us to be overly aggressive in deciding
539         // to give up searching for candidates, leading to spurious errors.
540         if obligation.predicate.references_error() {
541             return;
542         }
543
544         self.tcx().for_each_relevant_impl(
545             obligation.predicate.def_id(),
546             obligation.predicate.skip_binder().trait_ref.self_ty(),
547             |impl_def_id| {
548                 self.infcx.probe(|_| {
549                     if let Ok(_substs) = self.match_impl(impl_def_id, obligation) {
550                         candidates.vec.push(ImplCandidate(impl_def_id));
551                     }
552                 });
553             },
554         );
555     }
556
557     fn assemble_candidates_from_auto_impls(
558         &mut self,
559         obligation: &TraitObligation<'tcx>,
560         candidates: &mut SelectionCandidateSet<'tcx>,
561     ) {
562         // Okay to skip binder here because the tests we do below do not involve bound regions.
563         let self_ty = obligation.self_ty().skip_binder();
564         debug!(?self_ty, "assemble_candidates_from_auto_impls");
565
566         let def_id = obligation.predicate.def_id();
567
568         if self.tcx().trait_is_auto(def_id) {
569             match self_ty.kind() {
570                 ty::Dynamic(..) => {
571                     // For object types, we don't know what the closed
572                     // over types are. This means we conservatively
573                     // say nothing; a candidate may be added by
574                     // `assemble_candidates_from_object_ty`.
575                 }
576                 ty::Foreign(..) => {
577                     // Since the contents of foreign types is unknown,
578                     // we don't add any `..` impl. Default traits could
579                     // still be provided by a manual implementation for
580                     // this trait and type.
581                 }
582                 ty::Param(..) | ty::Projection(..) => {
583                     // In these cases, we don't know what the actual
584                     // type is.  Therefore, we cannot break it down
585                     // into its constituent types. So we don't
586                     // consider the `..` impl but instead just add no
587                     // candidates: this means that typeck will only
588                     // succeed if there is another reason to believe
589                     // that this obligation holds. That could be a
590                     // where-clause or, in the case of an object type,
591                     // it could be that the object type lists the
592                     // trait (e.g., `Foo+Send : Send`). See
593                     // `ui/typeck/typeck-default-trait-impl-send-param.rs`
594                     // for an example of a test case that exercises
595                     // this path.
596                 }
597                 ty::Infer(ty::TyVar(_)) => {
598                     // The auto impl might apply; we don't know.
599                     candidates.ambiguous = true;
600                 }
601                 ty::Generator(_, _, movability)
602                     if self.tcx().lang_items().unpin_trait() == Some(def_id) =>
603                 {
604                     match movability {
605                         hir::Movability::Static => {
606                             // Immovable generators are never `Unpin`, so
607                             // suppress the normal auto-impl candidate for it.
608                         }
609                         hir::Movability::Movable => {
610                             // Movable generators are always `Unpin`, so add an
611                             // unconditional builtin candidate.
612                             candidates.vec.push(BuiltinCandidate { has_nested: false });
613                         }
614                     }
615                 }
616
617                 _ => candidates.vec.push(AutoImplCandidate(def_id)),
618             }
619         }
620     }
621
622     /// Searches for impls that might apply to `obligation`.
623     fn assemble_candidates_from_object_ty(
624         &mut self,
625         obligation: &TraitObligation<'tcx>,
626         candidates: &mut SelectionCandidateSet<'tcx>,
627     ) {
628         debug!(
629             self_ty = ?obligation.self_ty().skip_binder(),
630             "assemble_candidates_from_object_ty",
631         );
632
633         self.infcx.probe(|_snapshot| {
634             // The code below doesn't care about regions, and the
635             // self-ty here doesn't escape this probe, so just erase
636             // any LBR.
637             let self_ty = self.tcx().erase_late_bound_regions(obligation.self_ty());
638             let poly_trait_ref = match self_ty.kind() {
639                 ty::Dynamic(ref data, ..) => {
640                     if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
641                         debug!(
642                             "assemble_candidates_from_object_ty: matched builtin bound, \
643                              pushing candidate"
644                         );
645                         candidates.vec.push(BuiltinObjectCandidate);
646                         return;
647                     }
648
649                     if let Some(principal) = data.principal() {
650                         if !self.infcx.tcx.features().object_safe_for_dispatch {
651                             principal.with_self_ty(self.tcx(), self_ty)
652                         } else if self.tcx().is_object_safe(principal.def_id()) {
653                             principal.with_self_ty(self.tcx(), self_ty)
654                         } else {
655                             return;
656                         }
657                     } else {
658                         // Only auto trait bounds exist.
659                         return;
660                     }
661                 }
662                 ty::Infer(ty::TyVar(_)) => {
663                     debug!("assemble_candidates_from_object_ty: ambiguous");
664                     candidates.ambiguous = true; // could wind up being an object type
665                     return;
666                 }
667                 _ => return,
668             };
669
670             debug!(?poly_trait_ref, "assemble_candidates_from_object_ty");
671
672             let poly_trait_predicate = self.infcx().resolve_vars_if_possible(obligation.predicate);
673             let placeholder_trait_predicate =
674                 self.infcx().replace_bound_vars_with_placeholders(poly_trait_predicate);
675
676             // Count only those upcast versions that match the trait-ref
677             // we are looking for. Specifically, do not only check for the
678             // correct trait, but also the correct type parameters.
679             // For example, we may be trying to upcast `Foo` to `Bar<i32>`,
680             // but `Foo` is declared as `trait Foo: Bar<u32>`.
681             let candidate_supertraits = util::supertraits(self.tcx(), poly_trait_ref)
682                 .enumerate()
683                 .filter(|&(_, upcast_trait_ref)| {
684                     self.infcx.probe(|_| {
685                         self.match_normalize_trait_ref(
686                             obligation,
687                             upcast_trait_ref,
688                             placeholder_trait_predicate.trait_ref,
689                         )
690                         .is_ok()
691                     })
692                 })
693                 .map(|(idx, _)| ObjectCandidate(idx));
694
695             candidates.vec.extend(candidate_supertraits);
696         })
697     }
698
699     /// Temporary migration for #89190
700     fn need_migrate_deref_output_trait_object(
701         &mut self,
702         ty: Ty<'tcx>,
703         cause: &traits::ObligationCause<'tcx>,
704         param_env: ty::ParamEnv<'tcx>,
705     ) -> Option<(Ty<'tcx>, DefId)> {
706         let tcx = self.tcx();
707         if tcx.features().trait_upcasting {
708             return None;
709         }
710
711         // <ty as Deref>
712         let trait_ref = ty::TraitRef {
713             def_id: tcx.lang_items().deref_trait()?,
714             substs: tcx.mk_substs_trait(ty, &[]),
715         };
716
717         let obligation = traits::Obligation::new(
718             cause.clone(),
719             param_env,
720             ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
721         );
722         if !self.infcx.predicate_may_hold(&obligation) {
723             return None;
724         }
725
726         let mut fulfillcx = traits::FulfillmentContext::new_in_snapshot();
727         let normalized_ty = fulfillcx.normalize_projection_type(
728             &self.infcx,
729             param_env,
730             ty::ProjectionTy {
731                 item_def_id: tcx.lang_items().deref_target()?,
732                 substs: trait_ref.substs,
733             },
734             cause.clone(),
735         );
736
737         let ty::Dynamic(data, ..) = normalized_ty.kind() else {
738             return None;
739         };
740
741         let def_id = data.principal_def_id()?;
742
743         return Some((normalized_ty, def_id));
744     }
745
746     /// Searches for unsizing that might apply to `obligation`.
747     fn assemble_candidates_for_unsizing(
748         &mut self,
749         obligation: &TraitObligation<'tcx>,
750         candidates: &mut SelectionCandidateSet<'tcx>,
751     ) {
752         // We currently never consider higher-ranked obligations e.g.
753         // `for<'a> &'a T: Unsize<Trait+'a>` to be implemented. This is not
754         // because they are a priori invalid, and we could potentially add support
755         // for them later, it's just that there isn't really a strong need for it.
756         // A `T: Unsize<U>` obligation is always used as part of a `T: CoerceUnsize<U>`
757         // impl, and those are generally applied to concrete types.
758         //
759         // That said, one might try to write a fn with a where clause like
760         //     for<'a> Foo<'a, T>: Unsize<Foo<'a, Trait>>
761         // where the `'a` is kind of orthogonal to the relevant part of the `Unsize`.
762         // Still, you'd be more likely to write that where clause as
763         //     T: Trait
764         // so it seems ok if we (conservatively) fail to accept that `Unsize`
765         // obligation above. Should be possible to extend this in the future.
766         let source = match obligation.self_ty().no_bound_vars() {
767             Some(t) => t,
768             None => {
769                 // Don't add any candidates if there are bound regions.
770                 return;
771             }
772         };
773         let target = obligation.predicate.skip_binder().trait_ref.substs.type_at(1);
774
775         debug!(?source, ?target, "assemble_candidates_for_unsizing");
776
777         match (source.kind(), target.kind()) {
778             // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
779             (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
780                 // Upcast coercions permit several things:
781                 //
782                 // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
783                 // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b`
784                 // 3. Tightening trait to its super traits, eg. `Foo` to `Bar` if `Foo: Bar`
785                 //
786                 // Note that neither of the first two of these changes requires any
787                 // change at runtime. The third needs to change pointer metadata at runtime.
788                 //
789                 // We always perform upcasting coercions when we can because of reason
790                 // #2 (region bounds).
791                 let auto_traits_compatible = data_b
792                     .auto_traits()
793                     // All of a's auto traits need to be in b's auto traits.
794                     .all(|b| data_a.auto_traits().any(|a| a == b));
795                 if auto_traits_compatible {
796                     let principal_def_id_a = data_a.principal_def_id();
797                     let principal_def_id_b = data_b.principal_def_id();
798                     if principal_def_id_a == principal_def_id_b {
799                         // no cyclic
800                         candidates.vec.push(BuiltinUnsizeCandidate);
801                     } else if principal_def_id_a.is_some() && principal_def_id_b.is_some() {
802                         // not casual unsizing, now check whether this is trait upcasting coercion.
803                         let principal_a = data_a.principal().unwrap();
804                         let target_trait_did = principal_def_id_b.unwrap();
805                         let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
806                         if let Some((deref_output_ty, deref_output_trait_did)) = self
807                             .need_migrate_deref_output_trait_object(
808                                 source,
809                                 &obligation.cause,
810                                 obligation.param_env,
811                             )
812                         {
813                             if deref_output_trait_did == target_trait_did {
814                                 self.tcx().struct_span_lint_hir(
815                                     DEREF_INTO_DYN_SUPERTRAIT,
816                                     obligation.cause.body_id,
817                                     obligation.cause.span,
818                                     |lint| {
819                                         lint.build(&format!(
820                                             "`{}` implements `Deref` with supertrait `{}` as output",
821                                             source,
822                                             deref_output_ty
823                                         )).emit();
824                                     },
825                                 );
826                                 return;
827                             }
828                         }
829
830                         for (idx, upcast_trait_ref) in
831                             util::supertraits(self.tcx(), source_trait_ref).enumerate()
832                         {
833                             if upcast_trait_ref.def_id() == target_trait_did {
834                                 candidates.vec.push(TraitUpcastingUnsizeCandidate(idx));
835                             }
836                         }
837                     }
838                 }
839             }
840
841             // `T` -> `Trait`
842             (_, &ty::Dynamic(..)) => {
843                 candidates.vec.push(BuiltinUnsizeCandidate);
844             }
845
846             // Ambiguous handling is below `T` -> `Trait`, because inference
847             // variables can still implement `Unsize<Trait>` and nested
848             // obligations will have the final say (likely deferred).
849             (&ty::Infer(ty::TyVar(_)), _) | (_, &ty::Infer(ty::TyVar(_))) => {
850                 debug!("assemble_candidates_for_unsizing: ambiguous");
851                 candidates.ambiguous = true;
852             }
853
854             // `[T; n]` -> `[T]`
855             (&ty::Array(..), &ty::Slice(_)) => {
856                 candidates.vec.push(BuiltinUnsizeCandidate);
857             }
858
859             // `Struct<T>` -> `Struct<U>`
860             (&ty::Adt(def_id_a, _), &ty::Adt(def_id_b, _)) if def_id_a.is_struct() => {
861                 if def_id_a == def_id_b {
862                     candidates.vec.push(BuiltinUnsizeCandidate);
863                 }
864             }
865
866             // `(.., T)` -> `(.., U)`
867             (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
868                 if tys_a.len() == tys_b.len() {
869                     candidates.vec.push(BuiltinUnsizeCandidate);
870                 }
871             }
872
873             _ => {}
874         };
875     }
876
877     #[tracing::instrument(level = "debug", skip(self, obligation, candidates))]
878     fn assemble_candidates_for_trait_alias(
879         &mut self,
880         obligation: &TraitObligation<'tcx>,
881         candidates: &mut SelectionCandidateSet<'tcx>,
882     ) {
883         // Okay to skip binder here because the tests we do below do not involve bound regions.
884         let self_ty = obligation.self_ty().skip_binder();
885         debug!(?self_ty);
886
887         let def_id = obligation.predicate.def_id();
888
889         if self.tcx().is_trait_alias(def_id) {
890             candidates.vec.push(TraitAliasCandidate(def_id));
891         }
892     }
893
894     /// Assembles the trait which are built-in to the language itself:
895     /// `Copy`, `Clone` and `Sized`.
896     #[tracing::instrument(level = "debug", skip(self, candidates))]
897     fn assemble_builtin_bound_candidates(
898         &mut self,
899         conditions: BuiltinImplConditions<'tcx>,
900         candidates: &mut SelectionCandidateSet<'tcx>,
901     ) {
902         match conditions {
903             BuiltinImplConditions::Where(nested) => {
904                 candidates
905                     .vec
906                     .push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() });
907             }
908             BuiltinImplConditions::None => {}
909             BuiltinImplConditions::Ambiguous => {
910                 candidates.ambiguous = true;
911             }
912         }
913     }
914
915     fn assemble_const_drop_candidates(
916         &mut self,
917         obligation: &TraitObligation<'tcx>,
918         candidates: &mut SelectionCandidateSet<'tcx>,
919     ) {
920         // If the predicate is `~const Drop` in a non-const environment, we don't actually need
921         // to check anything. We'll short-circuit checking any obligations in confirmation, too.
922         if obligation.param_env.constness() == hir::Constness::NotConst {
923             candidates.vec.push(ConstDropCandidate(None));
924             return;
925         }
926
927         let self_ty = self.infcx().shallow_resolve(obligation.self_ty());
928         match self_ty.skip_binder().kind() {
929             ty::Opaque(..)
930             | ty::Dynamic(..)
931             | ty::Error(_)
932             | ty::Bound(..)
933             | ty::Param(_)
934             | ty::Placeholder(_)
935             | ty::Projection(_) => {
936                 // We don't know if these are `~const Drop`, at least
937                 // not structurally... so don't push a candidate.
938             }
939
940             ty::Bool
941             | ty::Char
942             | ty::Int(_)
943             | ty::Uint(_)
944             | ty::Float(_)
945             | ty::Infer(ty::IntVar(_))
946             | ty::Infer(ty::FloatVar(_))
947             | ty::Str
948             | ty::RawPtr(_)
949             | ty::Ref(..)
950             | ty::FnDef(..)
951             | ty::FnPtr(_)
952             | ty::Never
953             | ty::Foreign(_)
954             | ty::Array(..)
955             | ty::Slice(_)
956             | ty::Closure(..)
957             | ty::Generator(..)
958             | ty::Tuple(_)
959             | ty::GeneratorWitness(_) => {
960                 // These are built-in, and cannot have a custom `impl const Drop`.
961                 candidates.vec.push(ConstDropCandidate(None));
962             }
963
964             ty::Adt(..) => {
965                 // Find a custom `impl Drop` impl, if it exists
966                 let relevant_impl = self.tcx().find_map_relevant_impl(
967                     obligation.predicate.def_id(),
968                     obligation.predicate.skip_binder().trait_ref.self_ty(),
969                     Some,
970                 );
971
972                 if let Some(impl_def_id) = relevant_impl {
973                     // Check that `impl Drop` is actually const, if there is a custom impl
974                     if self.tcx().impl_constness(impl_def_id) == hir::Constness::Const {
975                         candidates.vec.push(ConstDropCandidate(Some(impl_def_id)));
976                     }
977                 } else {
978                     // Otherwise check the ADT like a built-in type (structurally)
979                     candidates.vec.push(ConstDropCandidate(None));
980                 }
981             }
982
983             ty::Infer(_) => {
984                 candidates.ambiguous = true;
985             }
986         }
987     }
988 }