rustc_trait_selection/traits/query/type_op/
custom.rs1use std::fmt;
2
3use rustc_errors::ErrorGuaranteed;
4use rustc_hir::def_id::LocalDefId;
5use rustc_infer::infer::region_constraints::RegionConstraintData;
6use rustc_middle::traits::query::NoSolution;
7use rustc_middle::ty::{TyCtxt, TypeFoldable};
8use rustc_span::Span;
9use tracing::info;
10
11use crate::infer::InferCtxt;
12use crate::infer::canonical::query_response;
13use crate::traits::ObligationCtxt;
14use crate::traits::query::type_op::TypeOpOutput;
15
16pub struct CustomTypeOp<F> {
17 closure: F,
18 description: &'static str,
19}
20
21impl<F> CustomTypeOp<F> {
22 pub fn new<'tcx, R>(closure: F, description: &'static str) -> Self
23 where
24 F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
25 {
26 CustomTypeOp { closure, description }
27 }
28}
29
30impl<'tcx, F, R> super::TypeOp<'tcx> for CustomTypeOp<F>
31where
32 F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
33 R: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
34{
35 type Output = R;
36 type ErrorInfo = !;
39
40 fn fully_perform(
44 self,
45 infcx: &InferCtxt<'tcx>,
46 root_def_id: LocalDefId,
47 span: Span,
48 ) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
49 if truecfg!(debug_assertions) {
50 {
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/query/type_op/custom.rs:50",
"rustc_trait_selection::traits::query::type_op::custom",
::tracing::Level::INFO,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs"),
::tracing_core::__macro_support::Option::Some(50u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::custom"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::INFO <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::INFO <=
::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!("fully_perform({0:?})",
self) as &dyn Value))])
});
} else { ; }
};info!("fully_perform({:?})", self);
51 }
52
53 Ok(scrape_region_constraints(infcx, root_def_id, self.description, span, self.closure)?.0)
54 }
55}
56
57impl<F> fmt::Debug for CustomTypeOp<F> {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 self.description.fmt(f)
60 }
61}
62
63pub fn scrape_region_constraints<'tcx, Op, R>(
66 infcx: &InferCtxt<'tcx>,
67 root_def_id: LocalDefId,
68 name: &'static str,
69 span: Span,
70 op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
71) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed>
72where
73 R: TypeFoldable<TyCtxt<'tcx>>,
74 Op: super::TypeOp<'tcx, Output = R>,
75{
76 let pre_obligations = infcx.take_registered_region_obligations();
82 if !pre_obligations.is_empty() {
{
::core::panicking::panic_fmt(format_args!("scrape_region_constraints: incoming region obligations = {0:#?}",
pre_obligations));
}
};assert!(
83 pre_obligations.is_empty(),
84 "scrape_region_constraints: incoming region obligations = {pre_obligations:#?}",
85 );
86 let pre_assumptions = infcx.take_registered_region_assumptions();
87 if !pre_assumptions.is_empty() {
{
::core::panicking::panic_fmt(format_args!("scrape_region_constraints: incoming region assumptions = {0:#?}",
pre_assumptions));
}
};assert!(
88 pre_assumptions.is_empty(),
89 "scrape_region_constraints: incoming region assumptions = {pre_assumptions:#?}",
90 );
91
92 let value = infcx.commit_if_ok(|_| {
93 let ocx = ObligationCtxt::new(infcx);
94 let value = op(&ocx).map_err(|_| {
95 infcx.tcx.check_potentially_region_dependent_goals(root_def_id).err().unwrap_or_else(
96 || {
124 infcx
125 .dcx()
126 .span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("error performing operation: {0}",
name))
})format!("error performing operation: {name}"))
127 },
128 )
129 })?;
130 let errors = ocx.evaluate_obligations_error_on_ambiguity();
131 if errors.is_empty() {
132 Ok(value)
133 } else if let Err(guar) = infcx.tcx.check_potentially_region_dependent_goals(root_def_id) {
134 Err(guar)
135 } else {
136 Err(infcx.dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("errors selecting obligation during MIR typeck: {0} {1:?} {2:?}",
name, root_def_id, errors))
})format!(
137 "errors selecting obligation during MIR typeck: {name} {root_def_id:?} {errors:?}"
138 )))
139 }
140 })?;
141
142 let value = infcx.resolve_vars_if_possible(value);
144
145 let region_obligations = infcx.take_registered_region_obligations();
146 let region_assumptions = infcx.take_registered_region_assumptions();
147 let region_constraint_data = infcx.take_and_reset_region_constraints();
148 let region_constraints = query_response::make_query_region_constraints(
149 region_obligations,
150 ®ion_constraint_data,
151 region_assumptions,
152 );
153
154 if region_constraints.is_empty() {
155 Ok((
156 TypeOpOutput { output: value, constraints: None, error_info: None },
157 region_constraint_data,
158 ))
159 } else {
160 Ok((
161 TypeOpOutput {
162 output: value,
163 constraints: Some(infcx.tcx.arena.alloc(region_constraints)),
164 error_info: None,
165 },
166 region_constraint_data,
167 ))
168 }
169}