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 delegate.create_next_universe();
166 }
167
168 let var_values = response.value.var_values();
169 {
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());
170
171 let mut opt_values = IndexVec::from_elem_n(None, response.var_kinds.len());
179 for (original_value, result_value) in iter::zip(original_values, var_values.var_values.iter()) {
180 match result_value.kind() {
181 ty::GenericArgKind::Type(t) => {
182 if let ty::Bound(index_kind, b) = t.kind()
187 && !#[allow(non_exhaustive_omitted_patterns)] match response.var_kinds.get(b.var().as_usize()).unwrap()
{
CanonicalVarKind::Ty { .. } => true,
_ => false,
}matches!(
188 response.var_kinds.get(b.var().as_usize()).unwrap(),
189 CanonicalVarKind::Ty { .. }
190 )
191 {
192 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));
193 opt_values[b.var()] = Some(*original_value);
194 }
195 }
196 ty::GenericArgKind::Lifetime(r) => {
197 if let ty::ReBound(index_kind, br) = r.kind() {
198 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));
199 opt_values[br.var()] = Some(*original_value);
200 }
201 }
202 ty::GenericArgKind::Const(c) => {
203 if let ty::ConstKind::Bound(index_kind, bc) = c.kind() {
204 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));
205 opt_values[bc.var()] = Some(*original_value);
206 }
207 }
208 }
209 }
210 CanonicalVarValues::instantiate(delegate.cx(), response.var_kinds, |var_values, kind| {
211 if kind.universe() != ty::UniverseIndex::ROOT {
212 delegate.instantiate_canonical_var(kind, span, &var_values, |idx| {
216 prev_universe + idx.index()
217 })
218 } else if kind.is_existential() {
219 if let Some(v) = opt_values[ty::BoundVar::from_usize(var_values.len())] {
227 v
228 } else {
229 delegate.instantiate_canonical_var(kind, span, &var_values, |_| prev_universe)
230 }
231 } else {
232 original_values[kind.expect_placeholder_index()]
247 }
248 })
249}
250
251struct ResponseRelating<'infcx, Infcx, I: Interner> {
262 infcx: &'infcx Infcx,
263 span: I::Span,
264}
265
266impl<'infcx, Infcx, I> ResponseRelating<'infcx, Infcx, I>
267where
268 Infcx: InferCtxtLike<Interner = I>,
269 I: Interner,
270{
271 fn new(infcx: &'infcx Infcx, span: I::Span) -> Self {
272 ResponseRelating { infcx, span }
273 }
274}
275
276impl<Infcx, I> TypeRelation<I> for ResponseRelating<'_, Infcx, I>
277where
278 Infcx: InferCtxtLike<Interner = I>,
279 I: Interner,
280{
281 fn cx(&self) -> I {
282 self.infcx.cx()
283 }
284
285 fn relate_ty_args(
286 &mut self,
287 a_ty: I::Ty,
288 _b_ty: I::Ty,
289 _def_id: I::DefId,
290 a_args: I::GenericArgs,
291 b_args: I::GenericArgs,
292 _: impl FnOnce(I::GenericArgs) -> I::Ty,
293 ) -> RelateResult<I, I::Ty> {
294 relate_args_invariantly(self, a_args, b_args)?;
295 Ok(a_ty)
296 }
297 fn relate_with_variance<T: Relate<I>>(
298 &mut self,
299 _variance: ty::Variance,
300 _info: VarianceDiagInfo<I>,
301 a: T,
302 b: T,
303 ) -> RelateResult<I, T> {
304 self.relate(a, b)
305 }
306
307 #[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(307u32),
::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")]
308 fn tys(&mut self, a: I::Ty, b: I::Ty) -> RelateResult<I, I::Ty> {
309 if a == b {
310 return Ok(a);
311 }
312
313 let infcx = self.infcx;
314 let a = infcx.shallow_resolve(a);
315 let b = infcx.shallow_resolve(b);
316
317 match (a.kind(), b.kind()) {
318 (ty::Infer(ty::TyVar(a_id)), ty::Infer(ty::TyVar(b_id))) => {
319 infcx.equate_ty_vids_raw(a_id, b_id);
320 }
321
322 (ty::Infer(ty::TyVar(a_vid)), _) => {
323 infcx.instantiate_ty_var_raw(a_vid, b);
324 }
325
326 (_, ty::Infer(ty::TyVar(b_vid))) => {
327 infcx.instantiate_ty_var_raw(b_vid, a);
328 }
329
330 (ty::Error(e), _) | (_, ty::Error(e)) => {
331 infcx.set_tainted_by_errors(e);
332 return Ok(Ty::new_error(infcx.cx(), e));
333 }
334
335 (ty::Infer(ty::IntVar(a_id)), ty::Infer(ty::IntVar(b_id))) => {
342 infcx.equate_int_vids_raw(a_id, b_id);
343 }
344 (ty::Infer(ty::IntVar(v_id)), ty::Int(v)) => {
345 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
346 }
347 (ty::Int(v), ty::Infer(ty::IntVar(v_id))) => {
348 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::IntType(v));
349 }
350 (ty::Infer(ty::IntVar(v_id)), ty::Uint(v)) => {
351 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
352 }
353 (ty::Uint(v), ty::Infer(ty::IntVar(v_id))) => {
354 infcx.instantiate_int_var_raw(v_id, ty::IntVarValue::UintType(v));
355 }
356
357 (ty::Infer(ty::FloatVar(a_id)), ty::Infer(ty::FloatVar(b_id))) => {
359 infcx.equate_float_vids_raw(a_id, b_id);
360 }
361 (ty::Infer(ty::FloatVar(v_id)), ty::Float(v)) => {
362 infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
363 }
364 (ty::Float(v), ty::Infer(ty::FloatVar(v_id))) => {
365 infcx.instantiate_float_var_raw(v_id, ty::FloatVarValue::Known(v));
366 }
367
368 (_, ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)))
369 | (ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)), _) => {
370 panic!("We do not expect to encounter `Fresh` variables in the new solver")
371 }
372
373 _ => {
374 relate::structurally_relate_tys(self, a, b)?;
375 }
376 }
377
378 Ok(a)
379 }
380
381 #[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(381u32),
::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")]
382 fn regions(&mut self, a: Region<I>, b: Region<I>) -> RelateResult<I, Region<I>> {
383 self.infcx.equate_regions(a, b, VisibleForLeakCheck::Yes, self.span);
384
385 Ok(a)
386 }
387
388 #[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(388u32),
::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")]
389 fn consts(&mut self, a: I::Const, b: I::Const) -> RelateResult<I, I::Const> {
390 if a == b {
391 return Ok(a);
392 }
393
394 let infcx = self.infcx;
395 let a = infcx.shallow_resolve_const(a);
398 let b = infcx.shallow_resolve_const(b);
399 match (a.kind(), b.kind()) {
400 (
401 ty::ConstKind::Infer(ty::InferConst::Var(a_vid)),
402 ty::ConstKind::Infer(ty::InferConst::Var(b_vid)),
403 ) => {
404 infcx.equate_const_vids_raw(a_vid, b_vid);
405 }
406
407 (ty::ConstKind::Infer(ty::InferConst::Var(a_vid)), _) => {
408 infcx.instantiate_const_var_raw(a_vid, b);
409 }
410
411 (_, ty::ConstKind::Infer(ty::InferConst::Var(b_vid))) => {
412 infcx.instantiate_const_var_raw(b_vid, a);
413 }
414
415 _ => {
416 relate::structurally_relate_consts(self, a, b)?;
417 }
418 }
419
420 Ok(a)
421 }
422
423 fn binders<T>(
424 &mut self,
425 a: ty::Binder<I, T>,
426 b: ty::Binder<I, T>,
427 ) -> RelateResult<I, ty::Binder<I, T>>
428 where
429 T: Relate<I>,
430 {
431 if a == b {
432 return Ok(a);
433 }
434
435 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());
436 self.relate(a.skip_binder(), b.skip_binder())?;
437
438 Ok(a)
439 }
440}
441
442#[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(454u32),
::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))]
455fn unify_query_var_values<D, I>(
456 delegate: &D,
457 param_env: I::ParamEnv,
458 original_values: &[I::GenericArg],
459 var_values: CanonicalVarValues<I>,
460 span: I::Span,
461) where
462 D: SolverDelegate<Interner = I>,
463 I: Interner,
464{
465 assert_eq!(original_values.len(), var_values.len());
466
467 for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
468 let mut must_eq = ResponseRelating::new(&**delegate, span);
469 must_eq.relate(orig, response).unwrap();
470 }
471}
472
473fn register_region_constraints<D, I>(
474 delegate: &D,
475 constraints: impl IntoIterator<Item = (ty::RegionConstraint<I>, VisibleForLeakCheck)>,
476 span: I::Span,
477) where
478 D: SolverDelegate<Interner = I>,
479 I: Interner,
480{
481 for (constraint, vis) in constraints {
482 match constraint {
483 ty::RegionConstraint::Outlives(ty::OutlivesPredicate(lhs, rhs)) => match lhs.kind() {
484 ty::GenericArgKind::Lifetime(lhs) => delegate.sub_regions(rhs, lhs, vis, span),
485 ty::GenericArgKind::Type(lhs) => delegate.register_ty_outlives(lhs, rhs, span),
486 ty::GenericArgKind::Const(_) => {
::core::panicking::panic_fmt(format_args!("const outlives: {0:?}: {1:?}",
lhs, rhs));
}panic!("const outlives: {lhs:?}: {rhs:?}"),
487 },
488 ty::RegionConstraint::Eq(ty::RegionEqPredicate(lhs, rhs)) => {
489 delegate.equate_regions(lhs, rhs, vis, span)
490 }
491 }
492 }
493}
494
495fn register_new_opaque_types<D, I>(
496 delegate: &D,
497 opaque_types: &[(ty::OpaqueTypeKey<I>, I::Ty)],
498 span: I::Span,
499) where
500 D: SolverDelegate<Interner = I>,
501 I: Interner,
502{
503 for &(key, ty) in opaque_types {
504 let prev = delegate.register_hidden_type_in_storage(key, ty, span);
505 if let Some(prev) = prev {
513 delegate.add_duplicate_opaque_type(key, prev, span);
514 }
515 }
516}
517
518pub fn make_canonical_state<D, I, T>(
523 delegate: &D,
524 var_values: &[I::GenericArg],
525 max_input_universe: ty::UniverseIndex,
526 data: T,
527) -> inspect::CanonicalState<I, T>
528where
529 D: SolverDelegate<Interner = I>,
530 I: Interner,
531 T: TypeFoldable<I>,
532{
533 let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) };
534 let state = inspect::State { var_values, data };
535 let state = eager_resolve_vars(&**delegate, state);
536 Canonicalizer::canonicalize_response(delegate, max_input_universe, state)
537}
538
539pub fn instantiate_canonical_state<D, I, T>(
542 delegate: &D,
543 span: I::Span,
544 param_env: I::ParamEnv,
545 orig_values: &mut ThinVec<I::GenericArg>,
546 state: inspect::CanonicalState<I, T>,
547) -> T
548where
549 D: SolverDelegate<Interner = I>,
550 I: Interner,
551 T: TypeFoldable<I>,
552{
553 orig_values.extend(
556 state.value.var_values.var_values.as_slice()[orig_values.len()..]
557 .iter()
558 .map(|&arg| delegate.fresh_var_for_kind_with_span(arg, span)),
559 );
560
561 let instantiation =
562 compute_query_response_instantiation_values(delegate, orig_values, &state, span);
563
564 let inspect::State { var_values, data } = delegate.instantiate_canonical(state, instantiation);
565
566 unify_query_var_values(delegate, param_env, orig_values, var_values, span);
567 data
568}
569
570pub fn response_no_constraints_raw<I: Interner>(
571 cx: I,
572 max_universe: ty::UniverseIndex,
573 var_kinds: I::CanonicalVarKinds,
574 certainty: Certainty,
575) -> CanonicalResponse<I> {
576 ty::Canonical {
577 max_universe,
578 var_kinds,
579 value: Response {
580 var_values: ty::CanonicalVarValues::make_identity(cx, var_kinds),
581 external_constraints: cx.mk_external_constraints(ExternalConstraintsData::new(cx)),
584 certainty,
585 },
586 }
587}