1use std::marker::PhantomData;
2use std::ops::ControlFlow;
3
4use rustc_data_structures::obligation_forest::{
5 Error, ForestObligation, ObligationForest, ObligationProcessor, Outcome, ProcessResult,
6};
7use rustc_hir::def_id::LocalDefId;
8use rustc_infer::infer::DefineOpaqueTypes;
9use rustc_infer::traits::{
10 FromSolverError, PolyTraitObligation, PredicateObligations, ProjectionCacheKey, SelectionError,
11 TraitEngine, TraitErrors,
12};
13use rustc_middle::ty::abstract_const::NotConstEvaluatable;
14use rustc_middle::ty::error::{ExpectedFound, TypeError};
15use rustc_middle::ty::{
16 self, Binder, Const, DelayedSet, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
17 TypeVisitableExt, TypeVisitor, TypingMode, may_use_unstable_feature,
18};
19use rustc_next_trait_solver::solve::TyOrConstInferVar;
20use rustc_span::bug;
21use thin_vec::{ThinVec, thin_vec};
22use tracing::{debug, debug_span, instrument};
23
24use super::effects::{self, HostEffectObligation};
25use super::project::{self, ProjectAndUnifyResult};
26use super::select::SelectionContext;
27use super::{
28 EvaluationResult, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
29 ScrubbedTraitError, const_evaluatable, wf,
30};
31use crate::error_reporting::InferCtxtErrorExt;
32use crate::infer::InferCtxt;
33use crate::traits::normalize::normalize_with_depth_to;
34use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _};
35use crate::traits::query::evaluate_obligation::InferCtxtExt;
36use crate::traits::{EvaluateConstErr, sizedness_fast_path};
37
38pub(crate) type PendingPredicateObligations<'tcx> = ThinVec<PendingPredicateObligation<'tcx>>;
39
40impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
41 type CacheKey = ty::ParamEnvAnd<'tcx, ty::Predicate<'tcx>>;
45
46 fn as_cache_key(&self) -> Self::CacheKey {
47 self.obligation.param_env.and(self.obligation.predicate)
48 }
49}
50
51pub struct FulfillmentContext<'tcx, E: 'tcx> {
62 predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
65
66 usable_in_snapshot: usize,
71
72 _errors: PhantomData<E>,
73}
74
75#[derive(#[automatically_derived]
impl<'tcx> ::core::clone::Clone for PendingPredicateObligation<'tcx> {
#[inline]
fn clone(&self) -> Self {
PendingPredicateObligation {
obligation: ::core::clone::Clone::clone(&self.obligation),
stalled_on: ::core::clone::Clone::clone(&self.stalled_on),
}
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for PendingPredicateObligation<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"PendingPredicateObligation", "obligation", &self.obligation,
"stalled_on", &&self.stalled_on)
}
}Debug)]
76pub struct PendingPredicateObligation<'tcx> {
77 pub obligation: PredicateObligation<'tcx>,
78 pub stalled_on: Vec<TyOrConstInferVar>,
83}
84
85#[cfg(target_pointer_width = "64")]
87const _: [(); 72] =
[(); ::std::mem::size_of::<PendingPredicateObligation<'_>>()];rustc_data_structures::static_assert_size!(PendingPredicateObligation<'_>, 72);
88
89impl<'tcx, E> FulfillmentContext<'tcx, E>
90where
91 E: FromSolverError<'tcx, OldSolverError<'tcx>>,
92{
93 pub(super) fn new(infcx: &InferCtxt<'tcx>) -> FulfillmentContext<'tcx, E> {
95 if !!infcx.next_trait_solver() {
{
::core::panicking::panic_fmt(format_args!("old trait solver fulfillment context created when infcx is set up for new trait solver"));
}
};assert!(
96 !infcx.next_trait_solver(),
97 "old trait solver fulfillment context created when \
98 infcx is set up for new trait solver"
99 );
100 FulfillmentContext {
101 predicates: ObligationForest::new(),
102 usable_in_snapshot: infcx.num_open_snapshots(),
103 _errors: PhantomData,
104 }
105 }
106
107 fn select(&mut self, selcx: SelectionContext<'_, 'tcx>) -> TraitErrors<E> {
109 let span = {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("select",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(109u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation_forest_size")
}> =
::tracing::__macro_support::FieldName::new("obligation_forest_size");
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(&self.predicates.len())
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
}debug_span!("select", obligation_forest_size = ?self.predicates.len());
110 let _enter = span.enter();
111 let infcx = selcx.infcx;
112
113 let outcome: Outcome<_, _> =
115 self.predicates.process_obligations(&mut FulfillProcessor { selcx });
116
117 let errors = TraitErrors::from_iter(
121 outcome.errors.into_iter().map(|err| E::from_solver_error(infcx, OldSolverError(err))),
122 );
123
124 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:124",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(124u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("select({0} predicates remaining, {1} errors) done",
self.predicates.len(), errors.len()) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
125 "select({} predicates remaining, {} errors) done",
126 self.predicates.len(),
127 errors.len()
128 );
129
130 errors
131 }
132}
133
134impl<'tcx, E> TraitEngine<'tcx, E> for FulfillmentContext<'tcx, E>
135where
136 E: FromSolverError<'tcx, OldSolverError<'tcx>>,
137{
138 #[inline]
139 fn register_predicate_obligation(
140 &mut self,
141 infcx: &InferCtxt<'tcx>,
142 mut obligation: PredicateObligation<'tcx>,
143 ) {
144 {
match (&self.usable_in_snapshot, &infcx.num_open_snapshots()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
145 if true {
if !!obligation.param_env.has_non_region_infer() {
::core::panicking::panic("assertion failed: !obligation.param_env.has_non_region_infer()")
};
};debug_assert!(!obligation.param_env.has_non_region_infer());
148 obligation.predicate = infcx.deeply_resolve_ignoring_regions(obligation.predicate);
149
150 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:150",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(150u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
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!("register_predicate_obligation")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(?obligation, "register_predicate_obligation");
151
152 self.predicates
153 .register_obligation(PendingPredicateObligation { obligation, stalled_on: ::alloc::vec::Vec::new()vec![] });
154 }
155
156 fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> TraitErrors<E> {
157 TraitErrors::from_iter(
158 self.predicates
159 .to_errors(FulfillmentErrorCode::Ambiguity { overflow: None })
160 .into_iter()
161 .map(|err| E::from_solver_error(infcx, OldSolverError(err))),
162 )
163 }
164
165 fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> TraitErrors<E> {
166 let selcx = SelectionContext::new(infcx);
167 self.select(selcx)
168 }
169
170 fn drain_stalled_obligations_for_coroutines(
171 &mut self,
172 infcx: &InferCtxt<'tcx>,
173 ) -> PredicateObligations<'tcx> {
174 let stalled_coroutines = match infcx.typing_mode_raw().assert_not_erased() {
175 TypingMode::Typeck { defining_opaque_types_and_generators } => {
176 defining_opaque_types_and_generators
177 }
178 TypingMode::PostTypeckUntilBorrowck { defining_opaque_types: _ }
179 | TypingMode::PostBorrowck { defined_opaque_types: _ }
180 | TypingMode::Reflection
181 | TypingMode::PostAnalysis
182 | TypingMode::Codegen => return Default::default(),
183 TypingMode::Coherence => {
184 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("old solver coherence")));
}unreachable!("old solver coherence")
185 }
186 };
187
188 if stalled_coroutines.is_empty() {
189 return Default::default();
190 }
191
192 let mut processor = DrainProcessor {
193 infcx,
194 removed_predicates: PredicateObligations::new(),
195 stalled_coroutines,
196 };
197 let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut processor);
198 if !outcome.errors.is_empty() {
::core::panicking::panic("assertion failed: outcome.errors.is_empty()")
};assert!(outcome.errors.is_empty());
199 return processor.removed_predicates;
200
201 struct DrainProcessor<'a, 'tcx> {
202 infcx: &'a InferCtxt<'tcx>,
203 removed_predicates: PredicateObligations<'tcx>,
204 stalled_coroutines: &'tcx ty::List<LocalDefId>,
205 }
206
207 impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> {
208 type Obligation = PendingPredicateObligation<'tcx>;
209 type Error = !;
210 type OUT = Outcome<Self::Obligation, Self::Error>;
211
212 fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
213 struct StalledOnCoroutines<'tcx> {
214 pub stalled_coroutines: &'tcx ty::List<LocalDefId>,
215 pub cache: DelayedSet<Ty<'tcx>>,
216 }
217
218 impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
219 type Result = ControlFlow<()>;
220
221 fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
222 if !self.cache.insert(ty) {
223 return ControlFlow::Continue(());
224 }
225
226 if let ty::Coroutine(def_id, _) = ty.kind()
227 && def_id
228 .as_local()
229 .is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
230 {
231 ControlFlow::Break(())
232 } else if ty.has_coroutines() {
233 ty.super_visit_with(self)
234 } else {
235 ControlFlow::Continue(())
236 }
237 }
238 }
239
240 self.infcx
241 .deeply_resolve_ignoring_regions(pending_obligation.obligation.predicate)
242 .visit_with(&mut StalledOnCoroutines {
243 stalled_coroutines: self.stalled_coroutines,
244 cache: Default::default(),
245 })
246 .is_break()
247 }
248
249 fn process_obligation(
250 &mut self,
251 pending_obligation: &mut PendingPredicateObligation<'tcx>,
252 ) -> ProcessResult<PendingPredicateObligation<'tcx>, !> {
253 if !self.needs_process_obligation(pending_obligation) {
::core::panicking::panic("assertion failed: self.needs_process_obligation(pending_obligation)")
};assert!(self.needs_process_obligation(pending_obligation));
254 self.removed_predicates.push(pending_obligation.obligation.clone());
255 ProcessResult::Changed(Default::default())
256 }
257
258 fn process_backedge<'c, I>(
259 &mut self,
260 cycle: I,
261 _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
262 ) -> Result<(), !>
263 where
264 I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
265 {
266 self.removed_predicates.extend(cycle.map(|c| c.obligation.clone()));
267 Ok(())
268 }
269 }
270 }
271
272 fn has_pending_obligations(&self) -> bool {
273 self.predicates.has_pending_obligations()
274 }
275
276 fn pending_obligations(&self) -> PredicateObligations<'tcx> {
277 self.predicates.map_pending_obligations(|o| o.obligation.clone())
278 }
279}
280
281struct FulfillProcessor<'a, 'tcx> {
282 selcx: SelectionContext<'a, 'tcx>,
283}
284
285fn mk_pending<'tcx>(
286 parent: &PredicateObligation<'tcx>,
287 os: PredicateObligations<'tcx>,
288) -> PendingPredicateObligations<'tcx> {
289 os.into_iter()
290 .map(|mut o| {
291 o.set_depth_from_parent(parent.recursion_depth);
292 PendingPredicateObligation { obligation: o, stalled_on: ::alloc::vec::Vec::new()vec![] }
293 })
294 .collect()
295}
296
297impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
298 type Obligation = PendingPredicateObligation<'tcx>;
299 type Error = FulfillmentErrorCode<'tcx>;
300 type OUT = Outcome<Self::Obligation, Self::Error>;
301
302 #[inline]
312 fn skippable_obligations<'b>(
313 &'b self,
314 it: impl Iterator<Item = &'b Self::Obligation>,
315 ) -> usize {
316 let is_unchanged = self.selcx.infcx.is_ty_infer_var_definitely_unchanged();
317
318 it.take_while(|o| match o.stalled_on.as_slice() {
319 [o] => is_unchanged(*o),
320 _ => false,
321 })
322 .count()
323 }
324
325 #[inline(always)]
331 fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
332 if self.selcx.infcx.disable_trait_solver_fast_paths() {
333 return true;
334 }
335
336 let stalled_on = &pending_obligation.stalled_on;
340 match stalled_on.len() {
341 1 => self.selcx.infcx.ty_or_const_infer_var_changed(stalled_on[0]),
345
346 0 => true,
354
355 _ => (|| {
362 for &infer_var in stalled_on {
363 if self.selcx.infcx.ty_or_const_infer_var_changed(infer_var) {
364 return true;
365 }
366 }
367 false
368 })(),
369 }
370 }
371
372 #[inline(never)]
380 {}
#[allow(clippy :: suspicious_else_formatting)]
{
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("process_obligation",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(380u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&[],
::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,
&{ meta.fields().value_set_all(&[]) })
} 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:
ProcessResult<PendingPredicateObligation<'tcx>,
FulfillmentErrorCode<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
pending_obligation.stalled_on.clear();
let obligation = &mut pending_obligation.obligation;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:389",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(389u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message",
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("obligation")
}> =
::tracing::__macro_support::FieldName::new("obligation");
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!("pre-resolve")
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&obligation)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
if obligation.predicate.has_non_region_infer() {
obligation.predicate =
self.selcx.infcx.deeply_resolve_ignoring_regions(obligation.predicate);
}
let obligation = &pending_obligation.obligation;
let infcx = self.selcx.infcx;
if !infcx.disable_trait_solver_fast_paths() &&
sizedness_fast_path(infcx.tcx, obligation.predicate,
obligation.param_env) {
return ProcessResult::Changed(::thin_vec::ThinVec::new());
}
if obligation.predicate.has_aliases() {
let mut obligations = PredicateObligations::new();
let predicate =
normalize_with_depth_to(&mut self.selcx,
obligation.param_env, obligation.cause.clone(),
obligation.recursion_depth + 1,
ty::Unnormalized::new_wip(obligation.predicate),
&mut obligations);
if predicate != obligation.predicate {
obligations.push(obligation.with(infcx.tcx, predicate));
return ProcessResult::Changed(mk_pending(obligation,
obligations));
}
}
let binder = obligation.predicate.kind();
match binder.no_bound_vars() {
None =>
match binder.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref))
=> {
let trait_obligation =
obligation.with(infcx.tcx, binder.rebind(trait_ref));
self.process_trait_obligation(obligation, trait_obligation,
&mut pending_obligation.stalled_on)
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(data))
=> {
let project_obligation =
obligation.with(infcx.tcx, binder.rebind(data));
self.process_projection_obligation(obligation,
project_obligation, &mut pending_obligation.stalled_on)
}
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_))
|
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
| ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) |
ty::PredicateKind::DynCompatible(_) |
ty::PredicateKind::Subtype(_) | ty::PredicateKind::Coerce(_)
|
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
| ty::PredicateKind::ConstEquate(..) |
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) =>
{
let pred =
ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
let mut obligations =
PredicateObligations::with_capacity(1);
obligations.push(obligation.with(infcx.tcx, pred));
ProcessResult::Changed(mk_pending(obligation, obligations))
}
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
ty::PredicateKind::NormalizesTo(..) => {
::rustc_span::macros::bug_impl(None,
format_args!("NormalizesTo is only used by the new solver"),
Location::caller())
}
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_))
=> {
{
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("unexpected higher ranked `UnstableFeature` goal")));
}
}
},
Some(pred) =>
match pred {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
let trait_obligation =
obligation.with(infcx.tcx, Binder::dummy(data));
self.process_trait_obligation(obligation, trait_obligation,
&mut pending_obligation.stalled_on)
}
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data))
=> {
let host_obligation = obligation.with(infcx.tcx, data);
self.process_host_obligation(obligation, host_obligation,
&mut pending_obligation.stalled_on)
}
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data))
=> {
if infcx.considering_regions {
infcx.register_region_outlives_constraint(data,
ty::VisibleForLeakCheck::Yes, &obligation.cause);
}
ProcessResult::Changed(Default::default())
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesClause(t_a,
r_b))) => {
if infcx.considering_regions {
infcx.register_type_outlives_constraint(t_a, r_b,
&obligation.cause);
}
ProcessResult::Changed(Default::default())
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ref data))
=> {
let project_obligation =
obligation.with(infcx.tcx, Binder::dummy(*data));
self.process_projection_obligation(obligation,
project_obligation, &mut pending_obligation.stalled_on)
}
ty::PredicateKind::DynCompatible(trait_def_id) => {
if !self.selcx.tcx().is_dyn_compatible(trait_def_id) {
ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::Unimplemented))
} else { ProcessResult::Changed(Default::default()) }
}
ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
ty::PredicateKind::NormalizesTo(..) => {
::rustc_span::macros::bug_impl(None,
format_args!("NormalizesTo is only used by the new solver"),
Location::caller())
}
ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct,
ty)) => {
let ct = infcx.shallow_resolve_const(ct);
let ct_ty =
match ct.kind() {
ty::ConstKind::Infer(var) => {
let var =
match var {
ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid),
ty::InferConst::Fresh(_) => {
::rustc_span::macros::bug_impl(None,
format_args!("encountered fresh const in fulfill"),
Location::caller())
}
};
pending_obligation.stalled_on.clear();
pending_obligation.stalled_on.extend([var]);
return ProcessResult::Unchanged;
}
ty::ConstKind::Error(_) => {
return ProcessResult::Changed(PendingPredicateObligations::new());
}
ty::ConstKind::Value(cv) => cv.ty,
ty::ConstKind::Alias(_, alias_const) => {
alias_const.type_of(infcx.tcx).skip_norm_wip()
}
ty::ConstKind::Expr(_) => {
return ProcessResult::Changed(mk_pending(obligation,
PredicateObligations::new()));
}
ty::ConstKind::Placeholder(_) => {
::rustc_span::macros::bug_impl(None,
format_args!("placeholder const {0:?} in old solver", ct),
Location::caller())
}
ty::ConstKind::Bound(_, _) =>
::rustc_span::macros::bug_impl(None,
format_args!("escaping bound vars in {0:?}", ct),
Location::caller()),
ty::ConstKind::Param(param_ct) => {
param_ct.find_const_ty_from_env(obligation.param_env)
}
};
match infcx.at(&obligation.cause,
obligation.param_env).eq(DefineOpaqueTypes::Yes, ct_ty, ty)
{
Ok(inf_ok) =>
ProcessResult::Changed(mk_pending(obligation,
inf_ok.into_obligations())),
Err(_) =>
ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::ConstArgHasWrongType {
ct,
ct_ty,
expected_ty: ty,
})),
}
}
_ if
!self.selcx.tcx().recursion_limit().value_within_limit(obligation.recursion_depth)
=> {
self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation,
false);
}
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term))
=> {
if term.is_trivially_wf(self.selcx.tcx()) {
return ProcessResult::Changed(::thin_vec::ThinVec::new());
}
match wf::obligations(self.selcx.infcx,
obligation.param_env, obligation.cause.body_def_id,
obligation.recursion_depth + 1, term, obligation.cause.span)
{
None => {
pending_obligation.stalled_on =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[TyOrConstInferVar::maybe_from_term::<TyCtxt<'tcx>>(term).unwrap()]));
ProcessResult::Unchanged
}
Some(os) =>
ProcessResult::Changed(mk_pending(obligation, os)),
}
}
ty::PredicateKind::Subtype(subtype) => {
match self.selcx.infcx.subtype_predicate(&obligation.cause,
obligation.param_env, Binder::dummy(subtype)) {
Err((a, b)) => {
pending_obligation.stalled_on =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)]));
ProcessResult::Unchanged
}
Ok(Ok(ok)) => {
ProcessResult::Changed(mk_pending(obligation,
ok.obligations))
}
Ok(Err(err)) => {
let expected_found =
if subtype.a_is_expected {
ExpectedFound::new(subtype.a, subtype.b)
} else { ExpectedFound::new(subtype.b, subtype.a) };
ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found,
err))
}
}
}
ty::PredicateKind::Coerce(coerce) => {
match self.selcx.infcx.coerce_predicate(&obligation.cause,
obligation.param_env, Binder::dummy(coerce)) {
Err((a, b)) => {
pending_obligation.stalled_on =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)]));
ProcessResult::Unchanged
}
Ok(Ok(ok)) => {
ProcessResult::Changed(mk_pending(obligation,
ok.obligations))
}
Ok(Err(err)) => {
let expected_found = ExpectedFound::new(coerce.b, coerce.a);
ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found,
err))
}
}
}
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(alias_const))
=> {
match const_evaluatable::is_const_evaluatable(self.selcx.infcx,
alias_const, obligation.param_env, obligation.cause.span) {
Ok(()) => ProcessResult::Changed(Default::default()),
Err(NotConstEvaluatable::MentionsInfer) => {
pending_obligation.stalled_on.clear();
pending_obligation.stalled_on.extend(alias_const.walk().filter_map(TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>));
ProcessResult::Unchanged
}
Err(e @ NotConstEvaluatable::MentionsParam | e @
NotConstEvaluatable::Error(_)) =>
ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::NotConstEvaluatable(e))),
}
}
ty::PredicateKind::ConstEquate(c1, c2) => {
let tcx = self.selcx.tcx();
if !tcx.features().generic_const_exprs() {
{
::core::panicking::panic_fmt(format_args!("`ConstEquate` without a feature gate: {0:?} {1:?}",
c1, c2));
}
};
{
let c1 = tcx.expand_abstract_consts(c1);
let c2 = tcx.expand_abstract_consts(c2);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:718",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(718u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("equating consts:\nc1= {0:?}\nc2= {1:?}",
c1, c2) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
match (c1.kind(), c2.kind()) {
(ty::ConstKind::Alias(_, a), ty::ConstKind::Alias(_, b)) if
a.kind == b.kind &&
#[allow(non_exhaustive_omitted_patterns)] match a.kind {
ty::AliasConstKind::Projection { .. } |
ty::AliasConstKind::InherentSelf { .. } |
ty::AliasConstKind::InherentImpl { .. } => true,
_ => false,
} => {
if let Ok(new_obligations) =
infcx.at(&obligation.cause,
obligation.param_env).eq(DefineOpaqueTypes::Yes,
ty::AliasTerm::from(a), ty::AliasTerm::from(b)) {
return ProcessResult::Changed(mk_pending(obligation,
new_obligations.into_obligations()));
}
}
(_, ty::ConstKind::Alias(_, _)) |
(ty::ConstKind::Alias(_, _), _) => (),
(_, _) => {
if let Ok(new_obligations) =
infcx.at(&obligation.cause,
obligation.param_env).eq(DefineOpaqueTypes::Yes, c1, c2) {
return ProcessResult::Changed(mk_pending(obligation,
new_obligations.into_obligations()));
}
}
}
}
let stalled_on = &mut pending_obligation.stalled_on;
let mut evaluate =
|c: Const<'tcx>|
{
if let ty::ConstKind::Alias(_, alias_const) = c.kind() {
match super::try_evaluate_const(self.selcx.infcx, c,
obligation.param_env, |ty| Ok::<_, !>(ty.skip_norm_wip())) {
Ok(val) => Ok(val),
e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
stalled_on.extend(alias_const.args.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>));
e
}
e @
Err(EvaluateConstErr::EvaluationFailure(_) |
EvaluateConstErr::InvalidConstParamTy(_)) => e,
}
} else { Ok(c) }
};
match (evaluate(c1), evaluate(c2)) {
(Ok(c1), Ok(c2)) => {
match self.selcx.infcx.at(&obligation.cause,
obligation.param_env).eq(DefineOpaqueTypes::Yes, c1, c2) {
Ok(inf_ok) =>
ProcessResult::Changed(mk_pending(obligation,
inf_ok.into_obligations())),
Err(err) => {
ProcessResult::Error(FulfillmentErrorCode::ConstEquate(ExpectedFound::new(c1,
c2), err))
}
}
}
(Err(EvaluateConstErr::InvalidConstParamTy(e)), _) |
(_, Err(EvaluateConstErr::InvalidConstParamTy(e))) => {
ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e))))
}
(Err(EvaluateConstErr::EvaluationFailure(e)), _) |
(_, Err(EvaluateConstErr::EvaluationFailure(e))) => {
ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e))))
}
(Err(EvaluateConstErr::HasGenericsOrInfers), _) |
(_, Err(EvaluateConstErr::HasGenericsOrInfers)) => {
if c1.has_non_region_infer() || c2.has_non_region_infer() {
ProcessResult::Unchanged
} else {
let expected_found = ExpectedFound::new(c1, c2);
ProcessResult::Error(FulfillmentErrorCode::ConstEquate(expected_found,
TypeError::ConstMismatch(expected_found)))
}
}
}
}
ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol))
=> {
if may_use_unstable_feature(self.selcx.infcx,
obligation.param_env, symbol) {
ProcessResult::Changed(Default::default())
} else { ProcessResult::Unchanged }
}
},
}
}
}
}#[instrument(level = "debug", skip(self, pending_obligation))]
381 fn process_obligation(
382 &mut self,
383 pending_obligation: &mut PendingPredicateObligation<'tcx>,
384 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
385 pending_obligation.stalled_on.clear();
386
387 let obligation = &mut pending_obligation.obligation;
388
389 debug!(?obligation, "pre-resolve");
390
391 if obligation.predicate.has_non_region_infer() {
392 obligation.predicate =
393 self.selcx.infcx.deeply_resolve_ignoring_regions(obligation.predicate);
394 }
395
396 let obligation = &pending_obligation.obligation;
397
398 let infcx = self.selcx.infcx;
399
400 if !infcx.disable_trait_solver_fast_paths()
401 && sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env)
402 {
403 return ProcessResult::Changed(thin_vec![]);
404 }
405
406 if obligation.predicate.has_aliases() {
407 let mut obligations = PredicateObligations::new();
408 let predicate = normalize_with_depth_to(
409 &mut self.selcx,
410 obligation.param_env,
411 obligation.cause.clone(),
412 obligation.recursion_depth + 1,
413 ty::Unnormalized::new_wip(obligation.predicate),
414 &mut obligations,
415 );
416 if predicate != obligation.predicate {
417 obligations.push(obligation.with(infcx.tcx, predicate));
418 return ProcessResult::Changed(mk_pending(obligation, obligations));
419 }
420 }
421 let binder = obligation.predicate.kind();
422 match binder.no_bound_vars() {
423 None => match binder.skip_binder() {
424 ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) => {
428 let trait_obligation = obligation.with(infcx.tcx, binder.rebind(trait_ref));
429
430 self.process_trait_obligation(
431 obligation,
432 trait_obligation,
433 &mut pending_obligation.stalled_on,
434 )
435 }
436 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
437 let project_obligation = obligation.with(infcx.tcx, binder.rebind(data));
438
439 self.process_projection_obligation(
440 obligation,
441 project_obligation,
442 &mut pending_obligation.stalled_on,
443 )
444 }
445 ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
446 | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_))
447 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
448 | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
449 | ty::PredicateKind::DynCompatible(_)
450 | ty::PredicateKind::Subtype(_)
451 | ty::PredicateKind::Coerce(_)
452 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
453 | ty::PredicateKind::ConstEquate(..)
454 | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
458 let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
459 let mut obligations = PredicateObligations::with_capacity(1);
460 obligations.push(obligation.with(infcx.tcx, pred));
461
462 ProcessResult::Changed(mk_pending(obligation, obligations))
463 }
464 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
465 ty::PredicateKind::NormalizesTo(..) => {
466 bug!("NormalizesTo is only used by the new solver")
467 }
468 ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => {
469 unreachable!("unexpected higher ranked `UnstableFeature` goal")
470 }
471 },
472 Some(pred) => match pred {
473 ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
474 let trait_obligation = obligation.with(infcx.tcx, Binder::dummy(data));
475
476 self.process_trait_obligation(
477 obligation,
478 trait_obligation,
479 &mut pending_obligation.stalled_on,
480 )
481 }
482
483 ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
484 let host_obligation = obligation.with(infcx.tcx, data);
485
486 self.process_host_obligation(
487 obligation,
488 host_obligation,
489 &mut pending_obligation.stalled_on,
490 )
491 }
492
493 ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
494 if infcx.considering_regions {
495 infcx.register_region_outlives_constraint(
496 data,
497 ty::VisibleForLeakCheck::Yes,
498 &obligation.cause,
499 );
500 }
501
502 ProcessResult::Changed(Default::default())
503 }
504
505 ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesClause(
506 t_a,
507 r_b,
508 ))) => {
509 if infcx.considering_regions {
510 infcx.register_type_outlives_constraint(t_a, r_b, &obligation.cause);
511 }
512 ProcessResult::Changed(Default::default())
513 }
514
515 ty::PredicateKind::Clause(ty::ClauseKind::Projection(ref data)) => {
516 let project_obligation = obligation.with(infcx.tcx, Binder::dummy(*data));
517
518 self.process_projection_obligation(
519 obligation,
520 project_obligation,
521 &mut pending_obligation.stalled_on,
522 )
523 }
524
525 ty::PredicateKind::DynCompatible(trait_def_id) => {
526 if !self.selcx.tcx().is_dyn_compatible(trait_def_id) {
527 ProcessResult::Error(FulfillmentErrorCode::Select(
528 SelectionError::Unimplemented,
529 ))
530 } else {
531 ProcessResult::Changed(Default::default())
532 }
533 }
534
535 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
536 ty::PredicateKind::NormalizesTo(..) => {
537 bug!("NormalizesTo is only used by the new solver")
538 }
539 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
543 let ct = infcx.shallow_resolve_const(ct);
544 let ct_ty = match ct.kind() {
545 ty::ConstKind::Infer(var) => {
546 let var = match var {
547 ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid),
548 ty::InferConst::Fresh(_) => {
549 bug!("encountered fresh const in fulfill")
550 }
551 };
552 pending_obligation.stalled_on.clear();
553 pending_obligation.stalled_on.extend([var]);
554 return ProcessResult::Unchanged;
555 }
556 ty::ConstKind::Error(_) => {
557 return ProcessResult::Changed(PendingPredicateObligations::new());
558 }
559 ty::ConstKind::Value(cv) => cv.ty,
560 ty::ConstKind::Alias(_, alias_const) => {
561 alias_const.type_of(infcx.tcx).skip_norm_wip()
562 }
563 ty::ConstKind::Expr(_) => {
567 return ProcessResult::Changed(mk_pending(
568 obligation,
569 PredicateObligations::new(),
570 ));
571 }
572 ty::ConstKind::Placeholder(_) => {
573 bug!("placeholder const {:?} in old solver", ct)
574 }
575 ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
576 ty::ConstKind::Param(param_ct) => {
577 param_ct.find_const_ty_from_env(obligation.param_env)
578 }
579 };
580
581 match infcx.at(&obligation.cause, obligation.param_env).eq(
582 DefineOpaqueTypes::Yes,
584 ct_ty,
585 ty,
586 ) {
587 Ok(inf_ok) => ProcessResult::Changed(mk_pending(
588 obligation,
589 inf_ok.into_obligations(),
590 )),
591 Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
592 SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
593 )),
594 }
595 }
596
597 _ if !self
602 .selcx
603 .tcx()
604 .recursion_limit()
605 .value_within_limit(obligation.recursion_depth) =>
606 {
607 self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false);
608 }
609
610 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
611 if term.is_trivially_wf(self.selcx.tcx()) {
612 return ProcessResult::Changed(thin_vec![]);
613 }
614
615 match wf::obligations(
616 self.selcx.infcx,
617 obligation.param_env,
618 obligation.cause.body_def_id,
619 obligation.recursion_depth + 1,
620 term,
621 obligation.cause.span,
622 ) {
623 None => {
624 pending_obligation.stalled_on = vec![
625 TyOrConstInferVar::maybe_from_term::<TyCtxt<'tcx>>(term).unwrap(),
626 ];
627 ProcessResult::Unchanged
628 }
629 Some(os) => ProcessResult::Changed(mk_pending(obligation, os)),
630 }
631 }
632
633 ty::PredicateKind::Subtype(subtype) => {
634 match self.selcx.infcx.subtype_predicate(
635 &obligation.cause,
636 obligation.param_env,
637 Binder::dummy(subtype),
638 ) {
639 Err((a, b)) => {
640 pending_obligation.stalled_on =
642 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
643 ProcessResult::Unchanged
644 }
645 Ok(Ok(ok)) => {
646 ProcessResult::Changed(mk_pending(obligation, ok.obligations))
647 }
648 Ok(Err(err)) => {
649 let expected_found = if subtype.a_is_expected {
650 ExpectedFound::new(subtype.a, subtype.b)
651 } else {
652 ExpectedFound::new(subtype.b, subtype.a)
653 };
654 ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
655 }
656 }
657 }
658
659 ty::PredicateKind::Coerce(coerce) => {
660 match self.selcx.infcx.coerce_predicate(
661 &obligation.cause,
662 obligation.param_env,
663 Binder::dummy(coerce),
664 ) {
665 Err((a, b)) => {
666 pending_obligation.stalled_on =
668 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
669 ProcessResult::Unchanged
670 }
671 Ok(Ok(ok)) => {
672 ProcessResult::Changed(mk_pending(obligation, ok.obligations))
673 }
674 Ok(Err(err)) => {
675 let expected_found = ExpectedFound::new(coerce.b, coerce.a);
676 ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
677 }
678 }
679 }
680
681 ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(alias_const)) => {
682 match const_evaluatable::is_const_evaluatable(
683 self.selcx.infcx,
684 alias_const,
685 obligation.param_env,
686 obligation.cause.span,
687 ) {
688 Ok(()) => ProcessResult::Changed(Default::default()),
689 Err(NotConstEvaluatable::MentionsInfer) => {
690 pending_obligation.stalled_on.clear();
691 pending_obligation.stalled_on.extend(alias_const.walk().filter_map(
692 TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>,
693 ));
694 ProcessResult::Unchanged
695 }
696 Err(
697 e @ NotConstEvaluatable::MentionsParam
698 | e @ NotConstEvaluatable::Error(_),
699 ) => ProcessResult::Error(FulfillmentErrorCode::Select(
700 SelectionError::NotConstEvaluatable(e),
701 )),
702 }
703 }
704
705 ty::PredicateKind::ConstEquate(c1, c2) => {
706 let tcx = self.selcx.tcx();
707 assert!(
708 tcx.features().generic_const_exprs(),
709 "`ConstEquate` without a feature gate: {c1:?} {c2:?}",
710 );
711 {
716 let c1 = tcx.expand_abstract_consts(c1);
717 let c2 = tcx.expand_abstract_consts(c2);
718 debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
719
720 match (c1.kind(), c2.kind()) {
721 (ty::ConstKind::Alias(_, a), ty::ConstKind::Alias(_, b))
722 if a.kind == b.kind
723 && matches!(
724 a.kind,
725 ty::AliasConstKind::Projection { .. }
726 | ty::AliasConstKind::InherentSelf { .. }
727 | ty::AliasConstKind::InherentImpl { .. }
728 ) =>
729 {
730 if let Ok(new_obligations) = infcx
731 .at(&obligation.cause, obligation.param_env)
732 .eq(
735 DefineOpaqueTypes::Yes,
736 ty::AliasTerm::from(a),
737 ty::AliasTerm::from(b),
738 )
739 {
740 return ProcessResult::Changed(mk_pending(
741 obligation,
742 new_obligations.into_obligations(),
743 ));
744 }
745 }
746 (_, ty::ConstKind::Alias(_, _)) | (ty::ConstKind::Alias(_, _), _) => (),
747 (_, _) => {
748 if let Ok(new_obligations) = infcx
749 .at(&obligation.cause, obligation.param_env)
750 .eq(DefineOpaqueTypes::Yes, c1, c2)
753 {
754 return ProcessResult::Changed(mk_pending(
755 obligation,
756 new_obligations.into_obligations(),
757 ));
758 }
759 }
760 }
761 }
762
763 let stalled_on = &mut pending_obligation.stalled_on;
764
765 let mut evaluate = |c: Const<'tcx>| {
766 if let ty::ConstKind::Alias(_, alias_const) = c.kind() {
767 match super::try_evaluate_const(
768 self.selcx.infcx,
769 c,
770 obligation.param_env,
771 |ty| Ok::<_, !>(ty.skip_norm_wip()),
772 ) {
773 Ok(val) => Ok(val),
774 e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
775 stalled_on.extend(alias_const.args.iter().filter_map(
776 TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>,
777 ));
778 e
779 }
780 e @ Err(
781 EvaluateConstErr::EvaluationFailure(_)
782 | EvaluateConstErr::InvalidConstParamTy(_),
783 ) => e,
784 }
785 } else {
786 Ok(c)
787 }
788 };
789
790 match (evaluate(c1), evaluate(c2)) {
791 (Ok(c1), Ok(c2)) => {
792 match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
793 DefineOpaqueTypes::Yes,
796 c1,
797 c2,
798 ) {
799 Ok(inf_ok) => ProcessResult::Changed(mk_pending(
800 obligation,
801 inf_ok.into_obligations(),
802 )),
803 Err(err) => {
804 ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
805 ExpectedFound::new(c1, c2),
806 err,
807 ))
808 }
809 }
810 }
811 (Err(EvaluateConstErr::InvalidConstParamTy(e)), _)
812 | (_, Err(EvaluateConstErr::InvalidConstParamTy(e))) => {
813 ProcessResult::Error(FulfillmentErrorCode::Select(
814 SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)),
815 ))
816 }
817 (Err(EvaluateConstErr::EvaluationFailure(e)), _)
818 | (_, Err(EvaluateConstErr::EvaluationFailure(e))) => {
819 ProcessResult::Error(FulfillmentErrorCode::Select(
820 SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)),
821 ))
822 }
823 (Err(EvaluateConstErr::HasGenericsOrInfers), _)
824 | (_, Err(EvaluateConstErr::HasGenericsOrInfers)) => {
825 if c1.has_non_region_infer() || c2.has_non_region_infer() {
826 ProcessResult::Unchanged
827 } else {
828 let expected_found = ExpectedFound::new(c1, c2);
830 ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
831 expected_found,
832 TypeError::ConstMismatch(expected_found),
833 ))
834 }
835 }
836 }
837 }
838 ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
839 if may_use_unstable_feature(self.selcx.infcx, obligation.param_env, symbol) {
840 ProcessResult::Changed(Default::default())
841 } else {
842 ProcessResult::Unchanged
843 }
844 }
845 },
846 }
847 }
848
849 #[inline(never)]
850 fn process_backedge<'c, I>(
851 &mut self,
852 cycle: I,
853 _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
854 ) -> Result<(), FulfillmentErrorCode<'tcx>>
855 where
856 I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
857 {
858 if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
859 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:859",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(859u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("process_child_obligations: coinductive match")
as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("process_child_obligations: coinductive match");
860 Ok(())
861 } else {
862 let cycle = cycle.map(|c| c.obligation.clone()).collect();
863 Err(FulfillmentErrorCode::Cycle(cycle))
864 }
865 }
866}
867
868impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
869 {}
#[allow(clippy :: suspicious_else_formatting)]
{
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("process_trait_obligation",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(869u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("trait_obligation")
}> =
::tracing::__macro_support::FieldName::new("trait_obligation");
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(&trait_obligation)
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:
ProcessResult<PendingPredicateObligation<'tcx>,
FulfillmentErrorCode<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
if true {
if !!self.selcx.typing_mode().is_coherence() {
{
::core::panicking::panic_fmt(format_args!("old solver coherence"));
}
};
};
let infcx = self.selcx.infcx;
if obligation.predicate.is_global() {
if infcx.predicate_must_hold_considering_regions(obligation) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:882",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(882u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("selecting trait at depth {0} evaluated to holds",
obligation.recursion_depth) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};
return ProcessResult::Changed(Default::default());
}
}
match self.selcx.poly_select(&trait_obligation) {
Ok(Some(impl_source)) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:892",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(892u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("selecting trait at depth {0} yielded Ok(Some)",
obligation.recursion_depth) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};
ProcessResult::Changed(mk_pending(obligation,
impl_source.nested_obligations()))
}
Ok(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/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:896",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(896u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("selecting trait at depth {0} yielded Ok(None)",
obligation.recursion_depth) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};
stalled_on.clear();
stalled_on.extend(args_infer_vars(&self.selcx,
trait_obligation.predicate.map_bound(|pred|
pred.trait_ref.args)));
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:908",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(908u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("process_predicate: pending obligation {0:?} now stalled on {1:?}",
infcx.deeply_resolve_ignoring_regions(obligation.clone()),
stalled_on) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
ProcessResult::Unchanged
}
Err(selection_err) => {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:917",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(917u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("selecting trait at depth {0} yielded Err",
obligation.recursion_depth) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};
ProcessResult::Error(FulfillmentErrorCode::Select(selection_err))
}
}
}
}
}#[instrument(level = "debug", skip(self, obligation, stalled_on))]
870 fn process_trait_obligation(
871 &mut self,
872 obligation: &PredicateObligation<'tcx>,
873 trait_obligation: PolyTraitObligation<'tcx>,
874 stalled_on: &mut Vec<TyOrConstInferVar>,
875 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
876 debug_assert!(!self.selcx.typing_mode().is_coherence(), "old solver coherence");
877 let infcx = self.selcx.infcx;
878 if obligation.predicate.is_global() {
879 if infcx.predicate_must_hold_considering_regions(obligation) {
882 debug!(
883 "selecting trait at depth {} evaluated to holds",
884 obligation.recursion_depth
885 );
886 return ProcessResult::Changed(Default::default());
887 }
888 }
889
890 match self.selcx.poly_select(&trait_obligation) {
891 Ok(Some(impl_source)) => {
892 debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
893 ProcessResult::Changed(mk_pending(obligation, impl_source.nested_obligations()))
894 }
895 Ok(None) => {
896 debug!("selecting trait at depth {} yielded Ok(None)", obligation.recursion_depth);
897
898 stalled_on.clear();
903 stalled_on.extend(args_infer_vars(
904 &self.selcx,
905 trait_obligation.predicate.map_bound(|pred| pred.trait_ref.args),
906 ));
907
908 debug!(
909 "process_predicate: pending obligation {:?} now stalled on {:?}",
910 infcx.deeply_resolve_ignoring_regions(obligation.clone()),
911 stalled_on
912 );
913
914 ProcessResult::Unchanged
915 }
916 Err(selection_err) => {
917 debug!("selecting trait at depth {} yielded Err", obligation.recursion_depth);
918
919 ProcessResult::Error(FulfillmentErrorCode::Select(selection_err))
920 }
921 }
922 }
923
924 fn process_projection_obligation(
925 &mut self,
926 obligation: &PredicateObligation<'tcx>,
927 project_obligation: PolyProjectionObligation<'tcx>,
928 stalled_on: &mut Vec<TyOrConstInferVar>,
929 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
930 if true {
if !!self.selcx.typing_mode().is_coherence() {
{
::core::panicking::panic_fmt(format_args!("old solver coherence"));
}
};
};debug_assert!(!self.selcx.typing_mode().is_coherence(), "old solver coherence");
931
932 let tcx = self.selcx.tcx();
933 let infcx = self.selcx.infcx;
934 if obligation.predicate.is_global() {
935 if infcx.predicate_must_hold_considering_regions(obligation) {
938 if let Some(key) = ProjectionCacheKey::from_poly_projection_obligation(
939 &mut self.selcx,
940 &project_obligation,
941 ) {
942 infcx
946 .inner
947 .borrow_mut()
948 .projection_cache()
949 .complete(key, EvaluationResult::EvaluatedToOk);
950 }
951 return ProcessResult::Changed(Default::default());
952 } else {
953 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs:953",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/b6eeb93c992027a03e1fd120b6652546396b142c/compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(953u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message"],
::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!("Does NOT hold: {0:?}",
obligation) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("Does NOT hold: {:?}", obligation);
954 }
955 }
956
957 match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) {
958 ProjectAndUnifyResult::Holds(os) if os.is_empty() => {
959 ProcessResult::Changed(mk_pending(obligation, os))
960 }
961 ProjectAndUnifyResult::Holds(os) => {
962 let input_projection_term = infcx
963 .deeply_resolve_ignoring_regions(project_obligation.predicate)
964 .map_bound(|p| p.projection_term);
965 let all_same_projection_term = os.iter().all(|o| {
966 let Some(proj_clause) = o.predicate.as_projection_clause() else {
967 return false;
968 };
969 infcx
970 .deeply_resolve_ignoring_regions(proj_clause)
971 .map_bound(|p| p.projection_term)
972 == input_projection_term
973 });
974 if all_same_projection_term {
975 ProcessResult::Error(FulfillmentErrorCode::Ambiguity { overflow: None })
985 } else {
986 ProcessResult::Changed(mk_pending(obligation, os))
987 }
988 }
989 ProjectAndUnifyResult::FailedNormalization => {
990 stalled_on.clear();
991 stalled_on.extend(args_infer_vars(
992 &self.selcx,
993 project_obligation.predicate.map_bound(|pred| pred.projection_term.args),
994 ));
995 ProcessResult::Unchanged
996 }
997 ProjectAndUnifyResult::Recursive => {
999 let mut obligations = PredicateObligations::with_capacity(1);
1000 obligations.push(project_obligation.with(tcx, project_obligation.predicate));
1001
1002 ProcessResult::Changed(mk_pending(obligation, obligations))
1003 }
1004 ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
1005 ProcessResult::Error(FulfillmentErrorCode::Project(e))
1006 }
1007 }
1008 }
1009
1010 fn process_host_obligation(
1011 &mut self,
1012 obligation: &PredicateObligation<'tcx>,
1013 host_obligation: HostEffectObligation<'tcx>,
1014 stalled_on: &mut Vec<TyOrConstInferVar>,
1015 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
1016 match effects::evaluate_host_effect_obligation(&mut self.selcx, &host_obligation) {
1017 Ok(nested) => ProcessResult::Changed(mk_pending(obligation, nested)),
1018 Err(effects::EvaluationFailure::Ambiguous) => {
1019 stalled_on.clear();
1020 stalled_on.extend(args_infer_vars(
1021 &self.selcx,
1022 ty::Binder::dummy(host_obligation.predicate.trait_ref.args),
1023 ));
1024 ProcessResult::Unchanged
1025 }
1026 Err(effects::EvaluationFailure::NoSolution) => {
1027 ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::Unimplemented))
1028 }
1029 }
1030 }
1031}
1032
1033fn args_infer_vars<'tcx>(
1035 selcx: &SelectionContext<'_, 'tcx>,
1036 args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
1037) -> impl Iterator<Item = TyOrConstInferVar> {
1038 selcx
1039 .infcx
1040 .deeply_resolve_ignoring_regions(args)
1041 .skip_binder() .iter()
1043 .filter(|arg| arg.has_non_region_infer())
1044 .flat_map(|arg| {
1045 let mut walker = arg.walk();
1046 while let Some(c) = walker.next() {
1047 if !c.has_non_region_infer() {
1048 walker.visited.remove(&c);
1049 walker.skip_current_subtree();
1050 }
1051 }
1052 walker.visited.into_iter()
1053 })
1054 .filter_map(TyOrConstInferVar::maybe_from_generic_arg::<TyCtxt<'tcx>>)
1055}
1056
1057#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for OldSolverError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "OldSolverError",
&&self.0)
}
}Debug)]
1058pub struct OldSolverError<'tcx>(
1059 Error<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>>,
1060);
1061
1062impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx> {
1063 fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
1064 let mut iter = error.0.backtrace.into_iter();
1065 let obligation = iter.next().unwrap().obligation;
1066 let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation);
1069 FulfillmentError::new(obligation, error.0.error, root_obligation)
1070 }
1071}
1072
1073impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> {
1074 fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
1075 match error.0.error {
1076 FulfillmentErrorCode::Select(_)
1077 | FulfillmentErrorCode::Project(_)
1078 | FulfillmentErrorCode::Outlives
1079 | FulfillmentErrorCode::Subtype(_, _)
1080 | FulfillmentErrorCode::ConstEquate(_, _) => ScrubbedTraitError::TrueError,
1081 FulfillmentErrorCode::Ambiguity { overflow: _ } => ScrubbedTraitError::Ambiguity,
1082 FulfillmentErrorCode::Cycle(cycle) => ScrubbedTraitError::Cycle(cycle),
1083 }
1084 }
1085}