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