1use std::iter;
13
14use canonicalizer::Canonicalizer;
15use rustc_index::IndexVec;
16use rustc_type_ir::inherent::*;
17use rustc_type_ir::relate::{
18 self, Relate, RelateResult, TypeRelation, VarianceDiagInfo, relate_args_invariantly,
19};
20use rustc_type_ir::{
21 self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner, Region,
22 TypeFoldable, TypingMode, TypingModeEqWrapper, eager_resolve_vars,
23};
24use thin_vec::ThinVec;
25use tracing::instrument;
26
27use crate::delegate::SolverDelegate;
28use crate::solve::{
29 CanonicalInput, CanonicalResponse, Certainty, ExternalConstraintsData,
30 ExternalRegionConstraints, Goal, NestedNormalizationGoals, QueryInput, Response,
31 VisibleForLeakCheck, inspect,
32};
33
34pub mod canonicalizer;
35
36trait ResponseT<I: Interner> {
37 fn var_values(&self) -> CanonicalVarValues<I>;
38}
39
40impl<I: Interner> ResponseT<I> for Response<I> {
41 fn var_values(&self) -> CanonicalVarValues<I> {
42 self.var_values
43 }
44}
45
46impl<I: Interner, T> ResponseT<I> for inspect::State<I, T> {
47 fn var_values(&self) -> CanonicalVarValues<I> {
48 self.var_values
49 }
50}
51
52pub(super) fn canonicalize_goal<D, I>(
57 delegate: &D,
58 goal: Goal<I, I::Predicate>,
59 opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)],
60 typing_mode: TypingMode<I>,
61) -> (ThinVec<I::GenericArg>, CanonicalInput<I, I::Predicate>)
62where
63 D: SolverDelegate<Interner = I>,
64 I: Interner,
65{
66 let (orig_values, canonical) = Canonicalizer::canonicalize_input(
67 delegate,
68 QueryInput {
69 goal,
70 predefined_opaques_in_body: delegate.cx().mk_predefined_opaques_in_body(opaque_types),
71 },
72 );
73
74 let query_input =
75 ty::CanonicalQueryInput { canonical, typing_mode: TypingModeEqWrapper(typing_mode) };
76 (orig_values, query_input)
77}
78
79pub(super) fn canonicalize_response<D, I, T>(
80 delegate: &D,
81 max_input_universe: ty::UniverseIndex,
82 value: T,
83) -> ty::Canonical<I, T>
84where
85 D: SolverDelegate<Interner = I>,
86 I: Interner,
87 T: TypeFoldable<I>,
88{
89 Canonicalizer::canonicalize_response(delegate, max_input_universe, value)
90}
91
92pub(super) fn instantiate_and_apply_query_response<D, I>(
101 delegate: &D,
102 param_env: I::ParamEnv,
103 original_values: &[I::GenericArg],
104 response: CanonicalResponse<I>,
105 span: I::Span,
106) -> (NestedNormalizationGoals<I>, Certainty)
107where
108 D: SolverDelegate<Interner = I>,
109 I: Interner,
110{
111 let instantiation =
112 compute_query_response_instantiation_values(delegate, &original_values, &response, span);
113
114 let Response { var_values, external_constraints, certainty } =
115 delegate.instantiate_canonical(response, instantiation);
116
117 unify_query_var_values(delegate, param_env, &original_values, var_values, span);
118
119 let ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals } =
120 &*external_constraints;
121
122 match region_constraints {
123 ExternalRegionConstraints::Old(r) => register_region_constraints(
124 delegate,
125 r.iter().map(|(c, vis)| {
126 (*c, vis.and(VisibleForLeakCheck::No))
133 }),
134 span,
135 ),
136 ExternalRegionConstraints::NextGen(r) => {
137 delegate.register_solver_region_constraint(r.clone())
138 }
139 };
140 register_new_opaque_types(delegate, opaque_types, span);
141
142 (normalization_nested_goals.clone(), certainty)
143}
144
145fn compute_query_response_instantiation_values<D, I, T>(
149 delegate: &D,
150 original_values: &[I::GenericArg],
151 response: &Canonical<I, T>,
152 span: I::Span,
153) -> CanonicalVarValues<I>
154where
155 D: SolverDelegate<Interner = I>,
156 I: Interner,
157 T: ResponseT<I>,
158{
159 let prev_universe = delegate.universe();
163 let universes_created_in_query = response.max_universe.index();
164 for _ in 0..universes_created_in_query {
165 let new_universe = delegate.create_next_universe();
166 if delegate.cx().assumptions_on_binders() {
167 delegate.insert_placeholder_assumptions(
175 new_universe,
176 Some(rustc_type_ir::region_constraint::Assumptions::empty()),
177 );
178 }
179 }
180
181 compute_query_response_instantiation_values_in_universe(
182 delegate,
183 original_values,
184 response,
185 span,
186 prev_universe,
187 )
188}
189
190fn compute_query_response_instantiation_values_in_universe<D, I, T>(
191 delegate: &D,
192 original_values: &[I::GenericArg],
193 response: &Canonical<I, T>,
194 span: I::Span,
195 prev_universe: ty::UniverseIndex,
196) -> CanonicalVarValues<I>
197where
198 D: SolverDelegate<Interner = I>,
199 I: Interner,
200 T: ResponseT<I>,
201{
202 let var_values = response.value.var_values();
203 {
match (&original_values.len(), &var_values.len()) {
(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!(original_values.len(), var_values.len());
204
205 let mut opt_values = IndexVec::from_elem_n(None, response.var_kinds.len());
213 for (original_value, result_value) in iter::zip(original_values, var_values.var_values.iter()) {
214 match result_value.kind() {
215 ty::GenericArgKind::Type(t) => {
216 if let ty::Bound(index_kind, b) = t.kind()
221 && !#[allow(non_exhaustive_omitted_patterns)] match response.var_kinds.get(b.var().as_usize()).unwrap()
{
CanonicalVarKind::Ty { .. } => true,
_ => false,
}matches!(
222 response.var_kinds.get(b.var().as_usize()).unwrap(),
223 CanonicalVarKind::Ty { .. }
224 )
225 {
226 if !#[allow(non_exhaustive_omitted_patterns)] match index_kind {
ty::BoundVarIndexKind::Canonical => true,
_ => false,
} {
::core::panicking::panic("assertion failed: matches!(index_kind, ty::BoundVarIndexKind::Canonical)")
};assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
227 opt_values[b.var()] = Some(*original_value);
228 }
229 }
230 ty::GenericArgKind::Lifetime(r) => {
231 if let ty::ReBound(index_kind, br) = r.kind() {
232 if !#[allow(non_exhaustive_omitted_patterns)] match index_kind {
ty::BoundVarIndexKind::Canonical => true,
_ => false,
} {
::core::panicking::panic("assertion failed: matches!(index_kind, ty::BoundVarIndexKind::Canonical)")
};assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
233 opt_values[br.var()] = Some(*original_value);
234 }
235 }
236 ty::GenericArgKind::Const(c) => {
237 if let ty::ConstKind::Bound(index_kind, bc) = c.kind() {
238 if !#[allow(non_exhaustive_omitted_patterns)] match index_kind {
ty::BoundVarIndexKind::Canonical => true,
_ => false,
} {
::core::panicking::panic("assertion failed: matches!(index_kind, ty::BoundVarIndexKind::Canonical)")
};assert!(matches!(index_kind, ty::BoundVarIndexKind::Canonical));
239 opt_values[bc.var()] = Some(*original_value);
240 }
241 }
242 }
243 }
244 CanonicalVarValues::instantiate(delegate.cx(), response.var_kinds, |var_values, kind| {
245 if kind.universe() != ty::UniverseIndex::ROOT {
246 delegate.instantiate_canonical_var(kind, span, &var_values, |idx| {
250 prev_universe + idx.index()
251 })
252 } else if kind.is_existential() {
253 if let Some(v) = opt_values[ty::BoundVar::from_usize(var_values.len())] {
261 v
262 } else {
263 delegate.instantiate_canonical_var(kind, span, &var_values, |_| prev_universe)
264 }
265 } else {
266 original_values[kind.expect_placeholder_index()]
281 }
282 })
283}
284
285struct ResponseRelating<'infcx, Infcx, I: Interner> {
296 infcx: &'infcx Infcx,
297 span: I::Span,
298}
299
300impl<'infcx, Infcx, I> ResponseRelating<'infcx, Infcx, I>
301where
302 Infcx: InferCtxtLike<Interner = I>,
303 I: Interner,
304{
305 fn new(infcx: &'infcx Infcx, span: I::Span) -> Self {
306 ResponseRelating { infcx, span }
307 }
308}
309
310impl<Infcx, I> TypeRelation<I> for ResponseRelating<'_, Infcx, I>
311where
312 Infcx: InferCtxtLike<Interner = I>,
313 I: Interner,
314{
315 fn cx(&self) -> I {
316 self.infcx.cx()
317 }
318
319 fn relate_ty_args(
320 &mut self,
321 a_ty: I::Ty,
322 _b_ty: I::Ty,
323 _def_id: I::DefId,
324 a_args: I::GenericArgs,
325 b_args: I::GenericArgs,
326 _: impl FnOnce(I::GenericArgs) -> I::Ty,
327 ) -> RelateResult<I, I::Ty> {
328 relate_args_invariantly(self, a_args, b_args)?;
329 Ok(a_ty)
330 }
331
332 fn relate_with_variance<T: Relate<I>>(
333 &mut self,
334 _variance: ty::Variance,
335 _info: VarianceDiagInfo<I>,
336 a: T,
337 b: T,
338 ) -> RelateResult<I, T> {
339 self.relate(a, b)
340 }
341
342 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("tys",
"rustc_next_trait_solver::canonical",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/canonical/mod.rs"),
::tracing_core::__macro_support::Option::Some(342u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::canonical"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("a")
}> =
::tracing::__macro_support::FieldName::new("a");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("b")
}> =
::tracing::__macro_support::FieldName::new("b");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<I, I::Ty> = loop {};
return __tracing_attr_fake_return;
}
{
if a == b { return Ok(a); }
let infcx = self.infcx;
let a = infcx.shallow_resolve(a);
let b = infcx.shallow_resolve(b);
match (a.kind(), b.kind()) {
(ty::Infer(ty::TyVar(a_id)), ty::Infer(ty::TyVar(b_id))) => {
infcx.equate_ty_vids_raw(a_id, b_id);
}
(ty::Infer(ty::TyVar(a_vid)), _) => {
infcx.instantiate_ty_var_raw(a_vid, b);
}
(_, ty::Infer(ty::TyVar(b_vid))) => {
infcx.instantiate_ty_var_raw(b_vid, a);
}
(ty::Error(e), _) | (_, ty::Error(e)) => {
infcx.set_tainted_by_errors(e);
return Ok(Ty::new_error(infcx.cx(), e));
}
(ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) =>
{
infcx.equate_int_vids_raw(a_id, b_id);
}
(ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => {
infcx.instantiate_int_var_raw(v_id,
ty::IntVarValue::IntType(v));
}
(ty::Int(v), ty::Infer(ty::IntVar(v_id))) => {
infcx.instantiate_int_var_raw(v_id,
ty::IntVarValue::IntType(v));
}
(ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => {
infcx.instantiate_int_var_raw(v_id,
ty::IntVarValue::UintType(v));
}
(ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => {
infcx.instantiate_int_var_raw(v_id,
ty::IntVarValue::UintType(v));
}
(ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id)))
=> {
infcx.equate_float_vids_raw(a_id, b_id);
}
(ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => {
infcx.instantiate_float_var_raw(v_id,
ty::FloatVarValue::Known(v));
}
(ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => {
infcx.instantiate_float_var_raw(v_id,
ty::FloatVarValue::Known(v));
}
(_,
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) |
ty::FreshFloatTy(_))) |
(ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) |
ty::FreshFloatTy(_)), _) => {
{
::core::panicking::panic_fmt(format_args!("We do not expect to encounter `Fresh` variables in the new solver"));
}
}
_ => { relate::structurally_relate_tys(self, a, b)?; }
}
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
343 fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty> {
344 if a == b {
345 return Ok(a);
346 }
347
348 let infcx = self.infcx;
349 let a = infcx.shallow_resolve(a);
350 let b = infcx.shallow_resolve(b);
351
352 match (a.kind(), b.kind()) {
353 (ty::Infer(ty::TyVar(a_id)), ty::Infer(ty::TyVar(b_id))) => {
354 infcx.equate_ty_vids_raw(a_id, b_id);
355 }
356
357 (ty::Infer(ty::TyVar(a_vid)), _) => {
358 infcx.instantiate_ty_var_raw(a_vid, b);
359 }
360
361 (_, ty::Infer(ty::TyVar(b_vid))) => {
362 infcx.instantiate_ty_var_raw(b_vid, a);
363 }
364
365 (ty::Error(e), _) | (_, ty::Error(e)) => {
366 infcx.set_tainted_by_errors(e);
367 return Ok(Ty::new_error(infcx.cx(), e));
368 }
369
370 (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => {
377 infcx.equate_int_vids_raw(a_id, b_id);
378 }
379 (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => {
380 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
381 }
382 (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => {
383 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
384 }
385 (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => {
386 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
387 }
388 (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => {
389 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
390 }
391
392 (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => {
394 infcx.equate_float_vids_raw(a_id, b_id);
395 }
396 (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => {
397 infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
398 }
399 (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => {
400 infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
401 }
402
403 (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
404 | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _) => {
405 panic!("We do not expect to encounter `Fresh` variables in the new solver")
406 }
407
408 _ => {
409 relate::structurally_relate_tys(self, a, b)?;
410 }
411 }
412
413 Ok(a)
414 }
415
416 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("regions",
"rustc_next_trait_solver::canonical",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/canonical/mod.rs"),
::tracing_core::__macro_support::Option::Some(416u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::canonical"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("a")
}> =
::tracing::__macro_support::FieldName::new("a");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("b")
}> =
::tracing::__macro_support::FieldName::new("b");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<I, Region<I>> =
loop {};
return __tracing_attr_fake_return;
}
{
self.infcx.equate_regions(a, b, VisibleForLeakCheck::Yes,
self.span);
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
417 fn regions(&mut self, a: Region<I>, b: Region<I>) -> RelateResult<I, Region<I>> {
418 self.infcx.equate_regions(a, b, VisibleForLeakCheck::Yes, self.span);
419
420 Ok(a)
421 }
422
423 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("consts",
"rustc_next_trait_solver::canonical",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/canonical/mod.rs"),
::tracing_core::__macro_support::Option::Some(423u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::canonical"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("a")
}> =
::tracing::__macro_support::FieldName::new("a");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("b")
}> =
::tracing::__macro_support::FieldName::new("b");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&a)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&b)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: RelateResult<I, I::Const> =
loop {};
return __tracing_attr_fake_return;
}
{
if a == b { return Ok(a); }
let infcx = self.infcx;
let a = infcx.shallow_resolve_const(a);
let b = infcx.shallow_resolve_const(b);
match (a.kind(), b.kind()) {
(ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
ty::ConstKind::Infer(ty::InferConst::Var(b_vid))) => {
infcx.equate_const_vids_raw(a_vid, b_vid);
}
(ty::ConstKind::Infer(ty::InferConst::Var(a_vid)), _) => {
infcx.instantiate_const_var_raw(a_vid, b);
}
(_, ty::ConstKind::Infer(ty::InferConst::Var(b_vid))) => {
infcx.instantiate_const_var_raw(b_vid, a);
}
_ => { relate::structurally_relate_consts(self, a, b)?; }
}
Ok(a)
}
}
}#[instrument(skip(self), level = "trace")]
424 fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const> {
425 if a == b {
426 return Ok(a);
427 }
428
429 let infcx = self.infcx;
430 let a = infcx.shallow_resolve_const(a);
433 let b = infcx.shallow_resolve_const(b);
434 match (a.kind(), b.kind()) {
435 (
436 ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
437 ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
438 ) => {
439 infcx.equate_const_vids_raw(a_vid, b_vid);
440 }
441
442 (ty::ConstKind::Infer(ty::InferConst::Var(a_vid)), _) => {
443 infcx.instantiate_const_var_raw(a_vid, b);
444 }
445
446 (_, ty::ConstKind::Infer(ty::InferConst::Var(b_vid))) => {
447 infcx.instantiate_const_var_raw(b_vid, a);
448 }
449
450 _ => {
451 relate::structurally_relate_consts(self, a, b)?;
452 }
453 }
454
455 Ok(a)
456 }
457
458 fn binders<T>(
459 &mut self,
460 a: ty::Binder<I, T>,
461 b: ty::Binder<I, T>,
462 ) -> RelateResult<I, ty::Binder<I, T>>
463 where
464 T: Relate<I>,
465 {
466 if a == b {
467 return Ok(a);
468 }
469
470 if true {
{
match (&a.bound_vars(), &b.bound_vars()) {
(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);
}
}
}
};
};debug_assert_eq!(a.bound_vars(), b.bound_vars());
471 self.relate(a.skip_binder(), b.skip_binder())?;
472
473 Ok(a)
474 }
475}
476
477#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::TRACE <=
::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("unify_query_var_values",
"rustc_next_trait_solver::canonical",
::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_next_trait_solver/src/canonical/mod.rs"),
::tracing_core::__macro_support::Option::Some(489u32),
::tracing_core::__macro_support::Option::Some("rustc_next_trait_solver::canonical"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("param_env")
}> =
::tracing::__macro_support::FieldName::new("param_env");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("original_values")
}> =
::tracing::__macro_support::FieldName::new("original_values");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("var_values")
}> =
::tracing::__macro_support::FieldName::new("var_values");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("span")
}> =
::tracing::__macro_support::FieldName::new("span");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::TRACE <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::TRACE <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(¶m_env)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&original_values)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&var_values)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&span)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: () = loop {};
return __tracing_attr_fake_return;
}
{
{
match (&original_values.len(), &var_values.len()) {
(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);
}
}
}
};
for (&orig, response) in
iter::zip(original_values, var_values.var_values.iter()) {
let mut must_eq = ResponseRelating::new(&**delegate, span);
must_eq.relate(orig, response).unwrap();
}
}
}
}#[instrument(level = "trace", skip(delegate))]
490fn unify_query_var_values<D, I>(
491 delegate: &D,
492 param_env: I::ParamEnv,
493 original_values: &[I::GenericArg],
494 var_values: CanonicalVarValues<I>,
495 span: I::Span,
496) where
497 D: SolverDelegate<Interner = I>,
498 I: Interner,
499{
500 assert_eq!(original_values.len(), var_values.len());
501
502 for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
503 let mut must_eq = ResponseRelating::new(&**delegate, span);
504 must_eq.relate(orig, response).unwrap();
505 }
506}
507
508fn register_region_constraints<D, I>(
509 delegate: &D,
510 constraints: impl IntoIterator<Item = (ty::RegionConstraint<I>, VisibleForLeakCheck)>,
511 span: I::Span,
512) where
513 D: SolverDelegate<Interner = I>,
514 I: Interner,
515{
516 for (constraint, vis) in constraints {
517 match constraint {
518 ty::RegionConstraint::Outlives(ty::OutlivesClause(lhs, rhs)) => match lhs.kind() {
519 ty::GenericArgKind::Lifetime(lhs) => delegate.sub_regions(rhs, lhs, vis, span),
520 ty::GenericArgKind::Type(lhs) => delegate.register_ty_outlives(lhs, rhs, span),
521 ty::GenericArgKind::Const(_) => {
::core::panicking::panic_fmt(format_args!("const outlives: {0:?}: {1:?}",
lhs, rhs));
}panic!("const outlives: {lhs:?}: {rhs:?}"),
522 },
523 ty::RegionConstraint::Eq(ty::RegionEqPredicate(lhs, rhs)) => {
524 delegate.equate_regions(lhs, rhs, vis, span)
525 }
526 }
527 }
528}
529
530fn register_new_opaque_types<D, I>(
531 delegate: &D,
532 opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)],
533 span: I::Span,
534) where
535 D: SolverDelegate<Interner = I>,
536 I: Interner,
537{
538 for &(key, ty) in opaque_types {
539 let prev = delegate.register_hidden_type_in_storage(key, ty, span);
540 if let Some(prev) = prev {
548 delegate.add_duplicate_opaque_type(key, prev, span);
549 }
550 }
551}
552
553pub fn make_canonical_state<D, I, T>(
558 delegate: &D,
559 var_values: &[I::GenericArg],
560 max_input_universe: ty::UniverseIndex,
561 data: T,
562) -> inspect::CanonicalState<I, T>
563where
564 D: SolverDelegate<Interner = I>,
565 I: Interner,
566 T: TypeFoldable<I>,
567{
568 let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) };
569 let state = inspect::State { var_values, data };
570 let state = eager_resolve_vars(&**delegate, state);
571 Canonicalizer::canonicalize_response(delegate, max_input_universe, state)
572}
573
574pub fn instantiate_canonical_state<D, I, T>(
577 delegate: &D,
578 span: I::Span,
579 param_env: I::ParamEnv,
580 prev_universe: ty::UniverseIndex,
581 orig_values: &mut ThinVec<I::GenericArg>,
582 state: inspect::CanonicalState<I, T>,
583) -> T
584where
585 D: SolverDelegate<Interner = I>,
586 I: Interner,
587 T: TypeFoldable<I>,
588{
589 let max_universe = prev_universe + state.max_universe.index();
592 while delegate.universe() < max_universe {
593 delegate.create_next_universe();
594 }
595 orig_values.extend(
596 state.value.var_values.var_values.as_slice()[orig_values.len()..]
597 .iter()
598 .map(|&arg| delegate.fresh_var_for_kind(arg, span, max_universe)),
599 );
600
601 let instantiation = compute_query_response_instantiation_values_in_universe(
602 delegate,
603 orig_values,
604 &state,
605 span,
606 prev_universe,
607 );
608
609 let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation);
610
611 unify_query_var_values(delegate, param_env, orig_values, var_values, span);
612 data
613}
614
615pub fn response_no_constraints_raw<I: Interner>(
616 cx: I,
617 max_universe: ty::UniverseIndex,
618 var_kinds: I::CanonicalVarKinds,
619 certainty: Certainty,
620) -> CanonicalResponse<I> {
621 ty::Canonical {
622 max_universe,
623 var_kinds,
624 value: Response {
625 var_values: ty::CanonicalVarValues::make_identity(cx, var_kinds),
626 external_constraints: cx.mk_external_constraints(ExternalConstraintsData::new(cx)),
629 certainty,
630 },
631 }
632}