1use rustc_type_ir::data_structures::IndexSet;
4use rustc_type_ir::fast_reject::DeepRejectCtxt;
5use rustc_type_ir::inherent::*;
6use rustc_type_ir::lang_items::SolverTraitLangItem;
7use rustc_type_ir::solve::{
8 AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, MaybeInfo,
9 NoSolutionOrRerunNonErased, OpaqueTypesJank, QueryResultOrRerunNonErased, RerunNonErased,
10 RerunReason, RerunResultExt, SizedTraitKind,
11};
12use rustc_type_ir::{
13 self as ty, ClausePolarity, ExistentialPredicate, FieldInfo, Interner, MayBeErased, Movability,
14 Region, TraitClause, TraitRef, TypeVisitableExt as _, TypingMode, Unnormalized, Upcast as _,
15 elaborate,
16};
17use tracing::{debug, instrument, trace, warn};
18
19use crate::delegate::SolverDelegate;
20use crate::solve::assembly::structural_traits::{self, AsyncCallableRelevantTypes};
21use crate::solve::assembly::{
22 self, AllowInferenceConstraints, AssembleCandidatesFrom, Candidate, FailedCandidateInfo,
23};
24use crate::solve::inspect::ProbeKind;
25use crate::solve::{
26 BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
27 MergeCandidateInfo, NoSolution, ParamEnvSource, StalledOnCoroutines,
28 has_only_region_constraints,
29};
30
31impl<D, I> assembly::GoalKind<D> for TraitClause<I>
32where
33 D: SolverDelegate<Interner = I>,
34 I: Interner,
35{
36 fn self_ty(self) -> I::Ty {
37 self.self_ty()
38 }
39
40 fn trait_ref(self, _: I) -> ty::TraitRef<I> {
41 self.trait_ref
42 }
43
44 fn with_replaced_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
45 self.with_replaced_self_ty(cx, self_ty)
46 }
47
48 fn trait_def_id(self, _: I) -> I::TraitId {
49 self.def_id()
50 }
51
52 fn consider_additional_alias_assumptions(
53 _ecx: &mut EvalCtxt<'_, D>,
54 _goal: Goal<I, Self>,
55 _alias_ty: ty::AliasTy<I>,
56 ) -> Vec<Candidate<I>> {
57 ::alloc::vec::Vec::new()vec![]
58 }
59
60 fn consider_impl_candidate(
61 ecx: &mut EvalCtxt<'_, D>,
62 goal: Goal<I, TraitClause<I>>,
63 goal_trait_ref: TraitRef<I>,
64 impl_def_id: I::ImplId,
65 then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
66 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
67 let cx = ecx.cx();
68
69 let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
70 if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
71 .args_may_unify(goal_trait_ref.args, impl_trait_ref.skip_binder().args)
72 {
73 return Err(NoSolution.into());
74 }
75
76 if cx.impl_is_default(impl_def_id) {
80 return Err(NoSolution.into());
81 }
82
83 match (cx.impl_polarity(impl_def_id), goal.predicate.polarity) {
84 (ty::ImplPolarity::Positive, ty::ClausePolarity::Positive)
86 | (ty::ImplPolarity::Negative, ty::ClausePolarity::Negative) => {}
87
88 (ty::ImplPolarity::Positive, ty::ClausePolarity::Negative)
90 | (ty::ImplPolarity::Negative, ty::ClausePolarity::Positive) => {
91 return Err(NoSolution.into());
92 }
93 }
94
95 if ecx.typing_mode().is_reflection() && !cx.is_fully_generic_for_reflection(impl_def_id) {
96 return Err(NoSolution.into());
97 }
98
99 ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
100 let impl_args = ecx.fresh_args_for_item(impl_def_id.into());
101 ecx.record_impl_args(impl_args);
102 let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args).skip_norm_wip();
103
104 ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
105 let where_clause_bounds = cx
106 .clauses_of(impl_def_id.into())
107 .iter_instantiated(cx, impl_args)
108 .map(Unnormalized::skip_norm_wip)
109 .map(|clause| goal.with(cx, clause));
110 ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds)?;
111
112 ecx.add_goals(
116 GoalSource::Misc,
117 cx.impl_super_outlives(impl_def_id)
118 .iter_instantiated(cx, impl_args)
119 .map(Unnormalized::skip_norm_wip)
120 .map(|pred| goal.with(cx, pred)),
121 )?;
122
123 then(ecx)
124 })
125 }
126
127 fn consider_error_guaranteed_candidate(
128 ecx: &mut EvalCtxt<'_, D>,
129 _goal: Goal<I, Self>,
130 _guar: I::ErrorGuaranteed,
131 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
132 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
133 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
134 }
135
136 fn fast_reject_assumption(
137 ecx: &mut EvalCtxt<'_, D>,
138 goal: Goal<I, Self>,
139 assumption: I::Clause,
140 ) -> Result<(), NoSolution> {
141 fn trait_def_id_matches<I: Interner>(
142 cx: I,
143 clause_def_id: I::TraitId,
144 goal_def_id: I::TraitId,
145 polarity: ClausePolarity,
146 ) -> bool {
147 clause_def_id == goal_def_id
148 || (polarity == ClausePolarity::Positive
153 && cx.is_trait_lang_item(clause_def_id, SolverTraitLangItem::Sized)
154 && cx.is_trait_lang_item(goal_def_id, SolverTraitLangItem::MetaSized))
155 }
156
157 if let Some(trait_clause) = assumption.as_trait_clause()
158 && trait_clause.polarity() == goal.predicate.polarity
159 && trait_def_id_matches(
160 ecx.cx(),
161 trait_clause.def_id(),
162 goal.predicate.def_id(),
163 goal.predicate.polarity,
164 )
165 && DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
166 goal.predicate.trait_ref.args,
167 trait_clause.skip_binder().trait_ref.args,
168 )
169 {
170 return Ok(());
171 } else {
172 Err(NoSolution)
173 }
174 }
175
176 fn match_assumption(
177 ecx: &mut EvalCtxt<'_, D>,
178 goal: Goal<I, Self>,
179 assumption: I::Clause,
180 then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResultOrRerunNonErased<I>,
181 ) -> QueryResultOrRerunNonErased<I> {
182 let trait_clause = assumption.as_trait_clause().unwrap();
183
184 if ecx.cx().is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::MetaSized)
190 && ecx.cx().is_trait_lang_item(trait_clause.def_id(), SolverTraitLangItem::Sized)
191 {
192 let meta_sized_clause =
193 trait_predicate_with_def_id(ecx.cx(), trait_clause, goal.predicate.def_id());
194 return Self::match_assumption(ecx, goal, meta_sized_clause, then);
195 }
196
197 let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
198 ecx.eq(goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref)?;
199
200 then(ecx)
201 }
202
203 fn consider_auto_trait_candidate(
204 ecx: &mut EvalCtxt<'_, D>,
205 goal: Goal<I, Self>,
206 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
207 let cx = ecx.cx();
208 if goal.predicate.polarity != ty::ClausePolarity::Positive {
209 return Err(NoSolution.into());
210 }
211
212 if let Some(result) = ecx.disqualify_auto_trait_candidate_due_to_possible_impl(goal) {
213 return result;
214 }
215
216 if cx.trait_is_unsafe(goal.predicate.def_id())
219 && goal.predicate.self_ty().has_unsafe_fields()
220 {
221 return Err(NoSolution.into());
222 }
223
224 if let ty::Alias(is_rigid, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) =
240 goal.predicate.self_ty().kind()
241 {
242 if true {
if !(is_rigid == ty::IsRigid::Yes) {
::core::panicking::panic("assertion failed: is_rigid == ty::IsRigid::Yes")
};
};debug_assert!(is_rigid == ty::IsRigid::Yes);
243 if ecx.opaque_accesses.might_rerun() {
244 match ecx.opaque_accesses.rerun_always(RerunReason::AutoTraitLeakage)? {}
245 }
246
247 for item_bound in cx.item_self_bounds(def_id.into()).skip_binder() {
248 if item_bound
249 .as_trait_clause()
250 .is_some_and(|b| b.def_id() == goal.predicate.def_id())
251 {
252 return Err(NoSolution.into());
253 }
254 }
255 }
256
257 if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
259 return cand;
260 }
261
262 ecx.probe_and_evaluate_goal_for_constituent_tys(
263 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
264 goal,
265 structural_traits::instantiate_constituent_tys_for_auto_trait,
266 )
267 }
268
269 fn consider_trait_alias_candidate(
270 ecx: &mut EvalCtxt<'_, D>,
271 goal: Goal<I, Self>,
272 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
273 if goal.predicate.polarity != ty::ClausePolarity::Positive {
274 return Err(NoSolution.into());
275 }
276
277 let cx = ecx.cx();
278
279 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
280 let nested_obligations = cx
281 .clauses_of(goal.predicate.def_id().into())
282 .iter_instantiated(cx, goal.predicate.trait_ref.args)
283 .map(Unnormalized::skip_norm_wip)
284 .map(|c| goal.with(cx, c));
285 ecx.add_goals(GoalSource::Misc, nested_obligations)?;
291 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
292 })
293 }
294
295 fn consider_builtin_sizedness_candidates(
296 ecx: &mut EvalCtxt<'_, D>,
297 goal: Goal<I, Self>,
298 sizedness: SizedTraitKind,
299 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
300 if goal.predicate.polarity != ty::ClausePolarity::Positive {
301 return Err(NoSolution.into());
302 }
303
304 ecx.probe_and_evaluate_goal_for_constituent_tys(
305 CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial),
306 goal,
307 |ecx, ty| {
308 structural_traits::instantiate_constituent_tys_for_sizedness_trait(
309 ecx, sizedness, ty,
310 )
311 },
312 )
313 }
314
315 fn consider_builtin_copy_clone_candidate(
316 ecx: &mut EvalCtxt<'_, D>,
317 goal: Goal<I, Self>,
318 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
319 if goal.predicate.polarity != ty::ClausePolarity::Positive {
320 return Err(NoSolution.into());
321 }
322
323 if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
325 return cand;
326 }
327
328 ecx.probe_and_evaluate_goal_for_constituent_tys(
329 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
330 goal,
331 structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
332 )
333 }
334
335 fn consider_builtin_fn_ptr_trait_candidate(
336 ecx: &mut EvalCtxt<'_, D>,
337 goal: Goal<I, Self>,
338 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
339 let self_ty = goal.predicate.self_ty();
340 match goal.predicate.polarity {
341 ty::ClausePolarity::Positive => {
343 if self_ty.is_fn_ptr() {
344 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
345 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
346 })
347 } else {
348 Err(NoSolution.into())
349 }
350 }
351 ty::ClausePolarity::Negative => {
353 if !self_ty.is_fn_ptr() && self_ty.is_known_rigid() {
356 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
357 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
358 })
359 } else {
360 Err(NoSolution.into())
361 }
362 }
363 }
364 }
365
366 fn consider_builtin_fn_trait_candidates(
367 ecx: &mut EvalCtxt<'_, D>,
368 goal: Goal<I, Self>,
369 goal_kind: ty::ClosureKind,
370 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
371 if goal.predicate.polarity != ty::ClausePolarity::Positive {
372 return Err(NoSolution.into());
373 }
374
375 let cx = ecx.cx();
376 let Some(tupled_inputs_and_output) =
377 structural_traits::extract_tupled_inputs_and_output_from_callable(
378 cx,
379 goal.predicate.self_ty(),
380 goal_kind,
381 )?
382 else {
383 return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
384 };
385 let (inputs, output) = ecx.instantiate_binder_with_infer(tupled_inputs_and_output);
386
387 let output_is_sized_pred =
390 ty::TraitRef::new(cx, cx.require_trait_lang_item(SolverTraitLangItem::Sized), [output]);
391
392 let pred =
393 ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
394 .upcast(cx);
395 Self::probe_and_consider_implied_clause(
396 ecx,
397 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
398 goal,
399 pred,
400 [(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))],
401 )
402 }
403
404 fn consider_builtin_async_fn_trait_candidates(
405 ecx: &mut EvalCtxt<'_, D>,
406 goal: Goal<I, Self>,
407 goal_kind: ty::ClosureKind,
408 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
409 if goal.predicate.polarity != ty::ClausePolarity::Positive {
410 return Err(NoSolution.into());
411 }
412
413 let cx = ecx.cx();
414 let (tupled_inputs_and_output_and_coroutine, nested_preds) =
415 structural_traits::extract_tupled_inputs_and_output_from_async_callable(
416 cx,
417 goal.predicate.self_ty(),
418 goal_kind,
419 Region::new_static(cx),
421 )?;
422 let AsyncCallableRelevantTypes {
423 tupled_inputs_ty,
424 output_coroutine_ty,
425 coroutine_return_ty: _,
426 } = ecx.instantiate_binder_with_infer(tupled_inputs_and_output_and_coroutine);
427
428 let output_is_sized_pred = ty::TraitRef::new(
431 cx,
432 cx.require_trait_lang_item(SolverTraitLangItem::Sized),
433 [output_coroutine_ty],
434 );
435
436 let pred = ty::TraitRef::new(
437 cx,
438 goal.predicate.def_id(),
439 [goal.predicate.self_ty(), tupled_inputs_ty],
440 )
441 .upcast(cx);
442 Self::probe_and_consider_implied_clause(
443 ecx,
444 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
445 goal,
446 pred,
447 [goal.with(cx, output_is_sized_pred)]
448 .into_iter()
449 .chain(nested_preds.into_iter().map(|pred| goal.with(cx, pred)))
450 .map(|goal| (GoalSource::ImplWhereBound, goal)),
451 )
452 }
453
454 fn consider_builtin_async_fn_kind_helper_candidate(
455 ecx: &mut EvalCtxt<'_, D>,
456 goal: Goal<I, Self>,
457 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
458 let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else {
459 ::core::panicking::panic("explicit panic");panic!();
460 };
461
462 let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind() else {
463 return Err(NoSolution.into());
465 };
466 let goal_kind = goal_kind_ty.expect_ty().to_opt_closure_kind().unwrap();
467 if closure_kind.extends(goal_kind) {
468 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
469 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
470 } else {
471 Err(NoSolution.into())
472 }
473 }
474
475 fn consider_builtin_tuple_candidate(
482 ecx: &mut EvalCtxt<'_, D>,
483 goal: Goal<I, Self>,
484 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
485 if goal.predicate.polarity != ty::ClausePolarity::Positive {
486 return Err(NoSolution.into());
487 }
488
489 if let ty::Tuple(..) = goal.predicate.self_ty().kind() {
490 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
491 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
492 } else {
493 Err(NoSolution.into())
494 }
495 }
496
497 fn consider_builtin_pointee_candidate(
498 ecx: &mut EvalCtxt<'_, D>,
499 goal: Goal<I, Self>,
500 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
501 if goal.predicate.polarity != ty::ClausePolarity::Positive {
502 return Err(NoSolution.into());
503 }
504
505 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
506 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
507 }
508
509 fn consider_builtin_future_candidate(
510 ecx: &mut EvalCtxt<'_, D>,
511 goal: Goal<I, Self>,
512 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
513 if goal.predicate.polarity != ty::ClausePolarity::Positive {
514 return Err(NoSolution.into());
515 }
516
517 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
518 return Err(NoSolution.into());
519 };
520
521 let cx = ecx.cx();
523 if !cx.coroutine_is_async(def_id) {
524 return Err(NoSolution.into());
525 }
526
527 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
531 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
532 }
533
534 fn consider_builtin_iterator_candidate(
535 ecx: &mut EvalCtxt<'_, D>,
536 goal: Goal<I, Self>,
537 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
538 if goal.predicate.polarity != ty::ClausePolarity::Positive {
539 return Err(NoSolution.into());
540 }
541
542 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
543 return Err(NoSolution.into());
544 };
545
546 let cx = ecx.cx();
548 if !cx.coroutine_is_gen(def_id) {
549 return Err(NoSolution.into());
550 }
551
552 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
556 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
557 }
558
559 fn consider_builtin_fused_iterator_candidate(
560 ecx: &mut EvalCtxt<'_, D>,
561 goal: Goal<I, Self>,
562 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
563 if goal.predicate.polarity != ty::ClausePolarity::Positive {
564 return Err(NoSolution.into());
565 }
566
567 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
568 return Err(NoSolution.into());
569 };
570
571 let cx = ecx.cx();
573 if !cx.coroutine_is_gen(def_id) {
574 return Err(NoSolution.into());
575 }
576
577 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
579 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
580 }
581
582 fn consider_builtin_async_iterator_candidate(
583 ecx: &mut EvalCtxt<'_, D>,
584 goal: Goal<I, Self>,
585 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
586 if goal.predicate.polarity != ty::ClausePolarity::Positive {
587 return Err(NoSolution.into());
588 }
589
590 let ty::Coroutine(def_id, _) = goal.predicate.self_ty().kind() else {
591 return Err(NoSolution.into());
592 };
593
594 let cx = ecx.cx();
596 if !cx.coroutine_is_async_gen(def_id) {
597 return Err(NoSolution.into());
598 }
599
600 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
604 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
605 }
606
607 fn consider_builtin_coroutine_candidate(
608 ecx: &mut EvalCtxt<'_, D>,
609 goal: Goal<I, Self>,
610 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
611 if goal.predicate.polarity != ty::ClausePolarity::Positive {
612 return Err(NoSolution.into());
613 }
614
615 let self_ty = goal.predicate.self_ty();
616 let ty::Coroutine(def_id, args) = self_ty.kind() else {
617 return Err(NoSolution.into());
618 };
619
620 let cx = ecx.cx();
622 if !cx.is_general_coroutine(def_id) {
623 return Err(NoSolution.into());
624 }
625
626 let coroutine = args.as_coroutine();
627 Self::probe_and_consider_implied_clause(
628 ecx,
629 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
630 goal,
631 ty::TraitRef::new(cx, goal.predicate.def_id(), [self_ty, coroutine.resume_ty()])
632 .upcast(cx),
633 [],
636 )
637 }
638
639 fn consider_builtin_discriminant_kind_candidate(
640 ecx: &mut EvalCtxt<'_, D>,
641 goal: Goal<I, Self>,
642 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
643 if goal.predicate.polarity != ty::ClausePolarity::Positive {
644 return Err(NoSolution.into());
645 }
646
647 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
649 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
650 }
651
652 fn consider_builtin_destruct_candidate(
653 ecx: &mut EvalCtxt<'_, D>,
654 goal: Goal<I, Self>,
655 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
656 if goal.predicate.polarity != ty::ClausePolarity::Positive {
657 return Err(NoSolution.into());
658 }
659
660 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
663 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
664 }
665
666 fn consider_builtin_transmute_candidate(
667 ecx: &mut EvalCtxt<'_, D>,
668 goal: Goal<I, Self>,
669 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
670 if goal.predicate.polarity != ty::ClausePolarity::Positive {
671 return Err(NoSolution.into());
672 }
673
674 if goal.predicate.has_non_region_placeholders() {
676 return Err(NoSolution.into());
677 }
678
679 if goal.has_non_region_infer() {
682 return ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS);
683 }
684
685 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(
686 |ecx| -> Result<_, NoSolutionOrRerunNonErased> {
687 let assume = ecx.structurally_normalize_const(
688 goal.param_env,
689 goal.predicate.trait_ref.args.const_at(2),
690 )?;
691
692 let certainty = ecx.is_transmutable(
693 goal.predicate.trait_ref.args.type_at(0),
694 goal.predicate.trait_ref.args.type_at(1),
695 assume,
696 )?;
697 ecx.evaluate_added_goals_and_make_canonical_response(certainty)
698 },
699 )
700 }
701
702 fn consider_builtin_bikeshed_guaranteed_no_drop_candidate(
715 ecx: &mut EvalCtxt<'_, D>,
716 goal: Goal<I, Self>,
717 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
718 if goal.predicate.polarity != ty::ClausePolarity::Positive {
719 return Err(NoSolution.into());
720 }
721
722 let cx = ecx.cx();
723 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
724 let ty = goal.predicate.self_ty();
725 match ty.kind() {
726 ty::Ref(..) => {}
728 ty::Adt(def, _) if def.is_manually_drop() => {}
730 ty::Tuple(tys) => {
733 ecx.add_goals(
734 GoalSource::ImplWhereBound,
735 tys.iter().map(|elem_ty| {
736 goal.with(cx, ty::TraitRef::new(cx, goal.predicate.def_id(), [elem_ty]))
737 }),
738 )?;
739 }
740 ty::Array(elem_ty, _) => {
741 ecx.add_goal(
742 GoalSource::ImplWhereBound,
743 goal.with(cx, ty::TraitRef::new(cx, goal.predicate.def_id(), [elem_ty])),
744 )?;
745 }
746
747 ty::FnDef(..)
751 | ty::FnPtr(..)
752 | ty::Error(_)
753 | ty::Uint(_)
754 | ty::Int(_)
755 | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
756 | ty::Bool
757 | ty::Float(_)
758 | ty::Char
759 | ty::RawPtr(..)
760 | ty::Never
761 | ty::Pat(..)
762 | ty::Dynamic(..)
763 | ty::Str
764 | ty::Slice(_)
765 | ty::Foreign(..)
766 | ty::Adt(..)
767 | ty::Alias(..)
768 | ty::Param(_)
769 | ty::Placeholder(..)
770 | ty::Closure(..)
771 | ty::CoroutineClosure(..)
772 | ty::Coroutine(..)
773 | ty::UnsafeBinder(_)
774 | ty::CoroutineWitness(..) => {
775 ecx.add_goal(
776 GoalSource::ImplWhereBound,
777 goal.with(
778 cx,
779 ty::TraitRef::new(
780 cx,
781 cx.require_trait_lang_item(SolverTraitLangItem::Copy),
782 [ty],
783 ),
784 ),
785 )?;
786 }
787
788 ty::Bound(..)
789 | ty::Infer(
790 ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),
791 ) => {
792 { ::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`", ty)); }panic!("unexpected type `{ty:?}`")
793 }
794 }
795
796 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
797 })
798 }
799
800 fn consider_structural_builtin_unsize_candidates(
808 ecx: &mut EvalCtxt<'_, D>,
809 goal: Goal<I, Self>,
810 ) -> Result<Vec<Candidate<I>>, RerunNonErased> {
811 if goal.predicate.polarity != ty::ClausePolarity::Positive {
812 return Ok(::alloc::vec::Vec::new()vec![]);
813 }
814
815 let result = ecx.probe(|_| ProbeKind::UnsizeAssembly).enter(
816 |ecx| -> Result<Vec<Candidate<I>>, NoSolutionOrRerunNonErased> {
817 let a_ty = goal.predicate.self_ty();
818 let b_ty = ecx.structurally_normalize_ty(
821 goal.param_env,
822 goal.predicate.trait_ref.args.type_at(1),
823 )?;
824
825 let goal = goal.with(ecx.cx(), (a_ty, b_ty));
826 match (a_ty.kind(), b_ty.kind()) {
827 (ty::Infer(ty::TyVar(..)), ..) => {
::core::panicking::panic_fmt(format_args!("unexpected infer {0:?} {1:?}",
a_ty, b_ty));
}panic!("unexpected infer {a_ty:?} {b_ty:?}"),
828
829 (_, ty::Infer(ty::TyVar(..))) => {
830 Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)?]))vec![ecx.forced_ambiguity(MaybeInfo::AMBIGUOUS)?])
831 }
832
833 (ty::Dynamic(a_data, a_region), ty::Dynamic(b_data, b_region)) => Ok(ecx
835 .consider_builtin_dyn_upcast_candidates(
836 goal, a_data, a_region, b_data, b_region,
837 )),
838
839 (_, ty::Dynamic(b_region, b_data)) => Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region,
b_data)?]))vec![
841 ecx.consider_builtin_unsize_to_dyn_candidate(goal, b_region, b_data)?,
842 ]),
843
844 (ty::Array(a_elem_ty, ..), ty::Slice(b_elem_ty)) => {
846 Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)?]))vec![ecx.consider_builtin_array_unsize(goal, a_elem_ty, b_elem_ty)?])
847 }
848
849 (ty::Adt(a_def, a_args), ty::Adt(b_def, b_args))
851 if a_def.is_struct() && a_def == b_def =>
852 {
853 Ok(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args)?]))vec![ecx.consider_builtin_struct_unsize(goal, a_def, a_args, b_args)?])
854 }
855
856 _ => Err(NoSolution.into()),
857 }
858 },
859 );
860
861 match result.map_err_to_rerun()? {
862 Ok(resp) => Ok(resp),
863 Err(NoSolution) => Ok(::alloc::vec::Vec::new()vec![]),
864 }
865 }
866
867 fn consider_builtin_try_as_dyn_candidate(
868 ecx: &mut EvalCtxt<'_, D>,
869 goal: Goal<I, Self>,
870 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
871 if goal.predicate.polarity != ty::ClausePolarity::Positive {
872 return Err(NoSolution.into());
873 }
874 let cx = ecx.cx();
875
876 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
877 let self_ty = goal.predicate.self_ty();
878 let ty_lifetime = goal.predicate.trait_ref.args.region_at(1);
879 match self_ty.kind() {
880 ty::Dynamic(bounds, lifetime) => {
881 for bound in bounds.iter() {
882 match bound.skip_binder() {
883 ExistentialPredicate::Trait(_) => {}
884 ExistentialPredicate::Projection(_) => return Err(NoSolution.into()),
886 ExistentialPredicate::AutoTrait(_) => {}
889 }
890 }
891 ecx.add_goal(
892 GoalSource::Misc,
893 goal.with(cx, ty::OutlivesClause(ty_lifetime, lifetime)),
894 )?;
895 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
896 }
897
898 ty::Bound(..)
899 | ty::Infer(
900 ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_),
901 ) => {
902 {
::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`",
self_ty));
}panic!("unexpected type `{self_ty:?}`")
903 }
904
905 _ => Err(NoSolution.into()),
906 }
907 })
908 }
909
910 fn consider_builtin_field_candidate(
911 ecx: &mut EvalCtxt<'_, D>,
912 goal: Goal<I, Self>,
913 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
914 if goal.predicate.polarity != ty::ClausePolarity::Positive {
915 return Err(NoSolution.into());
916 }
917 if let ty::Adt(def, args) = goal.predicate.self_ty().kind()
918 && let Some(FieldInfo { base, ty, .. }) =
919 def.field_representing_type_info(ecx.cx(), args)
920 && {
921 let sized_trait = ecx.cx().require_trait_lang_item(SolverTraitLangItem::Sized);
922 ecx.add_goal(
930 GoalSource::ImplWhereBound,
931 Goal {
932 param_env: goal.param_env,
933 predicate: TraitRef::new(ecx.cx(), sized_trait, [base]).upcast(ecx.cx()),
934 },
935 )?;
936 ecx.add_goal(
937 GoalSource::ImplWhereBound,
938 Goal {
939 param_env: goal.param_env,
940 predicate: TraitRef::new(ecx.cx(), sized_trait, [ty]).upcast(ecx.cx()),
941 },
942 )?;
943 ecx.try_evaluate_added_goals()? == Certainty::Yes
946 }
947 && match base.kind() {
948 ty::Adt(def, _) => def.is_struct() && !def.is_packed(),
949 ty::Tuple(..) => true,
950 _ => false,
951 }
952 {
953 ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
954 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
955 } else {
956 Err(NoSolution.into())
957 }
958 }
959}
960
961#[inline(always)]
967fn trait_predicate_with_def_id<I: Interner>(
968 cx: I,
969 clause: ty::Binder<I, ty::TraitClause<I>>,
970 did: I::TraitId,
971) -> I::Clause {
972 clause
973 .map_bound(|c| TraitClause {
974 trait_ref: TraitRef::new_from_args(cx, did, c.trait_ref.args),
975 polarity: c.polarity,
976 })
977 .upcast(cx)
978}
979
980impl<D, I> EvalCtxt<'_, D>
981where
982 D: SolverDelegate<Interner = I>,
983 I: Interner,
984{
985 fn consider_builtin_dyn_upcast_candidates(
995 &mut self,
996 goal: Goal<I, (I::Ty, I::Ty)>,
997 a_data: I::BoundExistentialPredicates,
998 a_region: Region<I>,
999 b_data: I::BoundExistentialPredicates,
1000 b_region: Region<I>,
1001 ) -> Vec<Candidate<I>> {
1002 let cx = self.cx();
1003 let Goal { predicate: (a_ty, _b_ty), .. } = goal;
1004
1005 let mut responses = ::alloc::vec::Vec::new()vec![];
1006 let b_principal_def_id = b_data.principal_def_id();
1009 if a_data.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
1010 responses.extend(self.consider_builtin_upcast_to_principal(
1011 goal,
1012 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
1013 a_data,
1014 a_region,
1015 b_data,
1016 b_region,
1017 a_data.principal(),
1018 ));
1019 } else if let Some(a_principal) = a_data.principal() {
1020 for (idx, new_a_principal) in
1021 elaborate::supertraits(self.cx(), a_principal.with_self_ty(cx, a_ty))
1022 .enumerate()
1023 .skip(1)
1024 {
1025 responses.extend(self.consider_builtin_upcast_to_principal(
1026 goal,
1027 CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting(idx)),
1028 a_data,
1029 a_region,
1030 b_data,
1031 b_region,
1032 Some(new_a_principal.map_bound(|trait_ref| {
1033 ty::ExistentialTraitRef::erase_self_ty(cx, trait_ref)
1034 })),
1035 ));
1036 }
1037 }
1038
1039 responses
1040 }
1041
1042 fn consider_builtin_unsize_to_dyn_candidate(
1043 &mut self,
1044 goal: Goal<I, (I::Ty, I::Ty)>,
1045 b_data: I::BoundExistentialPredicates,
1046 b_region: Region<I>,
1047 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1048 let cx = self.cx();
1049 let Goal { predicate: (a_ty, _), .. } = goal;
1050
1051 if b_data.principal_def_id().is_some_and(|def_id| !cx.trait_is_dyn_compatible(def_id)) {
1053 return Err(NoSolution.into());
1054 }
1055
1056 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1057 ecx.add_goals(
1060 GoalSource::ImplWhereBound,
1061 b_data.iter().map(|pred| goal.with(cx, pred.with_self_ty(cx, a_ty))),
1062 )?;
1063
1064 ecx.add_goal(
1066 GoalSource::ImplWhereBound,
1067 goal.with(
1068 cx,
1069 ty::TraitRef::new(
1070 cx,
1071 cx.require_trait_lang_item(SolverTraitLangItem::Sized),
1072 [a_ty],
1073 ),
1074 ),
1075 )?;
1076
1077 ecx.add_goal(GoalSource::Misc, goal.with(cx, ty::OutlivesClause(a_ty, b_region)))?;
1079 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1080 })
1081 }
1082
1083 fn consider_builtin_upcast_to_principal(
1084 &mut self,
1085 goal: Goal<I, (I::Ty, I::Ty)>,
1086 source: CandidateSource<I>,
1087 a_data: I::BoundExistentialPredicates,
1088 a_region: Region<I>,
1089 b_data: I::BoundExistentialPredicates,
1090 b_region: Region<I>,
1091 upcast_principal: Option<ty::Binder<I, ty::ExistentialTraitRef<I>>>,
1092 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1093 let param_env = goal.param_env;
1094
1095 let a_auto_traits: IndexSet<I::TraitId> = a_data
1099 .auto_traits()
1100 .into_iter()
1101 .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
1102 elaborate::supertrait_def_ids(self.cx(), principal_def_id)
1103 .filter(|def_id| self.cx().trait_is_auto(*def_id))
1104 }))
1105 .collect();
1106
1107 let projection_may_match =
1112 |ecx: &mut EvalCtxt<'_, D>,
1113 source_projection: ty::Binder<I, ty::ExistentialProjection<I>>,
1114 target_projection: ty::Binder<I, ty::ExistentialProjection<I>>|
1115 -> Result<bool, RerunNonErased> {
1116 if source_projection.item_def_id() != target_projection.item_def_id() {
1117 return Ok(false);
1118 }
1119 match ecx.probe(|_| ProbeKind::ProjectionCompatibility).enter(|ecx| {
1120 let target_projection = ecx.resolve_vars_if_possible(target_projection);
1121 ecx.enter_forall_with_assumptions(
1122 target_projection,
1123 param_env,
1124 |ecx, target_projection| {
1125 let source_projection =
1126 ecx.instantiate_binder_with_infer(source_projection);
1127 ecx.eq(param_env, source_projection, target_projection)?;
1128 ecx.try_evaluate_added_goals()
1129 },
1130 )
1131 }) {
1132 Ok(_) => Ok(true),
1133 Err(NoSolutionOrRerunNonErased::NoSolution(_)) => Ok(false),
1134 Err(NoSolutionOrRerunNonErased::RerunNonErased(rerun)) => Err(rerun),
1135 }
1136 };
1137
1138 self.probe_trait_candidate(source).enter(|ecx| {
1139 for bound in b_data.iter() {
1140 match bound.skip_binder() {
1141 ty::ExistentialPredicate::Trait(target_principal) => {
1144 let source_principal = upcast_principal.unwrap();
1145 let target_principal = bound.rebind(target_principal);
1146 let target_principal = ecx.resolve_vars_if_possible(target_principal);
1148 ecx.enter_forall_with_assumptions(
1149 target_principal,
1150 param_env,
1151 |ecx, target_principal| {
1152 let source_principal =
1153 ecx.instantiate_binder_with_infer(source_principal);
1154 ecx.eq(param_env, source_principal, target_principal)?;
1155 ecx.try_evaluate_added_goals()
1156 },
1157 )?;
1158 }
1159 ty::ExistentialPredicate::Projection(target_projection) => {
1165 let target_projection = bound.rebind(target_projection);
1166 let mut matching_projection = None;
1167 for source_projection in a_data.projection_bounds() {
1168 if projection_may_match(ecx, source_projection, target_projection)? {
1169 if matching_projection.is_some() {
1170 return ecx.evaluate_added_goals_and_make_canonical_response(
1171 Certainty::AMBIGUOUS,
1172 );
1173 }
1174 matching_projection = Some(source_projection);
1175 }
1176 }
1177 let Some(matching) = matching_projection else {
1178 return Err(NoSolution.into());
1179 };
1180
1181 let target_projection = ecx.resolve_vars_if_possible(target_projection);
1183 ecx.enter_forall_with_assumptions(
1184 target_projection,
1185 param_env,
1186 |ecx, target_projection| {
1187 let source_projection = ecx.instantiate_binder_with_infer(matching);
1188 ecx.eq(param_env, source_projection, target_projection)?;
1189 ecx.try_evaluate_added_goals()
1190 },
1191 )?;
1192 }
1193 ty::ExistentialPredicate::AutoTrait(def_id) => {
1195 if !a_auto_traits.contains(&def_id) {
1196 return Err(NoSolution.into());
1197 }
1198 }
1199 }
1200 }
1201
1202 ecx.add_goal(
1204 GoalSource::ImplWhereBound,
1205 Goal::new(ecx.cx(), param_env, ty::OutlivesClause(a_region, b_region)),
1206 )?;
1207
1208 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1209 })
1210 }
1211
1212 fn consider_builtin_array_unsize(
1221 &mut self,
1222 goal: Goal<I, (I::Ty, I::Ty)>,
1223 a_elem_ty: I::Ty,
1224 b_elem_ty: I::Ty,
1225 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1226 self.eq(goal.param_env, a_elem_ty, b_elem_ty)?;
1227 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
1228 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
1229 }
1230
1231 fn consider_builtin_struct_unsize(
1245 &mut self,
1246 goal: Goal<I, (I::Ty, I::Ty)>,
1247 def: I::AdtDef,
1248 a_args: I::GenericArgs,
1249 b_args: I::GenericArgs,
1250 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1251 let cx = self.cx();
1252 let Goal { predicate: (_a_ty, b_ty), .. } = goal;
1253
1254 let unsizing_params = cx.unsizing_params_for_adt(def.def_id());
1255 if unsizing_params.is_empty() {
1258 return Err(NoSolution.into());
1259 }
1260
1261 let tail_field_ty = def.struct_tail_ty(cx).unwrap();
1262
1263 let a_tail_ty = tail_field_ty.instantiate(cx, a_args).skip_norm_wip();
1264 let b_tail_ty = tail_field_ty.instantiate(cx, b_args).skip_norm_wip();
1265
1266 let new_a_args = cx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
1270 if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a }
1271 }));
1272 let unsized_a_ty = Ty::new_adt(cx, def, new_a_args);
1273
1274 self.eq(goal.param_env, unsized_a_ty, b_ty)?;
1277 self.add_goal(
1278 GoalSource::ImplWhereBound,
1279 goal.with(
1280 cx,
1281 ty::TraitRef::new(
1282 cx,
1283 cx.require_trait_lang_item(SolverTraitLangItem::Unsize),
1284 [a_tail_ty, b_tail_ty],
1285 ),
1286 ),
1287 )?;
1288 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
1289 .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
1290 }
1291
1292 fn disqualify_auto_trait_candidate_due_to_possible_impl(
1297 &mut self,
1298 goal: Goal<I, TraitClause<I>>,
1299 ) -> Option<Result<Candidate<I>, NoSolutionOrRerunNonErased>> {
1300 let self_ty = goal.predicate.self_ty();
1301 let check_impls = || {
1302 let mut disqualifying_impl = None;
1303 self.cx().for_each_relevant_impl(goal.predicate.trait_ref, |impl_def_id| {
1304 disqualifying_impl = Some(impl_def_id);
1305 });
1306 if let Some(def_id) = disqualifying_impl {
1307 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1307",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1307u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("def_id")
}> =
::tracing::__macro_support::FieldName::new("def_id");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("goal")
}> =
::tracing::__macro_support::FieldName::new("goal");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("disqualified auto-trait implementation")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};trace!(?def_id, ?goal, "disqualified auto-trait implementation");
1308 return Some(Err(NoSolution.into()));
1311 } else {
1312 None
1313 }
1314 };
1315
1316 match self_ty.kind() {
1317 ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) => {
1323 Some(self.forced_ambiguity(MaybeInfo::AMBIGUOUS))
1324 }
1325
1326 ty::Foreign(..) if self.cx().is_default_trait(goal.predicate.def_id()) => check_impls(),
1329
1330 ty::Dynamic(..)
1333 | ty::Param(..)
1334 | ty::Foreign(..)
1335 | ty::Alias(
1336 ty::IsRigid::Yes,
1337 ty::AliasTy {
1338 kind: ty::Projection { .. } | ty::Free { .. } | ty::Inherent { .. },
1339 ..
1340 },
1341 )
1342 | ty::Placeholder(..) => Some(Err(NoSolution.into())),
1343
1344 ty::Coroutine(def_id, _)
1348 if self
1349 .cx()
1350 .is_trait_lang_item(goal.predicate.def_id(), SolverTraitLangItem::Unpin) =>
1351 {
1352 match self.cx().coroutine_movability(def_id) {
1353 Movability::Static => Some(Err(NoSolution.into())),
1354 Movability::Movable => Some(
1355 self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
1356 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1357 }),
1358 ),
1359 }
1360 }
1361
1362 ty::Alias(ty::IsRigid::Yes, ty::AliasTy { kind: ty::Opaque { .. }, .. }) => None,
1367
1368 ty::Bool
1375 | ty::Char
1376 | ty::Int(_)
1377 | ty::Uint(_)
1378 | ty::Float(_)
1379 | ty::Str
1380 | ty::Array(_, _)
1381 | ty::Pat(_, _)
1382 | ty::Slice(_)
1383 | ty::RawPtr(_, _)
1384 | ty::Ref(_, _, _)
1385 | ty::FnDef(_, _)
1386 | ty::FnPtr(..)
1387 | ty::Closure(..)
1388 | ty::CoroutineClosure(..)
1389 | ty::Coroutine(_, _)
1390 | ty::CoroutineWitness(..)
1391 | ty::Never
1392 | ty::Tuple(_)
1393 | ty::Adt(_, _)
1394 | ty::UnsafeBinder(_) => check_impls(),
1395 ty::Error(_) => None,
1396
1397 ty::Infer(_) | ty::Alias(ty::IsRigid::No, _) | ty::Bound(_, _) => {
1398 {
::core::panicking::panic_fmt(format_args!("unexpected type `{0:?}`",
self_ty));
}panic!("unexpected type `{self_ty:?}`")
1399 }
1400 }
1401 }
1402
1403 fn probe_and_evaluate_goal_for_constituent_tys(
1408 &mut self,
1409 source: CandidateSource<I>,
1410 goal: Goal<I, TraitClause<I>>,
1411 constituent_tys: impl Fn(
1412 &EvalCtxt<'_, D>,
1413 I::Ty,
1414 ) -> Result<ty::Binder<I, Vec<I::Ty>>, NoSolution>,
1415 ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
1416 self.probe_trait_candidate(source).enter(|ecx| {
1417 let goals = ecx.enter_forall_with_assumptions(
1418 constituent_tys(ecx, goal.predicate.self_ty())?,
1419 goal.param_env,
1420 |ecx, tys| {
1421 tys.into_iter()
1422 .map(|ty| {
1423 goal.with(ecx.cx(), goal.predicate.with_replaced_self_ty(ecx.cx(), ty))
1424 })
1425 .collect::<Vec<_>>()
1426 },
1427 );
1428 ecx.add_goals(GoalSource::ImplWhereBound, goals)?;
1429 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1430 })
1431 }
1432}
1433
1434#[derive(#[automatically_derived]
impl ::core::fmt::Debug for TraitGoalProvenVia {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
TraitGoalProvenVia::Misc => "Misc",
TraitGoalProvenVia::ParamEnv => "ParamEnv",
TraitGoalProvenVia::AliasBound => "AliasBound",
})
}
}Debug, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for TraitGoalProvenVia { }
#[automatically_derived]
impl ::core::clone::Clone for TraitGoalProvenVia {
#[inline]
fn clone(&self) -> TraitGoalProvenVia { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for TraitGoalProvenVia { }Copy)]
1445pub(super) enum TraitGoalProvenVia {
1446 Misc,
1452 ParamEnv,
1453 AliasBound,
1454}
1455
1456impl<D, I> EvalCtxt<'_, D>
1457where
1458 D: SolverDelegate<Interner = I>,
1459 I: Interner,
1460{
1461 pub(super) fn unsound_prefer_builtin_dyn_impl(&mut self, candidates: &mut Vec<Candidate<I>>) {
1474 if self.typing_mode().is_coherence() {
1475 return;
1476 }
1477
1478 if candidates
1479 .iter()
1480 .find(|c| {
1481 #[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)) => true,
_ => false,
}matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Object(_)))
1482 })
1483 .is_some_and(|c| has_only_region_constraints(c.result))
1484 {
1485 candidates.retain(|c| {
1486 if #[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::Impl(_) => true,
_ => false,
}matches!(c.source, CandidateSource::Impl(_)) {
1487 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1487",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1487u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("c")
}> =
::tracing::__macro_support::FieldName::new("c");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("unsoundly dropping impl in favor of builtin dyn-candidate")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&c)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?c, "unsoundly dropping impl in favor of builtin dyn-candidate");
1488 false
1489 } else {
1490 true
1491 }
1492 });
1493 }
1494 }
1495
1496 {}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("merge_trait_candidates",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1496u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("candidate_preference_mode")
}> =
::tracing::__macro_support::FieldName::new("candidate_preference_mode");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("candidates")
}> =
::tracing::__macro_support::FieldName::new("candidates");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("failed_candidate_info")
}> =
::tracing::__macro_support::FieldName::new("failed_candidate_info");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&candidate_preference_mode)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&candidates)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&failed_candidate_info)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>),
NoSolution> = loop {};
return __tracing_attr_fake_return;
}
{
if self.typing_mode().is_coherence() {
return if let Some((response, _)) =
self.try_merge_candidates(&candidates) {
Ok((response, Some(TraitGoalProvenVia::Misc)))
} else { self.flounder(&candidates).map(|r| (r, None)) };
}
let mut trivial_builtin_impls =
candidates.iter().filter(|c|
{
#[allow(non_exhaustive_omitted_patterns)]
match c.source {
CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial) =>
true,
_ => false,
}
});
if let Some(candidate) = trivial_builtin_impls.next() {
if !trivial_builtin_impls.next().is_none() {
::core::panicking::panic("assertion failed: trivial_builtin_impls.next().is_none()")
};
return Ok((candidate.result,
Some(TraitGoalProvenVia::Misc)));
}
if #[allow(non_exhaustive_omitted_patterns)] match candidate_preference_mode
{
CandidatePreferenceMode::Marker => true,
_ => false,
} &&
candidates.iter().any(|c|
{
#[allow(non_exhaustive_omitted_patterns)]
match c.source {
CandidateSource::AliasBound(AliasBoundKind::SelfBounds) =>
true,
_ => false,
}
}) {
let alias_bounds: Vec<_> =
candidates.extract_if(..,
|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::AliasBound(..) => true,
_ => false,
}).collect();
return if let Some((response, _)) =
self.try_merge_candidates(&alias_bounds) {
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
} else {
Ok((self.bail_with_ambiguity(&alias_bounds), None))
};
}
let has_non_global_where_bounds =
candidates.iter().any(|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(ParamEnvSource::NonGlobal) =>
true,
_ => false,
});
if has_non_global_where_bounds {
let where_bounds: Vec<_> =
candidates.extract_if(..,
|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(_) => true,
_ => false,
}).collect();
let Some((response, info)) =
self.try_merge_candidates(&where_bounds) else {
return Ok((self.bail_with_ambiguity(&where_bounds), None));
};
match info {
MergeCandidateInfo::AlwaysApplicable(i) => {
for (j, c) in where_bounds.into_iter().enumerate() {
if i != j {
self.ignore_candidate_head_usages(c.head_usages)
}
}
self.ignore_candidate_head_usages(failed_candidate_info.param_env_head_usages);
}
MergeCandidateInfo::EqualResponse => {}
}
return Ok((response, Some(TraitGoalProvenVia::ParamEnv)));
}
if candidates.iter().any(|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::AliasBound(_) => true,
_ => false,
}) {
let alias_bounds: Vec<_> =
candidates.extract_if(..,
|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::AliasBound(_) => true,
_ => false,
}).collect();
return if let Some((response, _)) =
self.try_merge_candidates(&alias_bounds) {
Ok((response, Some(TraitGoalProvenVia::AliasBound)))
} else {
Ok((self.bail_with_ambiguity(&alias_bounds), None))
};
}
self.filter_specialized_impls(AllowInferenceConstraints::No,
&mut candidates);
self.unsound_prefer_builtin_dyn_impl(&mut candidates);
let proven_via =
if candidates.iter().all(|c|
#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(ParamEnvSource::Global) => true,
_ => false,
}) {
TraitGoalProvenVia::ParamEnv
} else {
candidates.retain(|c|
!#[allow(non_exhaustive_omitted_patterns)] match c.source {
CandidateSource::ParamEnv(ParamEnvSource::Global) => true,
_ => false,
});
TraitGoalProvenVia::Misc
};
if let Some((response, _)) =
self.try_merge_candidates(&candidates) {
Ok((response, Some(proven_via)))
} else { self.flounder(&candidates).map(|r| (r, None)) }
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs:1496",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1496u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(self), ret)]
1497 pub(super) fn merge_trait_candidates(
1498 &mut self,
1499 candidate_preference_mode: CandidatePreferenceMode,
1500 mut candidates: Vec<Candidate<I>>,
1501 failed_candidate_info: FailedCandidateInfo,
1502 ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolution> {
1503 if self.typing_mode().is_coherence() {
1504 return if let Some((response, _)) = self.try_merge_candidates(&candidates) {
1505 Ok((response, Some(TraitGoalProvenVia::Misc)))
1506 } else {
1507 self.flounder(&candidates).map(|r| (r, None))
1508 };
1509 }
1510
1511 let mut trivial_builtin_impls = candidates.iter().filter(|c| {
1516 matches!(c.source, CandidateSource::BuiltinImpl(BuiltinImplSource::Trivial))
1517 });
1518 if let Some(candidate) = trivial_builtin_impls.next() {
1519 assert!(trivial_builtin_impls.next().is_none());
1522 return Ok((candidate.result, Some(TraitGoalProvenVia::Misc)));
1523 }
1524
1525 if matches!(candidate_preference_mode, CandidatePreferenceMode::Marker)
1528 && candidates.iter().any(|c| {
1529 matches!(c.source, CandidateSource::AliasBound(AliasBoundKind::SelfBounds))
1530 })
1531 {
1532 let alias_bounds: Vec<_> = candidates
1533 .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(..)))
1534 .collect();
1535 return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1536 Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1537 } else {
1538 Ok((self.bail_with_ambiguity(&alias_bounds), None))
1539 };
1540 }
1541
1542 let has_non_global_where_bounds = candidates
1545 .iter()
1546 .any(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::NonGlobal)));
1547 if has_non_global_where_bounds {
1548 let where_bounds: Vec<_> = candidates
1549 .extract_if(.., |c| matches!(c.source, CandidateSource::ParamEnv(_)))
1550 .collect();
1551 let Some((response, info)) = self.try_merge_candidates(&where_bounds) else {
1552 return Ok((self.bail_with_ambiguity(&where_bounds), None));
1553 };
1554 match info {
1555 MergeCandidateInfo::AlwaysApplicable(i) => {
1571 for (j, c) in where_bounds.into_iter().enumerate() {
1572 if i != j {
1573 self.ignore_candidate_head_usages(c.head_usages)
1574 }
1575 }
1576 self.ignore_candidate_head_usages(failed_candidate_info.param_env_head_usages);
1580 }
1581 MergeCandidateInfo::EqualResponse => {}
1582 }
1583 return Ok((response, Some(TraitGoalProvenVia::ParamEnv)));
1584 }
1585
1586 if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound(_))) {
1588 let alias_bounds: Vec<_> = candidates
1589 .extract_if(.., |c| matches!(c.source, CandidateSource::AliasBound(_)))
1590 .collect();
1591 return if let Some((response, _)) = self.try_merge_candidates(&alias_bounds) {
1592 Ok((response, Some(TraitGoalProvenVia::AliasBound)))
1593 } else {
1594 Ok((self.bail_with_ambiguity(&alias_bounds), None))
1595 };
1596 }
1597
1598 self.filter_specialized_impls(AllowInferenceConstraints::No, &mut candidates);
1599 self.unsound_prefer_builtin_dyn_impl(&mut candidates);
1600
1601 let proven_via = if candidates
1606 .iter()
1607 .all(|c| matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)))
1608 {
1609 TraitGoalProvenVia::ParamEnv
1610 } else {
1611 candidates
1612 .retain(|c| !matches!(c.source, CandidateSource::ParamEnv(ParamEnvSource::Global)));
1613 TraitGoalProvenVia::Misc
1614 };
1615
1616 if let Some((response, _)) = self.try_merge_candidates(&candidates) {
1617 Ok((response, Some(proven_via)))
1618 } else {
1619 self.flounder(&candidates).map(|r| (r, None))
1620 }
1621 }
1622
1623 {}
#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("compute_trait_goal",
"rustc_next_trait_solver::solve::trait_goals",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("/rustc-dev/2e2b193f8ada105f27608b7be81c293e0d7292cb/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs"),
::tracing_core::__macro_support::Option::Some(1623u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::solve::trait_goals"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("goal")
}> =
::tracing::__macro_support::FieldName::new("goal");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&goal)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return:
Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>),
NoSolutionOrRerunNonErased> = loop {};
return __tracing_attr_fake_return;
}
{
let (candidates, failed_candidate_info) =
self.assemble_and_evaluate_candidates(goal,
AssembleCandidatesFrom::All)?;
let candidate_preference_mode =
CandidatePreferenceMode::compute(self.cx(),
goal.predicate.def_id());
self.merge_trait_candidates(candidate_preference_mode, candidates,
failed_candidate_info).map_err(Into::into)
}
}
}#[instrument(level = "trace", skip(self))]
1624 pub(super) fn compute_trait_goal(
1625 &mut self,
1626 goal: Goal<I, TraitClause<I>>,
1627 ) -> Result<(CanonicalResponse<I>, Option<TraitGoalProvenVia>), NoSolutionOrRerunNonErased>
1628 {
1629 let (candidates, failed_candidate_info) =
1630 self.assemble_and_evaluate_candidates(goal, AssembleCandidatesFrom::All)?;
1631 let candidate_preference_mode =
1632 CandidatePreferenceMode::compute(self.cx(), goal.predicate.def_id());
1633 self.merge_trait_candidates(candidate_preference_mode, candidates, failed_candidate_info)
1634 .map_err(Into::into)
1635 }
1636
1637 fn try_stall_coroutine(
1638 &mut self,
1639 self_ty: I::Ty,
1640 ) -> Option<Result<Candidate<I>, NoSolutionOrRerunNonErased>> {
1641 if let ty::Coroutine(def_id, _) = self_ty.kind() {
1642 match self.typing_mode() {
1643 TypingMode::Typeck { defining_opaque_types_and_generators: stalled_generators } => {
1644 if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
1645 {
1646 return Some(self.forced_ambiguity(MaybeInfo {
1647 cause: MaybeCause::Ambiguity,
1648 opaque_types_jank: OpaqueTypesJank::AllGood,
1649 stalled_on_coroutines: StalledOnCoroutines::Yes,
1650 }));
1651 }
1652 }
1653 TypingMode::ErasedNotCoherence(MayBeErased) => {
1654 return Some(
1656 match self.opaque_accesses.rerun_always(RerunReason::TryStallCoroutine) {
1657 Err(e) => Err(e.into()),
1658 },
1659 );
1660 }
1661 TypingMode::Coherence
1662 | TypingMode::PostAnalysis
1663 | TypingMode::Reflection
1664 | TypingMode::Codegen
1665 | TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ }
1666 | TypingMode::PostBorrowck { defined_opaque_types: _ } => {}
1667 }
1668 }
1669
1670 None
1671 }
1672}