1use std::marker::PhantomData;
2
3use rustc_data_structures::obligation_forest::{
4 Error, ForestObligation, ObligationForest, ObligationProcessor, Outcome, ProcessResult,
5};
6use rustc_hir::def_id::LocalDefId;
7use rustc_infer::infer::DefineOpaqueTypes;
8use rustc_infer::traits::{
9 FromSolverError, PolyTraitObligation, PredicateObligations, ProjectionCacheKey, SelectionError,
10 TraitEngine,
11};
12use rustc_middle::bug;
13use rustc_middle::ty::abstract_const::NotConstEvaluatable;
14use rustc_middle::ty::error::{ExpectedFound, TypeError};
15use rustc_middle::ty::{
16 self, Binder, Const, GenericArgsRef, TypeVisitable, TypeVisitableExt, TypingMode,
17 may_use_unstable_feature,
18};
19use rustc_span::DUMMY_SP;
20use thin_vec::{ThinVec, thin_vec};
21use tracing::{debug, debug_span, instrument};
22
23use super::effects::{self, HostEffectObligation};
24use super::project::{self, ProjectAndUnifyResult};
25use super::select::SelectionContext;
26use super::{
27 EvaluationResult, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
28 ScrubbedTraitError, const_evaluatable, wf,
29};
30use crate::error_reporting::InferCtxtErrorExt;
31use crate::infer::{InferCtxt, TyOrConstInferVar};
32use crate::solve::StalledOnCoroutines;
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) -> PendingPredicateObligation<'tcx> {
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>) -> Vec<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("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(&["obligation_forest_size"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&self.predicates.len())
as &dyn 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: Vec<E> = outcome
121 .errors
122 .into_iter()
123 .map(|err| E::from_solver_error(infcx, OldSolverError(err)))
124 .collect();
125
126 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/fulfill.rs:126",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(126u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("select({0} predicates remaining, {1} errors) done",
self.predicates.len(), errors.len()) as &dyn Value))])
});
} else { ; }
};debug!(
127 "select({} predicates remaining, {} errors) done",
128 self.predicates.len(),
129 errors.len()
130 );
131
132 errors
133 }
134}
135
136impl<'tcx, E> TraitEngine<'tcx, E> for FulfillmentContext<'tcx, E>
137where
138 E: FromSolverError<'tcx, OldSolverError<'tcx>>,
139{
140 #[inline]
141 fn register_predicate_obligation(
142 &mut self,
143 infcx: &InferCtxt<'tcx>,
144 mut obligation: PredicateObligation<'tcx>,
145 ) {
146 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());
147 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());
150 obligation.predicate = infcx.resolve_vars_if_possible(obligation.predicate);
151
152 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/fulfill.rs:152",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(152u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message",
"obligation"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("register_predicate_obligation")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&obligation)
as &dyn Value))])
});
} else { ; }
};debug!(?obligation, "register_predicate_obligation");
153
154 self.predicates
155 .register_obligation(PendingPredicateObligation { obligation, stalled_on: ::alloc::vec::Vec::new()vec![] });
156 }
157
158 fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
159 self.predicates
160 .to_errors(FulfillmentErrorCode::Ambiguity { overflow: None })
161 .into_iter()
162 .map(|err| E::from_solver_error(infcx, OldSolverError(err)))
163 .collect()
164 }
165
166 fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<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() {
176 TypingMode::Analysis { defining_opaque_types_and_generators } => {
177 defining_opaque_types_and_generators
178 }
179 TypingMode::Coherence
180 | TypingMode::Borrowck { defining_opaque_types: _ }
181 | TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ }
182 | TypingMode::PostAnalysis => return Default::default(),
183 };
184
185 if stalled_coroutines.is_empty() {
186 return Default::default();
187 }
188
189 let mut processor = DrainProcessor {
190 infcx,
191 removed_predicates: PredicateObligations::new(),
192 stalled_coroutines,
193 };
194 let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut processor);
195 if !outcome.errors.is_empty() {
::core::panicking::panic("assertion failed: outcome.errors.is_empty()")
};assert!(outcome.errors.is_empty());
196 return processor.removed_predicates;
197
198 struct DrainProcessor<'a, 'tcx> {
199 infcx: &'a InferCtxt<'tcx>,
200 removed_predicates: PredicateObligations<'tcx>,
201 stalled_coroutines: &'tcx ty::List<LocalDefId>,
202 }
203
204 impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> {
205 type Obligation = PendingPredicateObligation<'tcx>;
206 type Error = !;
207 type OUT = Outcome<Self::Obligation, Self::Error>;
208
209 fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
210 self.infcx
211 .resolve_vars_if_possible(pending_obligation.obligation.predicate)
212 .visit_with(&mut StalledOnCoroutines {
213 stalled_coroutines: self.stalled_coroutines,
214 span: DUMMY_SP,
215 cache: Default::default(),
216 })
217 .is_break()
218 }
219
220 fn process_obligation(
221 &mut self,
222 pending_obligation: &mut PendingPredicateObligation<'tcx>,
223 ) -> ProcessResult<PendingPredicateObligation<'tcx>, !> {
224 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));
225 self.removed_predicates.push(pending_obligation.obligation.clone());
226 ProcessResult::Changed(Default::default())
227 }
228
229 fn process_backedge<'c, I>(
230 &mut self,
231 cycle: I,
232 _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
233 ) -> Result<(), !>
234 where
235 I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
236 {
237 self.removed_predicates.extend(cycle.map(|c| c.obligation.clone()));
238 Ok(())
239 }
240 }
241 }
242
243 fn has_pending_obligations(&self) -> bool {
244 self.predicates.has_pending_obligations()
245 }
246
247 fn pending_obligations(&self) -> PredicateObligations<'tcx> {
248 self.predicates.map_pending_obligations(|o| o.obligation.clone())
249 }
250}
251
252struct FulfillProcessor<'a, 'tcx> {
253 selcx: SelectionContext<'a, 'tcx>,
254}
255
256fn mk_pending<'tcx>(
257 parent: &PredicateObligation<'tcx>,
258 os: PredicateObligations<'tcx>,
259) -> PendingPredicateObligations<'tcx> {
260 os.into_iter()
261 .map(|mut o| {
262 o.set_depth_from_parent(parent.recursion_depth);
263 PendingPredicateObligation { obligation: o, stalled_on: ::alloc::vec::Vec::new()vec![] }
264 })
265 .collect()
266}
267
268impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
269 type Obligation = PendingPredicateObligation<'tcx>;
270 type Error = FulfillmentErrorCode<'tcx>;
271 type OUT = Outcome<Self::Obligation, Self::Error>;
272
273 #[inline]
283 fn skippable_obligations<'b>(
284 &'b self,
285 it: impl Iterator<Item = &'b Self::Obligation>,
286 ) -> usize {
287 let is_unchanged = self.selcx.infcx.is_ty_infer_var_definitely_unchanged();
288
289 it.take_while(|o| match o.stalled_on.as_slice() {
290 [o] => is_unchanged(*o),
291 _ => false,
292 })
293 .count()
294 }
295
296 #[inline(always)]
302 fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
303 let stalled_on = &pending_obligation.stalled_on;
307 match stalled_on.len() {
308 1 => self.selcx.infcx.ty_or_const_infer_var_changed(stalled_on[0]),
312
313 0 => true,
321
322 _ => (|| {
329 for &infer_var in stalled_on {
330 if self.selcx.infcx.ty_or_const_infer_var_changed(infer_var) {
331 return true;
332 }
333 }
334 false
335 })(),
336 }
337 }
338
339 #[inline(never)]
347 #[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("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(347u32),
::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(&[]) })
} 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.truncate(0);
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 compiler/rustc_trait_selection/src/traits/fulfill.rs:356",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(356u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["message",
"obligation"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("pre-resolve")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&obligation)
as &dyn Value))])
});
} else { ; }
};
if obligation.predicate.has_non_region_infer() {
obligation.predicate =
self.selcx.infcx.resolve_vars_if_possible(obligation.predicate);
}
let obligation = &pending_obligation.obligation;
let infcx = self.selcx.infcx;
if 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, 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_middle::util::bug::bug_fmt(format_args!("NormalizesTo is only used by the new solver"))
}
ty::PredicateKind::AliasRelate(..) => {
::rustc_middle::util::bug::bug_fmt(format_args!("AliasRelate is only used by the new solver"))
}
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,
&obligation.cause);
}
ProcessResult::Changed(Default::default())
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(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_middle::util::bug::bug_fmt(format_args!("NormalizesTo is only used by the new solver"))
}
ty::PredicateKind::AliasRelate(..) => {
::rustc_middle::util::bug::bug_fmt(format_args!("AliasRelate is only used by the new solver"))
}
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_middle::util::bug::bug_fmt(format_args!("encountered fresh const in fulfill"))
}
};
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::Unevaluated(uv) => {
infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
}
ty::ConstKind::Expr(_) => {
return ProcessResult::Changed(mk_pending(obligation,
PredicateObligations::new()));
}
ty::ConstKind::Placeholder(_) => {
::rustc_middle::util::bug::bug_fmt(format_args!("placeholder const {0:?} in old solver",
ct))
}
ty::ConstKind::Bound(_, _) =>
::rustc_middle::util::bug::bug_fmt(format_args!("escaping bound vars in {0:?}",
ct)),
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_id,
obligation.recursion_depth + 1, term, obligation.cause.span)
{
None => {
pending_obligation.stalled_on =
<[_]>::into_vec(::alloc::boxed::box_new([TyOrConstInferVar::maybe_from_term(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 =
<[_]>::into_vec(::alloc::boxed::box_new([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 =
<[_]>::into_vec(::alloc::boxed::box_new([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(uv))
=> {
match const_evaluatable::is_const_evaluatable(self.selcx.infcx,
uv, obligation.param_env, obligation.cause.span) {
Ok(()) => ProcessResult::Changed(Default::default()),
Err(NotConstEvaluatable::MentionsInfer) => {
pending_obligation.stalled_on.clear();
pending_obligation.stalled_on.extend(uv.walk().filter_map(TyOrConstInferVar::maybe_from_generic_arg));
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 compiler/rustc_trait_selection/src/traits/fulfill.rs:683",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(683u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("equating consts:\nc1= {0:?}\nc2= {1:?}",
c1, c2) as &dyn Value))])
});
} else { ; }
};
use rustc_hir::def::DefKind;
match (c1.kind(), c2.kind()) {
(ty::ConstKind::Unevaluated(a),
ty::ConstKind::Unevaluated(b)) if
a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst
=> {
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::Unevaluated(_)) |
(ty::ConstKind::Unevaluated(_), _) => (),
(_, _) => {
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::Unevaluated(unevaluated) = c.kind() {
match super::try_evaluate_const(self.selcx.infcx, c,
obligation.param_env) {
Ok(val) => Ok(val),
e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
stalled_on.extend(unevaluated.args.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg));
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))]
348 fn process_obligation(
349 &mut self,
350 pending_obligation: &mut PendingPredicateObligation<'tcx>,
351 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
352 pending_obligation.stalled_on.truncate(0);
353
354 let obligation = &mut pending_obligation.obligation;
355
356 debug!(?obligation, "pre-resolve");
357
358 if obligation.predicate.has_non_region_infer() {
359 obligation.predicate = self.selcx.infcx.resolve_vars_if_possible(obligation.predicate);
360 }
361
362 let obligation = &pending_obligation.obligation;
363
364 let infcx = self.selcx.infcx;
365
366 if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) {
367 return ProcessResult::Changed(thin_vec![]);
368 }
369
370 if obligation.predicate.has_aliases() {
371 let mut obligations = PredicateObligations::new();
372 let predicate = normalize_with_depth_to(
373 &mut self.selcx,
374 obligation.param_env,
375 obligation.cause.clone(),
376 obligation.recursion_depth + 1,
377 obligation.predicate,
378 &mut obligations,
379 );
380 if predicate != obligation.predicate {
381 obligations.push(obligation.with(infcx.tcx, predicate));
382 return ProcessResult::Changed(mk_pending(obligation, obligations));
383 }
384 }
385 let binder = obligation.predicate.kind();
386 match binder.no_bound_vars() {
387 None => match binder.skip_binder() {
388 ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) => {
392 let trait_obligation = obligation.with(infcx.tcx, binder.rebind(trait_ref));
393
394 self.process_trait_obligation(
395 obligation,
396 trait_obligation,
397 &mut pending_obligation.stalled_on,
398 )
399 }
400 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
401 let project_obligation = obligation.with(infcx.tcx, binder.rebind(data));
402
403 self.process_projection_obligation(
404 obligation,
405 project_obligation,
406 &mut pending_obligation.stalled_on,
407 )
408 }
409 ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
410 | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_))
411 | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
412 | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_))
413 | ty::PredicateKind::DynCompatible(_)
414 | ty::PredicateKind::Subtype(_)
415 | ty::PredicateKind::Coerce(_)
416 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
417 | ty::PredicateKind::ConstEquate(..)
418 | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
422 let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
423 let mut obligations = PredicateObligations::with_capacity(1);
424 obligations.push(obligation.with(infcx.tcx, pred));
425
426 ProcessResult::Changed(mk_pending(obligation, obligations))
427 }
428 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
429 ty::PredicateKind::NormalizesTo(..) => {
430 bug!("NormalizesTo is only used by the new solver")
431 }
432 ty::PredicateKind::AliasRelate(..) => {
433 bug!("AliasRelate is only used by the new solver")
434 }
435 ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_)) => {
436 unreachable!("unexpected higher ranked `UnstableFeature` goal")
437 }
438 },
439 Some(pred) => match pred {
440 ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
441 let trait_obligation = obligation.with(infcx.tcx, Binder::dummy(data));
442
443 self.process_trait_obligation(
444 obligation,
445 trait_obligation,
446 &mut pending_obligation.stalled_on,
447 )
448 }
449
450 ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(data)) => {
451 let host_obligation = obligation.with(infcx.tcx, data);
452
453 self.process_host_obligation(
454 obligation,
455 host_obligation,
456 &mut pending_obligation.stalled_on,
457 )
458 }
459
460 ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
461 if infcx.considering_regions {
462 infcx.register_region_outlives_constraint(data, &obligation.cause);
463 }
464
465 ProcessResult::Changed(Default::default())
466 }
467
468 ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
469 t_a,
470 r_b,
471 ))) => {
472 if infcx.considering_regions {
473 infcx.register_type_outlives_constraint(t_a, r_b, &obligation.cause);
474 }
475 ProcessResult::Changed(Default::default())
476 }
477
478 ty::PredicateKind::Clause(ty::ClauseKind::Projection(ref data)) => {
479 let project_obligation = obligation.with(infcx.tcx, Binder::dummy(*data));
480
481 self.process_projection_obligation(
482 obligation,
483 project_obligation,
484 &mut pending_obligation.stalled_on,
485 )
486 }
487
488 ty::PredicateKind::DynCompatible(trait_def_id) => {
489 if !self.selcx.tcx().is_dyn_compatible(trait_def_id) {
490 ProcessResult::Error(FulfillmentErrorCode::Select(
491 SelectionError::Unimplemented,
492 ))
493 } else {
494 ProcessResult::Changed(Default::default())
495 }
496 }
497
498 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
499 ty::PredicateKind::NormalizesTo(..) => {
500 bug!("NormalizesTo is only used by the new solver")
501 }
502 ty::PredicateKind::AliasRelate(..) => {
503 bug!("AliasRelate is only used by the new solver")
504 }
505 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
509 let ct = infcx.shallow_resolve_const(ct);
510 let ct_ty = match ct.kind() {
511 ty::ConstKind::Infer(var) => {
512 let var = match var {
513 ty::InferConst::Var(vid) => TyOrConstInferVar::Const(vid),
514 ty::InferConst::Fresh(_) => {
515 bug!("encountered fresh const in fulfill")
516 }
517 };
518 pending_obligation.stalled_on.clear();
519 pending_obligation.stalled_on.extend([var]);
520 return ProcessResult::Unchanged;
521 }
522 ty::ConstKind::Error(_) => {
523 return ProcessResult::Changed(PendingPredicateObligations::new());
524 }
525 ty::ConstKind::Value(cv) => cv.ty,
526 ty::ConstKind::Unevaluated(uv) => {
527 infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args)
528 }
529 ty::ConstKind::Expr(_) => {
533 return ProcessResult::Changed(mk_pending(
534 obligation,
535 PredicateObligations::new(),
536 ));
537 }
538 ty::ConstKind::Placeholder(_) => {
539 bug!("placeholder const {:?} in old solver", ct)
540 }
541 ty::ConstKind::Bound(_, _) => bug!("escaping bound vars in {:?}", ct),
542 ty::ConstKind::Param(param_ct) => {
543 param_ct.find_const_ty_from_env(obligation.param_env)
544 }
545 };
546
547 match infcx.at(&obligation.cause, obligation.param_env).eq(
548 DefineOpaqueTypes::Yes,
550 ct_ty,
551 ty,
552 ) {
553 Ok(inf_ok) => ProcessResult::Changed(mk_pending(
554 obligation,
555 inf_ok.into_obligations(),
556 )),
557 Err(_) => ProcessResult::Error(FulfillmentErrorCode::Select(
558 SelectionError::ConstArgHasWrongType { ct, ct_ty, expected_ty: ty },
559 )),
560 }
561 }
562
563 _ if !self
568 .selcx
569 .tcx()
570 .recursion_limit()
571 .value_within_limit(obligation.recursion_depth) =>
572 {
573 self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false);
574 }
575
576 ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) => {
577 if term.is_trivially_wf(self.selcx.tcx()) {
578 return ProcessResult::Changed(thin_vec![]);
579 }
580
581 match wf::obligations(
582 self.selcx.infcx,
583 obligation.param_env,
584 obligation.cause.body_id,
585 obligation.recursion_depth + 1,
586 term,
587 obligation.cause.span,
588 ) {
589 None => {
590 pending_obligation.stalled_on =
591 vec![TyOrConstInferVar::maybe_from_term(term).unwrap()];
592 ProcessResult::Unchanged
593 }
594 Some(os) => ProcessResult::Changed(mk_pending(obligation, os)),
595 }
596 }
597
598 ty::PredicateKind::Subtype(subtype) => {
599 match self.selcx.infcx.subtype_predicate(
600 &obligation.cause,
601 obligation.param_env,
602 Binder::dummy(subtype),
603 ) {
604 Err((a, b)) => {
605 pending_obligation.stalled_on =
607 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
608 ProcessResult::Unchanged
609 }
610 Ok(Ok(ok)) => {
611 ProcessResult::Changed(mk_pending(obligation, ok.obligations))
612 }
613 Ok(Err(err)) => {
614 let expected_found = if subtype.a_is_expected {
615 ExpectedFound::new(subtype.a, subtype.b)
616 } else {
617 ExpectedFound::new(subtype.b, subtype.a)
618 };
619 ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
620 }
621 }
622 }
623
624 ty::PredicateKind::Coerce(coerce) => {
625 match self.selcx.infcx.coerce_predicate(
626 &obligation.cause,
627 obligation.param_env,
628 Binder::dummy(coerce),
629 ) {
630 Err((a, b)) => {
631 pending_obligation.stalled_on =
633 vec![TyOrConstInferVar::Ty(a), TyOrConstInferVar::Ty(b)];
634 ProcessResult::Unchanged
635 }
636 Ok(Ok(ok)) => {
637 ProcessResult::Changed(mk_pending(obligation, ok.obligations))
638 }
639 Ok(Err(err)) => {
640 let expected_found = ExpectedFound::new(coerce.b, coerce.a);
641 ProcessResult::Error(FulfillmentErrorCode::Subtype(expected_found, err))
642 }
643 }
644 }
645
646 ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(uv)) => {
647 match const_evaluatable::is_const_evaluatable(
648 self.selcx.infcx,
649 uv,
650 obligation.param_env,
651 obligation.cause.span,
652 ) {
653 Ok(()) => ProcessResult::Changed(Default::default()),
654 Err(NotConstEvaluatable::MentionsInfer) => {
655 pending_obligation.stalled_on.clear();
656 pending_obligation.stalled_on.extend(
657 uv.walk().filter_map(TyOrConstInferVar::maybe_from_generic_arg),
658 );
659 ProcessResult::Unchanged
660 }
661 Err(
662 e @ NotConstEvaluatable::MentionsParam
663 | e @ NotConstEvaluatable::Error(_),
664 ) => ProcessResult::Error(FulfillmentErrorCode::Select(
665 SelectionError::NotConstEvaluatable(e),
666 )),
667 }
668 }
669
670 ty::PredicateKind::ConstEquate(c1, c2) => {
671 let tcx = self.selcx.tcx();
672 assert!(
673 tcx.features().generic_const_exprs(),
674 "`ConstEquate` without a feature gate: {c1:?} {c2:?}",
675 );
676 {
681 let c1 = tcx.expand_abstract_consts(c1);
682 let c2 = tcx.expand_abstract_consts(c2);
683 debug!("equating consts:\nc1= {:?}\nc2= {:?}", c1, c2);
684
685 use rustc_hir::def::DefKind;
686 match (c1.kind(), c2.kind()) {
687 (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b))
688 if a.def == b.def && tcx.def_kind(a.def) == DefKind::AssocConst =>
689 {
690 if let Ok(new_obligations) = infcx
691 .at(&obligation.cause, obligation.param_env)
692 .eq(
695 DefineOpaqueTypes::Yes,
696 ty::AliasTerm::from(a),
697 ty::AliasTerm::from(b),
698 )
699 {
700 return ProcessResult::Changed(mk_pending(
701 obligation,
702 new_obligations.into_obligations(),
703 ));
704 }
705 }
706 (_, ty::ConstKind::Unevaluated(_))
707 | (ty::ConstKind::Unevaluated(_), _) => (),
708 (_, _) => {
709 if let Ok(new_obligations) = infcx
710 .at(&obligation.cause, obligation.param_env)
711 .eq(DefineOpaqueTypes::Yes, c1, c2)
714 {
715 return ProcessResult::Changed(mk_pending(
716 obligation,
717 new_obligations.into_obligations(),
718 ));
719 }
720 }
721 }
722 }
723
724 let stalled_on = &mut pending_obligation.stalled_on;
725
726 let mut evaluate = |c: Const<'tcx>| {
727 if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
728 match super::try_evaluate_const(
729 self.selcx.infcx,
730 c,
731 obligation.param_env,
732 ) {
733 Ok(val) => Ok(val),
734 e @ Err(EvaluateConstErr::HasGenericsOrInfers) => {
735 stalled_on.extend(
736 unevaluated
737 .args
738 .iter()
739 .filter_map(TyOrConstInferVar::maybe_from_generic_arg),
740 );
741 e
742 }
743 e @ Err(
744 EvaluateConstErr::EvaluationFailure(_)
745 | EvaluateConstErr::InvalidConstParamTy(_),
746 ) => e,
747 }
748 } else {
749 Ok(c)
750 }
751 };
752
753 match (evaluate(c1), evaluate(c2)) {
754 (Ok(c1), Ok(c2)) => {
755 match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
756 DefineOpaqueTypes::Yes,
759 c1,
760 c2,
761 ) {
762 Ok(inf_ok) => ProcessResult::Changed(mk_pending(
763 obligation,
764 inf_ok.into_obligations(),
765 )),
766 Err(err) => {
767 ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
768 ExpectedFound::new(c1, c2),
769 err,
770 ))
771 }
772 }
773 }
774 (Err(EvaluateConstErr::InvalidConstParamTy(e)), _)
775 | (_, Err(EvaluateConstErr::InvalidConstParamTy(e))) => {
776 ProcessResult::Error(FulfillmentErrorCode::Select(
777 SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)),
778 ))
779 }
780 (Err(EvaluateConstErr::EvaluationFailure(e)), _)
781 | (_, Err(EvaluateConstErr::EvaluationFailure(e))) => {
782 ProcessResult::Error(FulfillmentErrorCode::Select(
783 SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(e)),
784 ))
785 }
786 (Err(EvaluateConstErr::HasGenericsOrInfers), _)
787 | (_, Err(EvaluateConstErr::HasGenericsOrInfers)) => {
788 if c1.has_non_region_infer() || c2.has_non_region_infer() {
789 ProcessResult::Unchanged
790 } else {
791 let expected_found = ExpectedFound::new(c1, c2);
793 ProcessResult::Error(FulfillmentErrorCode::ConstEquate(
794 expected_found,
795 TypeError::ConstMismatch(expected_found),
796 ))
797 }
798 }
799 }
800 }
801 ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(symbol)) => {
802 if may_use_unstable_feature(self.selcx.infcx, obligation.param_env, symbol) {
803 ProcessResult::Changed(Default::default())
804 } else {
805 ProcessResult::Unchanged
806 }
807 }
808 },
809 }
810 }
811
812 #[inline(never)]
813 fn process_backedge<'c, I>(
814 &mut self,
815 cycle: I,
816 _marker: PhantomData<&'c PendingPredicateObligation<'tcx>>,
817 ) -> Result<(), FulfillmentErrorCode<'tcx>>
818 where
819 I: Clone + Iterator<Item = &'c PendingPredicateObligation<'tcx>>,
820 {
821 if self.selcx.coinductive_match(cycle.clone().map(|s| s.obligation.predicate)) {
822 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/fulfill.rs:822",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(822u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("process_child_obligations: coinductive match")
as &dyn Value))])
});
} else { ; }
};debug!("process_child_obligations: coinductive match");
823 Ok(())
824 } else {
825 let cycle = cycle.map(|c| c.obligation.clone()).collect();
826 Err(FulfillmentErrorCode::Cycle(cycle))
827 }
828 }
829}
830
831impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
832 #[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("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(832u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::fulfill"),
::tracing_core::field::FieldSet::new(&["trait_obligation"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&trait_obligation)
as &dyn 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() &&
!#[allow(non_exhaustive_omitted_patterns)] match infcx.typing_mode()
{
TypingMode::Coherence => true,
_ => false,
} {
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 compiler/rustc_trait_selection/src/traits/fulfill.rs:845",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(845u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("selecting trait at depth {0} evaluated to holds",
obligation.recursion_depth) as &dyn 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 compiler/rustc_trait_selection/src/traits/fulfill.rs:855",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(855u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("selecting trait at depth {0} yielded Ok(Some)",
obligation.recursion_depth) as &dyn 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 compiler/rustc_trait_selection/src/traits/fulfill.rs:859",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("selecting trait at depth {0} yielded Ok(None)",
obligation.recursion_depth) as &dyn 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 compiler/rustc_trait_selection/src/traits/fulfill.rs:871",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/fulfill.rs"),
::tracing_core::__macro_support::Option::Some(871u32),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("process_predicate: pending obligation {0:?} now stalled on {1:?}",
infcx.resolve_vars_if_possible(obligation.clone()),
stalled_on) as &dyn 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 compiler/rustc_trait_selection/src/traits/fulfill.rs:880",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("selecting trait at depth {0} yielded Err",
obligation.recursion_depth) as &dyn Value))])
});
} else { ; }
};
ProcessResult::Error(FulfillmentErrorCode::Select(selection_err))
}
}
}
}
}#[instrument(level = "debug", skip(self, obligation, stalled_on))]
833 fn process_trait_obligation(
834 &mut self,
835 obligation: &PredicateObligation<'tcx>,
836 trait_obligation: PolyTraitObligation<'tcx>,
837 stalled_on: &mut Vec<TyOrConstInferVar>,
838 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
839 let infcx = self.selcx.infcx;
840 if obligation.predicate.is_global() && !matches!(infcx.typing_mode(), TypingMode::Coherence)
841 {
842 if infcx.predicate_must_hold_considering_regions(obligation) {
845 debug!(
846 "selecting trait at depth {} evaluated to holds",
847 obligation.recursion_depth
848 );
849 return ProcessResult::Changed(Default::default());
850 }
851 }
852
853 match self.selcx.poly_select(&trait_obligation) {
854 Ok(Some(impl_source)) => {
855 debug!("selecting trait at depth {} yielded Ok(Some)", obligation.recursion_depth);
856 ProcessResult::Changed(mk_pending(obligation, impl_source.nested_obligations()))
857 }
858 Ok(None) => {
859 debug!("selecting trait at depth {} yielded Ok(None)", obligation.recursion_depth);
860
861 stalled_on.clear();
866 stalled_on.extend(args_infer_vars(
867 &self.selcx,
868 trait_obligation.predicate.map_bound(|pred| pred.trait_ref.args),
869 ));
870
871 debug!(
872 "process_predicate: pending obligation {:?} now stalled on {:?}",
873 infcx.resolve_vars_if_possible(obligation.clone()),
874 stalled_on
875 );
876
877 ProcessResult::Unchanged
878 }
879 Err(selection_err) => {
880 debug!("selecting trait at depth {} yielded Err", obligation.recursion_depth);
881
882 ProcessResult::Error(FulfillmentErrorCode::Select(selection_err))
883 }
884 }
885 }
886
887 fn process_projection_obligation(
888 &mut self,
889 obligation: &PredicateObligation<'tcx>,
890 project_obligation: PolyProjectionObligation<'tcx>,
891 stalled_on: &mut Vec<TyOrConstInferVar>,
892 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
893 let tcx = self.selcx.tcx();
894 let infcx = self.selcx.infcx;
895 if obligation.predicate.is_global() && !#[allow(non_exhaustive_omitted_patterns)] match infcx.typing_mode() {
TypingMode::Coherence => true,
_ => false,
}matches!(infcx.typing_mode(), TypingMode::Coherence)
896 {
897 if infcx.predicate_must_hold_considering_regions(obligation) {
900 if let Some(key) = ProjectionCacheKey::from_poly_projection_obligation(
901 &mut self.selcx,
902 &project_obligation,
903 ) {
904 infcx
908 .inner
909 .borrow_mut()
910 .projection_cache()
911 .complete(key, EvaluationResult::EvaluatedToOk);
912 }
913 return ProcessResult::Changed(Default::default());
914 } else {
915 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/fulfill.rs:915",
"rustc_trait_selection::traits::fulfill",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("Does NOT hold: {0:?}",
obligation) as &dyn Value))])
});
} else { ; }
};debug!("Does NOT hold: {:?}", obligation);
916 }
917 }
918
919 match project::poly_project_and_unify_term(&mut self.selcx, &project_obligation) {
920 ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(obligation, os)),
921 ProjectAndUnifyResult::FailedNormalization => {
922 stalled_on.clear();
923 stalled_on.extend(args_infer_vars(
924 &self.selcx,
925 project_obligation.predicate.map_bound(|pred| pred.projection_term.args),
926 ));
927 ProcessResult::Unchanged
928 }
929 ProjectAndUnifyResult::Recursive => {
931 let mut obligations = PredicateObligations::with_capacity(1);
932 obligations.push(project_obligation.with(tcx, project_obligation.predicate));
933
934 ProcessResult::Changed(mk_pending(obligation, obligations))
935 }
936 ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
937 ProcessResult::Error(FulfillmentErrorCode::Project(e))
938 }
939 }
940 }
941
942 fn process_host_obligation(
943 &mut self,
944 obligation: &PredicateObligation<'tcx>,
945 host_obligation: HostEffectObligation<'tcx>,
946 stalled_on: &mut Vec<TyOrConstInferVar>,
947 ) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
948 match effects::evaluate_host_effect_obligation(&mut self.selcx, &host_obligation) {
949 Ok(nested) => ProcessResult::Changed(mk_pending(obligation, nested)),
950 Err(effects::EvaluationFailure::Ambiguous) => {
951 stalled_on.clear();
952 stalled_on.extend(args_infer_vars(
953 &self.selcx,
954 ty::Binder::dummy(host_obligation.predicate.trait_ref.args),
955 ));
956 ProcessResult::Unchanged
957 }
958 Err(effects::EvaluationFailure::NoSolution) => {
959 ProcessResult::Error(FulfillmentErrorCode::Select(SelectionError::Unimplemented))
960 }
961 }
962 }
963}
964
965fn args_infer_vars<'tcx>(
967 selcx: &SelectionContext<'_, 'tcx>,
968 args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
969) -> impl Iterator<Item = TyOrConstInferVar> {
970 selcx
971 .infcx
972 .resolve_vars_if_possible(args)
973 .skip_binder() .iter()
975 .filter(|arg| arg.has_non_region_infer())
976 .flat_map(|arg| {
977 let mut walker = arg.walk();
978 while let Some(c) = walker.next() {
979 if !c.has_non_region_infer() {
980 walker.visited.remove(&c);
981 walker.skip_current_subtree();
982 }
983 }
984 walker.visited.into_iter()
985 })
986 .filter_map(TyOrConstInferVar::maybe_from_generic_arg)
987}
988
989#[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)]
990pub struct OldSolverError<'tcx>(
991 Error<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>>,
992);
993
994impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx> {
995 fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
996 let mut iter = error.0.backtrace.into_iter();
997 let obligation = iter.next().unwrap().obligation;
998 let root_obligation = iter.next_back().map_or_else(|| obligation.clone(), |e| e.obligation);
1001 FulfillmentError::new(obligation, error.0.error, root_obligation)
1002 }
1003}
1004
1005impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> {
1006 fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
1007 match error.0.error {
1008 FulfillmentErrorCode::Select(_)
1009 | FulfillmentErrorCode::Project(_)
1010 | FulfillmentErrorCode::Subtype(_, _)
1011 | FulfillmentErrorCode::ConstEquate(_, _) => ScrubbedTraitError::TrueError,
1012 FulfillmentErrorCode::Ambiguity { overflow: _ } => ScrubbedTraitError::Ambiguity,
1013 FulfillmentErrorCode::Cycle(cycle) => ScrubbedTraitError::Cycle(cycle),
1014 }
1015 }
1016}