diff options
| author | lcnr <rust@lcnr.de> | 2025-08-27 09:42:09 +0200 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2025-09-08 14:17:56 +0200 |
| commit | f51458640840cb94c32f1e55431b1c855ca22e88 (patch) | |
| tree | 96f0a77ec3555f183d2f49eb4689a9751d1332bc /compiler/rustc_infer | |
| parent | 28a0e77d1318210540fa1a561b9a8af08e2ffe40 (diff) | |
| download | rust-f51458640840cb94c32f1e55431b1c855ca22e88.tar.gz rust-f51458640840cb94c32f1e55431b1c855ca22e88.zip | |
optimize `CanonicalVarValues::instantiate`
Diffstat (limited to 'compiler/rustc_infer')
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/mod.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_infer/src/infer/canonical/query_response.rs | 24 |
2 files changed, 18 insertions, 37 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 4e1ea52af4c..517331c3245 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -24,7 +24,7 @@ pub use instantiate::CanonicalExt; use rustc_index::IndexVec; pub use rustc_middle::infer::canonical::*; -use rustc_middle::ty::{self, GenericArg, List, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use crate::infer::{InferCtxt, RegionVariableOrigin}; @@ -67,29 +67,12 @@ impl<'tcx> InferCtxt<'tcx> { .chain((1..=canonical.max_universe.as_u32()).map(|_| self.create_next_universe())) .collect(); - let canonical_inference_vars = - self.instantiate_canonical_vars(span, canonical.variables, |ui| universes[ui]); - let result = canonical.instantiate(self.tcx, &canonical_inference_vars); - (result, canonical_inference_vars) - } - - /// Given the "infos" about the canonical variables from some - /// canonical, creates fresh variables with the same - /// characteristics (see `instantiate_canonical_var` for - /// details). You can then use `instantiate` to instantiate the - /// canonical variable with these inference variables. - fn instantiate_canonical_vars( - &self, - span: Span, - variables: &List<CanonicalVarKind<'tcx>>, - universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, - ) -> CanonicalVarValues<'tcx> { - let mut var_values = Vec::with_capacity(variables.len()); - for info in variables.iter() { - let value = self.instantiate_canonical_var(span, info, &var_values, &universe_map); - var_values.push(value); - } - CanonicalVarValues { var_values: self.tcx.mk_args(&var_values) } + let var_values = + CanonicalVarValues::instantiate(self.tcx, &canonical.variables, |var_values, info| { + self.instantiate_canonical_var(span, info, &var_values, |ui| universes[ui]) + }); + let result = canonical.instantiate(self.tcx, &var_values); + (result, var_values) } /// Given the "info" about a canonical variable, creates a fresh diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 22c9c4edccc..5d1b4be9e57 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -453,16 +453,17 @@ impl<'tcx> InferCtxt<'tcx> { // Create result arguments: if we found a value for a // given variable in the loop above, use that. Otherwise, use // a fresh inference variable. - let mut var_values = Vec::with_capacity(query_response.variables.len()); - for (index, kind) in query_response.variables.iter().enumerate() { - let value = if kind.universe() != ty::UniverseIndex::ROOT { + let tcx = self.tcx; + let variables = query_response.variables; + let var_values = CanonicalVarValues::instantiate(tcx, variables, |var_values, kind| { + if kind.universe() != ty::UniverseIndex::ROOT { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all, we have to deal with them for now. self.instantiate_canonical_var(cause.span, kind, &var_values, |u| { universe_map[u.as_usize()] }) } else if kind.is_existential() { - match opt_values[BoundVar::new(index)] { + match opt_values[BoundVar::new(var_values.len())] { Some(k) => k, None => self.instantiate_canonical_var(cause.span, kind, &var_values, |u| { universe_map[u.as_usize()] @@ -471,20 +472,17 @@ impl<'tcx> InferCtxt<'tcx> { } else { // For placeholders which were already part of the input, we simply map this // universal bound variable back the placeholder of the input. - opt_values[BoundVar::new(index)] + opt_values[BoundVar::new(var_values.len())] .expect("expected placeholder to be unified with itself during response") - }; - var_values.push(value); - } - - let result_args = CanonicalVarValues { var_values: self.tcx.mk_args(&var_values) }; + } + }); let mut obligations = PredicateObligations::new(); // Carry all newly resolved opaque types to the caller's scope for &(a, b) in &query_response.value.opaque_types { - let a = instantiate_value(self.tcx, &result_args, a); - let b = instantiate_value(self.tcx, &result_args, b); + let a = instantiate_value(self.tcx, &var_values, a); + let b = instantiate_value(self.tcx, &var_values, b); debug!(?a, ?b, "constrain opaque type"); // We use equate here instead of, for example, just registering the // opaque type's hidden value directly, because the hidden type may have been an inference @@ -501,7 +499,7 @@ impl<'tcx> InferCtxt<'tcx> { ); } - Ok(InferOk { value: result_args, obligations }) + Ok(InferOk { value: var_values, obligations }) } /// Given a "guess" at the values for the canonical variables in |
