1use rustc_data_structures::unord::UnordSet;
4use rustc_hir::def_id::DefId;
5use rustc_infer::traits::{self, ObligationCause, PredicateObligations};
6use rustc_middle::ty::{self, Ty, TypeVisitableExt};
7use rustc_span::Span;
8use rustc_trait_selection::solve::Certainty;
9use rustc_trait_selection::solve::inspect::{
10 InferCtxtProofTreeExt, InspectConfig, InspectGoal, ProofTreeVisitor,
11};
12use tracing::{debug, instrument, trace};
13
14use crate::FnCtxt;
15
16impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17 #[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("obligations_for_self_ty",
"rustc_hir_typeck::fn_ctxt::inspect_obligations",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"),
::tracing_core::__macro_support::Option::Some(19u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::fn_ctxt::inspect_obligations"),
::tracing_core::field::FieldSet::new(&["self_ty"],
::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(&self_ty)
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: PredicateObligations<'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
if self.next_trait_solver() {
self.obligations_for_self_ty_next(self_ty)
} else {
let ty_var_root = self.root_var(self_ty);
let mut obligations =
self.fulfillment_cx.borrow().pending_obligations();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs:26",
"rustc_hir_typeck::fn_ctxt::inspect_obligations",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"),
::tracing_core::__macro_support::Option::Some(26u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::fn_ctxt::inspect_obligations"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
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!("pending_obligations = {0:#?}",
obligations) as &dyn Value))])
});
} else { ; }
};
obligations.retain(|obligation|
self.predicate_has_self_ty(obligation.predicate,
ty_var_root));
obligations
}
}
}
}#[instrument(skip(self), level = "debug")]
20 pub(crate) fn obligations_for_self_ty(&self, self_ty: ty::TyVid) -> PredicateObligations<'tcx> {
21 if self.next_trait_solver() {
22 self.obligations_for_self_ty_next(self_ty)
23 } else {
24 let ty_var_root = self.root_var(self_ty);
25 let mut obligations = self.fulfillment_cx.borrow().pending_obligations();
26 trace!("pending_obligations = {:#?}", obligations);
27 obligations
28 .retain(|obligation| self.predicate_has_self_ty(obligation.predicate, ty_var_root));
29 obligations
30 }
31 }
32
33 x;#[instrument(level = "debug", skip(self), ret)]
34 fn predicate_has_self_ty(
35 &self,
36 predicate: ty::Predicate<'tcx>,
37 expected_vid: ty::TyVid,
38 ) -> bool {
39 match predicate.kind().skip_binder() {
40 ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
41 self.type_matches_expected_vid(data.self_ty(), expected_vid)
42 }
43 ty::PredicateKind::Clause(ty::ClauseKind::Projection(data)) => {
44 if data.projection_term.kind.is_trait_projection() {
45 self.type_matches_expected_vid(data.self_ty(), expected_vid)
46 } else {
47 false
48 }
49 }
50 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
51 | ty::PredicateKind::Subtype(..)
52 | ty::PredicateKind::Coerce(..)
53 | ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..))
54 | ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..))
55 | ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(..))
56 | ty::PredicateKind::DynCompatible(..)
57 | ty::PredicateKind::NormalizesTo(..)
58 | ty::PredicateKind::AliasRelate(..)
59 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
60 | ty::PredicateKind::ConstEquate(..)
61 | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
62 | ty::PredicateKind::Clause(ty::ClauseKind::UnstableFeature(_))
63 | ty::PredicateKind::Ambiguous => false,
64 }
65 }
66
67 x;#[instrument(level = "debug", skip(self), ret)]
68 fn type_matches_expected_vid(&self, ty: Ty<'tcx>, expected_vid: ty::TyVid) -> bool {
69 let ty = self.shallow_resolve(ty);
70 debug!(?ty);
71
72 match *ty.kind() {
73 ty::Infer(ty::TyVar(found_vid)) => {
74 self.root_var(expected_vid) == self.root_var(found_vid)
75 }
76 _ => false,
77 }
78 }
79
80 pub(crate) fn obligations_for_self_ty_next(
81 &self,
82 self_ty: ty::TyVid,
83 ) -> PredicateObligations<'tcx> {
84 let sub_root_var = self.sub_unification_table_root_var(self_ty);
92 let obligations = self
93 .fulfillment_cx
94 .borrow()
95 .pending_obligations_potentially_referencing_sub_root(&self.infcx, sub_root_var);
96 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs:96",
"rustc_hir_typeck::fn_ctxt::inspect_obligations",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"),
::tracing_core::__macro_support::Option::Some(96u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::fn_ctxt::inspect_obligations"),
::tracing_core::field::FieldSet::new(&["obligations"],
::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(&debug(&obligations)
as &dyn Value))])
});
} else { ; }
};debug!(?obligations);
97 let mut obligations_for_self_ty = PredicateObligations::new();
98 for obligation in obligations {
99 let mut visitor = NestedObligationsForSelfTy {
100 fcx: self,
101 self_ty,
102 obligations_for_self_ty: &mut obligations_for_self_ty,
103 root_cause: &obligation.cause,
104 };
105
106 let goal = obligation.as_goal();
107 self.visit_proof_tree(goal, &mut visitor);
108 }
109
110 obligations_for_self_ty.retain_mut(|obligation| {
111 obligation.predicate = self.resolve_vars_if_possible(obligation.predicate);
112 !obligation.predicate.has_placeholders()
113 });
114 obligations_for_self_ty
115 }
116
117 #[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("from_float_for_f32_root_vids",
"rustc_hir_typeck::fn_ctxt::inspect_obligations",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"),
::tracing_core::__macro_support::Option::Some(118u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::fn_ctxt::inspect_obligations"),
::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: UnordSet<ty::FloatVid> = loop {};
return __tracing_attr_fake_return;
}
{
if self.next_trait_solver() {
self.from_float_for_f32_root_vids_next()
} else {
let Some(from_trait) =
self.tcx.lang_items().from_trait() else {
return UnordSet::new();
};
self.fulfillment_cx.borrow_mut().pending_obligations().into_iter().filter_map(|obligation|
{
self.predicate_from_float_for_f32_root_vid(from_trait,
obligation.predicate)
}).collect()
}
}
}
}#[instrument(skip(self), level = "debug")]
119 pub(crate) fn from_float_for_f32_root_vids(&self) -> UnordSet<ty::FloatVid> {
120 if self.next_trait_solver() {
121 self.from_float_for_f32_root_vids_next()
122 } else {
123 let Some(from_trait) = self.tcx.lang_items().from_trait() else {
124 return UnordSet::new();
125 };
126 self.fulfillment_cx
127 .borrow_mut()
128 .pending_obligations()
129 .into_iter()
130 .filter_map(|obligation| {
131 self.predicate_from_float_for_f32_root_vid(from_trait, obligation.predicate)
132 })
133 .collect()
134 }
135 }
136
137 fn predicate_from_float_for_f32_root_vid(
138 &self,
139 from_trait: DefId,
140 predicate: ty::Predicate<'tcx>,
141 ) -> Option<ty::FloatVid> {
142 match predicate.kind().no_bound_vars() {
146 Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
147 polarity: ty::PredicatePolarity::Positive,
148 trait_ref,
149 }))) if trait_ref.def_id == from_trait
150 && self.shallow_resolve(trait_ref.self_ty()).kind()
151 == &ty::Float(ty::FloatTy::F32) =>
152 {
153 self.root_float_vid(trait_ref.args.type_at(1))
154 }
155 _ => None,
156 }
157 }
158
159 fn from_float_for_f32_root_vids_next(&self) -> UnordSet<ty::FloatVid> {
160 let Some(from_trait) = self.tcx.lang_items().from_trait() else {
161 return UnordSet::new();
162 };
163 let obligations = self.fulfillment_cx.borrow().pending_obligations();
164 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs:164",
"rustc_hir_typeck::fn_ctxt::inspect_obligations",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"),
::tracing_core::__macro_support::Option::Some(164u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::fn_ctxt::inspect_obligations"),
::tracing_core::field::FieldSet::new(&["obligations"],
::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(&debug(&obligations)
as &dyn Value))])
});
} else { ; }
};debug!(?obligations);
165 let mut vids = UnordSet::new();
166 for obligation in obligations {
167 let mut visitor = FindFromFloatForF32RootVids {
168 fcx: self,
169 from_trait,
170 vids: &mut vids,
171 span: obligation.cause.span,
172 };
173
174 let goal = obligation.as_goal();
175 self.visit_proof_tree(goal, &mut visitor);
176 }
177 vids
178 }
179}
180
181struct NestedObligationsForSelfTy<'a, 'tcx> {
182 fcx: &'a FnCtxt<'a, 'tcx>,
183 self_ty: ty::TyVid,
184 root_cause: &'a ObligationCause<'tcx>,
185 obligations_for_self_ty: &'a mut PredicateObligations<'tcx>,
186}
187
188impl<'tcx> ProofTreeVisitor<'tcx> for NestedObligationsForSelfTy<'_, 'tcx> {
189 fn span(&self) -> Span {
190 self.root_cause.span
191 }
192
193 fn config(&self) -> InspectConfig {
194 InspectConfig { max_depth: 5 }
198 }
199
200 fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
201 if inspect_goal.result() == Ok(Certainty::Yes) {
204 return;
205 }
206
207 if !inspect_goal
210 .orig_values()
211 .iter()
212 .filter_map(|arg| arg.as_type())
213 .any(|ty| self.fcx.type_matches_expected_vid(ty, self.self_ty))
214 {
215 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs:215",
"rustc_hir_typeck::fn_ctxt::inspect_obligations",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs"),
::tracing_core::__macro_support::Option::Some(215u32),
::tracing_core::__macro_support::Option::Some("rustc_hir_typeck::fn_ctxt::inspect_obligations"),
::tracing_core::field::FieldSet::new(&["message", "goal"],
::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!("goal does not mention self type")
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&inspect_goal.goal())
as &dyn Value))])
});
} else { ; }
};debug!(goal = ?inspect_goal.goal(), "goal does not mention self type");
216 return;
217 }
218
219 let tcx = self.fcx.tcx;
220 let goal = inspect_goal.goal();
221 if self.fcx.predicate_has_self_ty(goal.predicate, self.self_ty) {
222 self.obligations_for_self_ty.push(traits::Obligation::new(
223 tcx,
224 self.root_cause.clone(),
225 goal.param_env,
226 goal.predicate,
227 ));
228 }
229
230 if let Some(candidate) = inspect_goal.unique_applicable_candidate() {
235 candidate.visit_nested_no_probe(self)
236 }
237 }
238}
239
240struct FindFromFloatForF32RootVids<'a, 'tcx> {
241 fcx: &'a FnCtxt<'a, 'tcx>,
242 from_trait: DefId,
243 vids: &'a mut UnordSet<ty::FloatVid>,
244 span: Span,
245}
246
247impl<'tcx> ProofTreeVisitor<'tcx> for FindFromFloatForF32RootVids<'_, 'tcx> {
248 fn span(&self) -> Span {
249 self.span
250 }
251
252 fn config(&self) -> InspectConfig {
253 InspectConfig { max_depth: 3 }
256 }
257
258 fn visit_goal(&mut self, inspect_goal: &InspectGoal<'_, 'tcx>) {
259 if let Some(vid) = self
260 .fcx
261 .predicate_from_float_for_f32_root_vid(self.from_trait, inspect_goal.goal().predicate)
262 {
263 self.vids.insert(vid);
264 } else if let Some(candidate) = inspect_goal.unique_applicable_candidate() {
265 let start_len = self.vids.len();
266 let _ = candidate.goal().infcx().commit_if_ok(|_| {
267 candidate.visit_nested_no_probe(self);
268 if self.vids.len() > start_len { Ok(()) } else { Err(()) }
269 });
270 }
271 }
272}