Skip to content

Commit 6ace43c

Browse files
committed
hide SmallCanonicalVarValues in OriginalQueryValues struct
1 parent da76b4d commit 6ace43c

File tree

9 files changed

+66
-46
lines changed

9 files changed

+66
-46
lines changed

src/librustc/infer/canonical/canonicalizer.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
1818
use infer::canonical::{
1919
Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
20-
SmallCanonicalVarValues,
20+
OriginalQueryValues,
2121
};
2222
use infer::InferCtxt;
2323
use std::sync::atomic::Ordering;
@@ -48,7 +48,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
4848
pub fn canonicalize_query<V>(
4949
&self,
5050
value: &V,
51-
var_values: &mut SmallCanonicalVarValues<'tcx>,
51+
query_state: &mut OriginalQueryValues<'tcx>,
5252
) -> Canonicalized<'gcx, V>
5353
where
5454
V: TypeFoldable<'tcx> + Lift<'gcx>,
@@ -64,7 +64,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
6464
Some(self),
6565
self.tcx,
6666
&CanonicalizeAllFreeRegions,
67-
var_values,
67+
query_state,
6868
)
6969
}
7070

@@ -97,13 +97,13 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
9797
where
9898
V: TypeFoldable<'tcx> + Lift<'gcx>,
9999
{
100-
let mut var_values = SmallVec::new();
100+
let mut query_state = OriginalQueryValues::default();
101101
Canonicalizer::canonicalize(
102102
value,
103103
Some(self),
104104
self.tcx,
105105
&CanonicalizeQueryResponse,
106-
&mut var_values,
106+
&mut query_state,
107107
)
108108
}
109109

@@ -119,7 +119,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
119119
pub fn canonicalize_hr_query_hack<V>(
120120
&self,
121121
value: &V,
122-
var_values: &mut SmallCanonicalVarValues<'tcx>,
122+
query_state: &mut OriginalQueryValues<'tcx>,
123123
) -> Canonicalized<'gcx, V>
124124
where
125125
V: TypeFoldable<'tcx> + Lift<'gcx>,
@@ -135,7 +135,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
135135
Some(self),
136136
self.tcx,
137137
&CanonicalizeFreeRegionsOtherThanStatic,
138-
var_values,
138+
query_state,
139139
)
140140
}
141141
}
@@ -222,7 +222,7 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
222222
infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
223223
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
224224
variables: SmallVec<[CanonicalVarInfo; 8]>,
225-
var_values: &'cx mut SmallCanonicalVarValues<'tcx>,
225+
query_state: &'cx mut OriginalQueryValues<'tcx>,
226226
// Note that indices is only used once `var_values` is big enough to be
227227
// heap-allocated.
228228
indices: FxHashMap<Kind<'tcx>, CanonicalVar>,
@@ -330,7 +330,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
330330
infcx: Option<&InferCtxt<'_, 'gcx, 'tcx>>,
331331
tcx: TyCtxt<'_, 'gcx, 'tcx>,
332332
canonicalize_region_mode: &dyn CanonicalizeRegionMode,
333-
var_values: &mut SmallCanonicalVarValues<'tcx>,
333+
query_state: &mut OriginalQueryValues<'tcx>,
334334
) -> Canonicalized<'gcx, V>
335335
where
336336
V: TypeFoldable<'tcx> + Lift<'gcx>,
@@ -365,7 +365,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
365365
canonicalize_region_mode,
366366
needs_canonical_flags,
367367
variables: SmallVec::new(),
368-
var_values,
368+
query_state,
369369
indices: FxHashMap::default(),
370370
};
371371
let out_value = value.fold_with(&mut canonicalizer);
@@ -396,11 +396,13 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
396396
fn canonical_var(&mut self, info: CanonicalVarInfo, kind: Kind<'tcx>) -> CanonicalVar {
397397
let Canonicalizer {
398398
variables,
399-
var_values,
399+
query_state,
400400
indices,
401401
..
402402
} = self;
403403

404+
let var_values = &mut query_state.var_values;
405+
404406
// This code is hot. `variables` and `var_values` are usually small
405407
// (fewer than 8 elements ~95% of the time). They are SmallVec's to
406408
// avoid allocations in those cases. We also don't use `indices` to

src/librustc/infer/canonical/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,16 @@ pub struct CanonicalVarValues<'tcx> {
7575
pub var_values: IndexVec<CanonicalVar, Kind<'tcx>>,
7676
}
7777

78-
/// Like CanonicalVarValues, but for use in places where a SmallVec is
79-
/// appropriate.
80-
pub type SmallCanonicalVarValues<'tcx> = SmallVec<[Kind<'tcx>; 8]>;
78+
/// When we canonicalize a value to form a query, we wind up replacing
79+
/// various parts of it with canonical variables. This struct stores
80+
/// those replaced bits to remember for when we process the query
81+
/// result.
82+
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable)]
83+
pub struct OriginalQueryValues<'tcx> {
84+
/// This is equivalent to `CanonicalVarValues`, but using a
85+
/// `SmallVec` yields a significant performance win.
86+
pub var_values: SmallVec<[Kind<'tcx>; 8]>,
87+
}
8188

8289
/// Information about a canonical variable that is included with the
8390
/// canonical value. This is sufficient information for code to create

src/librustc/infer/canonical/query_response.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use infer::canonical::substitute::substitute_value;
2121
use infer::canonical::{
2222
Canonical, CanonicalVarKind, CanonicalVarValues, CanonicalizedQueryResponse, Certainty,
23-
QueryRegionConstraint, QueryResponse, SmallCanonicalVarValues,
23+
OriginalQueryValues, QueryRegionConstraint, QueryResponse,
2424
};
2525
use infer::region_constraints::{Constraint, RegionConstraintData};
2626
use infer::InferCtxtBuilder;
@@ -64,11 +64,15 @@ impl<'cx, 'gcx, 'tcx> InferCtxtBuilder<'cx, 'gcx, 'tcx> {
6464
K: TypeFoldable<'tcx>,
6565
R: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
6666
{
67-
self.enter_with_canonical(DUMMY_SP, canonical_key, |ref infcx, key, canonical_inference_vars| {
68-
let fulfill_cx = &mut FulfillmentContext::new();
69-
let value = operation(infcx, fulfill_cx, key)?;
70-
infcx.make_canonicalized_query_response(canonical_inference_vars, value, fulfill_cx)
71-
})
67+
self.enter_with_canonical(
68+
DUMMY_SP,
69+
canonical_key,
70+
|ref infcx, key, canonical_inference_vars| {
71+
let fulfill_cx = &mut FulfillmentContext::new();
72+
let value = operation(infcx, fulfill_cx, key)?;
73+
infcx.make_canonicalized_query_response(canonical_inference_vars, value, fulfill_cx)
74+
},
75+
)
7276
}
7377
}
7478

@@ -153,7 +157,8 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
153157
region_obligations
154158
.iter()
155159
.map(|(_, r_o)| (r_o.sup_type, r_o.sub_region)),
156-
region_constraints)
160+
region_constraints,
161+
)
157162
});
158163

159164
let certainty = if ambig_errors.is_empty() {
@@ -184,7 +189,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
184189
&self,
185190
cause: &ObligationCause<'tcx>,
186191
param_env: ty::ParamEnv<'tcx>,
187-
original_values: &SmallCanonicalVarValues<'tcx>,
192+
original_values: &OriginalQueryValues<'tcx>,
188193
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
189194
) -> InferResult<'tcx, R>
190195
where
@@ -250,7 +255,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
250255
&self,
251256
cause: &ObligationCause<'tcx>,
252257
param_env: ty::ParamEnv<'tcx>,
253-
original_values: &SmallCanonicalVarValues<'tcx>,
258+
original_values: &OriginalQueryValues<'tcx>,
254259
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
255260
output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
256261
) -> InferResult<'tcx, R>
@@ -272,7 +277,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
272277
// variable...
273278
let mut obligations = vec![];
274279

275-
for (index, original_value) in original_values.iter().enumerate() {
280+
for (index, original_value) in original_values.var_values.iter().enumerate() {
276281
// ...with the value `v_r` of that variable from the query.
277282
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
278283
&v.var_values[CanonicalVar::new(index)]
@@ -344,7 +349,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
344349
&self,
345350
cause: &ObligationCause<'tcx>,
346351
param_env: ty::ParamEnv<'tcx>,
347-
original_values: &SmallCanonicalVarValues<'tcx>,
352+
original_values: &OriginalQueryValues<'tcx>,
348353
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
349354
) -> InferResult<'tcx, CanonicalVarValues<'tcx>>
350355
where
@@ -385,7 +390,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
385390
fn query_response_substitution_guess<R>(
386391
&self,
387392
cause: &ObligationCause<'tcx>,
388-
original_values: &SmallCanonicalVarValues<'tcx>,
393+
original_values: &OriginalQueryValues<'tcx>,
389394
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
390395
) -> CanonicalVarValues<'tcx>
391396
where
@@ -401,7 +406,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
401406
// these values with the original inputs that were
402407
// canonicalized.
403408
let result_values = &query_response.value.var_values;
404-
assert_eq!(original_values.len(), result_values.len());
409+
assert_eq!(original_values.var_values.len(), result_values.len());
405410

406411
// Quickly try to find initial values for the canonical
407412
// variables in the result in terms of the query. We do this
@@ -415,7 +420,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
415420

416421
// In terms of our example above, we are iterating over pairs like:
417422
// [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
418-
for (original_value, result_value) in original_values.iter().zip(result_values) {
423+
for (original_value, result_value) in original_values.var_values.iter().zip(result_values) {
419424
match result_value.unpack() {
420425
UnpackedKind::Type(result_value) => {
421426
// e.g., here `result_value` might be `?0` in the example above...
@@ -461,7 +466,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
461466
&self,
462467
cause: &ObligationCause<'tcx>,
463468
param_env: ty::ParamEnv<'tcx>,
464-
original_values: &SmallCanonicalVarValues<'tcx>,
469+
original_values: &OriginalQueryValues<'tcx>,
465470
result_subst: &CanonicalVarValues<'tcx>,
466471
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
467472
) -> InferResult<'tcx, ()>
@@ -478,7 +483,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
478483

479484
// Unify the original value for each variable with the value
480485
// taken from `query_response` (after applying `result_subst`).
481-
Ok(self.unify_canonical_vars(cause, param_env, original_values, substituted_query_response)?)
486+
Ok(self.unify_canonical_vars(
487+
cause,
488+
param_env,
489+
original_values,
490+
substituted_query_response,
491+
)?)
482492
}
483493

484494
/// Converts the region constraints resulting from a query into an
@@ -522,12 +532,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
522532
&self,
523533
cause: &ObligationCause<'tcx>,
524534
param_env: ty::ParamEnv<'tcx>,
525-
variables1: &SmallCanonicalVarValues<'tcx>,
535+
variables1: &OriginalQueryValues<'tcx>,
526536
variables2: impl Fn(CanonicalVar) -> Kind<'tcx>,
527537
) -> InferResult<'tcx, ()> {
528538
self.commit_if_ok(|_| {
529539
let mut obligations = vec![];
530-
for (index, value1) in variables1.iter().enumerate() {
540+
for (index, value1) in variables1.var_values.iter().enumerate() {
531541
let value2 = variables2(CanonicalVar::new(index));
532542

533543
match (value1.unpack(), value2.unpack()) {

src/librustc/traits/query/dropck_outlives.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use infer::at::At;
1212
use infer::InferOk;
13-
use smallvec::SmallVec;
13+
use infer::canonical::OriginalQueryValues;
1414
use std::iter::FromIterator;
1515
use syntax::source_map::Span;
1616
use ty::subst::Kind;
@@ -51,7 +51,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
5151
}
5252

5353
let gcx = tcx.global_tcx();
54-
let mut orig_values = SmallVec::new();
54+
let mut orig_values = OriginalQueryValues::default();
5555
let c_ty = self.infcx.canonicalize_query(&self.param_env.and(ty), &mut orig_values);
5656
let span = self.cause.span;
5757
debug!("c_ty = {:?}", c_ty);

src/librustc/traits/query/evaluate_obligation.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use infer::InferCtxt;
12-
use smallvec::SmallVec;
12+
use infer::canonical::OriginalQueryValues;
1313
use traits::{EvaluationResult, PredicateObligation, SelectionContext,
1414
TraitQueryMode, OverflowError};
1515

@@ -38,7 +38,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
3838
&self,
3939
obligation: &PredicateObligation<'tcx>,
4040
) -> Result<EvaluationResult, OverflowError> {
41-
let mut _orig_values = SmallVec::new();
41+
let mut _orig_values = OriginalQueryValues::default();
4242
let c_pred = self.canonicalize_query(&obligation.param_env.and(obligation.predicate),
4343
&mut _orig_values);
4444
// Run canonical query. If overflow occurs, rerun from scratch but this time

src/librustc/traits/query/normalize.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
//! `normalize_projection_ty` query when it encounters projections.
1414
1515
use infer::at::At;
16+
use infer::canonical::OriginalQueryValues;
1617
use infer::{InferCtxt, InferOk};
1718
use mir::interpret::{ConstValue, GlobalId};
18-
use smallvec::SmallVec;
1919
use traits::project::Normalized;
2020
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
2121
use ty::fold::{TypeFoldable, TypeFolder};
@@ -154,7 +154,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
154154

155155
let gcx = self.infcx.tcx.global_tcx();
156156

157-
let mut orig_values = SmallVec::new();
157+
let mut orig_values = OriginalQueryValues::default();
158158
let c_data = self.infcx.canonicalize_query(
159159
&self.param_env.and(*data), &mut orig_values);
160160
debug!("QueryNormalizer: c_data = {:#?}", c_data);

src/librustc/traits/query/outlives_bounds.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
// except according to those terms.
1010

1111
use infer::InferCtxt;
12+
use infer::canonical::OriginalQueryValues;
1213
use syntax::ast;
1314
use syntax::source_map::Span;
14-
use smallvec::SmallVec;
1515
use traits::{FulfillmentContext, ObligationCause, TraitEngine, TraitEngineExt};
1616
use traits::query::NoSolution;
1717
use ty::{self, Ty, TyCtxt};
@@ -105,7 +105,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
105105
) -> Vec<OutlivesBound<'tcx>> {
106106
debug!("implied_outlives_bounds(ty = {:?})", ty);
107107

108-
let mut orig_values = SmallVec::new();
108+
let mut orig_values = OriginalQueryValues::default();
109109
let key = self.canonicalize_query(&param_env.and(ty), &mut orig_values);
110110
let result = match self.tcx.global_tcx().implied_outlives_bounds(key) {
111111
Ok(r) => r,

src/librustc/traits/query/type_op/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
// except according to those terms.
1010

1111
use infer::canonical::{
12-
Canonical, Canonicalized, CanonicalizedQueryResponse, QueryRegionConstraint, QueryResponse,
12+
Canonical, Canonicalized, CanonicalizedQueryResponse, OriginalQueryValues,
13+
QueryRegionConstraint, QueryResponse,
1314
};
1415
use infer::{InferCtxt, InferOk};
15-
use smallvec::SmallVec;
1616
use std::fmt;
1717
use std::rc::Rc;
1818
use traits::query::Fallible;
@@ -106,7 +106,7 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
106106
// `canonicalize_hr_query_hack` here because of things
107107
// like the subtype query, which go awry around
108108
// `'static` otherwise.
109-
let mut canonical_var_values = SmallVec::new();
109+
let mut canonical_var_values = OriginalQueryValues::default();
110110
let canonical_self =
111111
infcx.canonicalize_hr_query_hack(&query_key, &mut canonical_var_values);
112112
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;

src/librustc_traits/chalk_context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010

1111
use chalk_engine::fallible::Fallible as ChalkEngineFallible;
1212
use chalk_engine::{context, hh::HhGoal, DelayedLiteral, ExClause};
13-
use rustc::infer::canonical::{Canonical, CanonicalVarValues, QueryRegionConstraint, QueryResponse};
13+
use rustc::infer::canonical::{
14+
Canonical, CanonicalVarValues, OriginalQueryValues, QueryRegionConstraint, QueryResponse,
15+
};
1416
use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
1517
use rustc::traits::{
1618
WellFormed,
@@ -26,7 +28,6 @@ use rustc::traits::{
2628
use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
2729
use rustc::ty::subst::Kind;
2830
use rustc::ty::{self, TyCtxt};
29-
use smallvec::SmallVec;
3031

3132
use std::fmt::{self, Debug};
3233
use std::marker::PhantomData;
@@ -390,7 +391,7 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
390391
&mut self,
391392
value: &ty::ParamEnvAnd<'tcx, Goal<'tcx>>,
392393
) -> Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>> {
393-
let mut _orig_values = SmallVec::new();
394+
let mut _orig_values = OriginalQueryValues::default();
394395
self.infcx.canonicalize_query(value, &mut _orig_values)
395396
}
396397

0 commit comments

Comments
 (0)