Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9618da7

Browse files
committed
Auto merge of rust-lang#131422 - GnomedDev:smallvec-predicate-obligations, r=compiler-errors
Use `ThinVec` for PredicateObligation storage ~~I noticed while profiling clippy on a project that a large amount of time is being spent allocating `Vec`s for `PredicateObligation`, and the `Vec`s are often quite small. This is an attempt to optimise this by using SmallVec to avoid heap allocations for these common small Vecs.~~ This PR turns all the `Vec<PredicateObligation>` into a single type alias while avoiding referring to `Vec` around it, then swaps the type over to `ThinVec<PredicateObligation>` and fixes the fallout. This also contains an implementation of `ThinVec::extract_if`, copied from `Vec::extract_if` and currently being upstreamed to mozilla/thin-vec#66. This leads to a small (0.2-0.7%) performance gain in the latest perf run.
2 parents 9ce3675 + 8de8f46 commit 9618da7

File tree

43 files changed

+414
-255
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+414
-255
lines changed

‎Cargo.lock‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# This file is automatically @generated by Cargo.
22
# It is not intended for manual editing.
3-
version = 3
3+
version = 4
44

55
[[package]]
66
name = "addr2line"
@@ -3857,6 +3857,7 @@ dependencies = [
38573857
"rustc_target",
38583858
"rustc_type_ir",
38593859
"smallvec",
3860+
"thin-vec",
38603861
"tracing",
38613862
]
38623863

@@ -4496,6 +4497,7 @@ dependencies = [
44964497
"rustc_transmute",
44974498
"rustc_type_ir",
44984499
"smallvec",
4500+
"thin-vec",
44994501
"tracing",
45004502
]
45014503

@@ -4567,6 +4569,7 @@ dependencies = [
45674569
"rustc_span",
45684570
"rustc_type_ir_macros",
45694571
"smallvec",
4572+
"thin-vec",
45704573
"tracing",
45714574
]
45724575

‎compiler/rustc_borrowck/src/type_check/mod.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_infer::infer::region_constraints::RegionConstraintData;
1818
use rustc_infer::infer::{
1919
BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin,
2020
};
21+
use rustc_infer::traits::PredicateObligations;
2122
use rustc_middle::mir::tcx::PlaceTy;
2223
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
2324
use rustc_middle::mir::*;
@@ -40,7 +41,6 @@ use rustc_span::source_map::Spanned;
4041
use rustc_span::symbol::sym;
4142
use rustc_span::{DUMMY_SP, Span};
4243
use rustc_target::abi::{FIRST_VARIANT, FieldIdx};
43-
use rustc_trait_selection::traits::PredicateObligation;
4444
use rustc_trait_selection::traits::query::type_op::custom::{
4545
CustomTypeOp, scrape_region_constraints,
4646
};
@@ -2940,7 +2940,7 @@ impl NormalizeLocation for Location {
29402940
pub(super) struct InstantiateOpaqueType<'tcx> {
29412941
pub base_universe: Option<ty::UniverseIndex>,
29422942
pub region_constraints: Option<RegionConstraintData<'tcx>>,
2943-
pub obligations: Vec<PredicateObligation<'tcx>>,
2943+
pub obligations: PredicateObligations<'tcx>,
29442944
}
29452945

29462946
impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> {

‎compiler/rustc_data_structures/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ pub mod svh;
7676
pub mod sync;
7777
pub mod tagged_ptr;
7878
pub mod temp_dir;
79+
pub mod thinvec;
7980
pub mod transitive_relation;
8081
pub mod unhash;
8182
pub mod unord;

‎compiler/rustc_data_structures/src/obligation_forest/mod.rs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ use std::fmt::Debug;
7575
use std::hash;
7676
use std::marker::PhantomData;
7777

78+
use thin_vec::ThinVec;
7879
use tracing::debug;
7980

8081
use crate::fx::{FxHashMap, FxHashSet};
@@ -141,7 +142,7 @@ pub trait ObligationProcessor {
141142
#[derive(Debug)]
142143
pub enum ProcessResult<O, E> {
143144
Unchanged,
144-
Changed(Vec<O>),
145+
Changed(ThinVec<O>),
145146
Error(E),
146147
}
147148

@@ -402,9 +403,10 @@ impl<O: ForestObligation> ObligationForest<O> {
402403
}
403404

404405
/// Returns the set of obligations that are in a pending state.
405-
pub fn map_pending_obligations<P, F>(&self, f: F) -> Vec<P>
406+
pub fn map_pending_obligations<P, F,R>(&self, f: F) -> R
406407
where
407408
F: Fn(&O) -> P,
409+
R: FromIterator<P>,
408410
{
409411
self.nodes
410412
.iter()

‎compiler/rustc_data_structures/src/obligation_forest/tests.rs‎

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::fmt;
22

3+
use thin_vec::thin_vec;
4+
35
use super::*;
46

57
impl<'a> super::ForestObligation for &'a str {
@@ -101,9 +103,9 @@ fn push_pop() {
101103
// |-> A.3
102104
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
103105
|obligation| match *obligation {
104-
"A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
106+
"A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]),
105107
"B" => ProcessResult::Error("B is for broken"),
106-
"C" => ProcessResult::Changed(vec![]),
108+
"C" => ProcessResult::Changed(thin_vec![]),
107109
"A.1" | "A.2" | "A.3" => ProcessResult::Unchanged,
108110
_ => unreachable!(),
109111
},
@@ -123,8 +125,8 @@ fn push_pop() {
123125
|obligation| match *obligation {
124126
"A.1" => ProcessResult::Unchanged,
125127
"A.2" => ProcessResult::Unchanged,
126-
"A.3" => ProcessResult::Changed(vec!["A.3.i"]),
127-
"D" => ProcessResult::Changed(vec!["D.1", "D.2"]),
128+
"A.3" => ProcessResult::Changed(thin_vec!["A.3.i"]),
129+
"D" => ProcessResult::Changed(thin_vec!["D.1", "D.2"]),
128130
"A.3.i" | "D.1" | "D.2" => ProcessResult::Unchanged,
129131
_ => unreachable!(),
130132
},
@@ -139,11 +141,11 @@ fn push_pop() {
139141
// |-> D.2 |-> D.2.i
140142
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
141143
|obligation| match *obligation {
142-
"A.1" => ProcessResult::Changed(vec![]),
144+
"A.1" => ProcessResult::Changed(thin_vec![]),
143145
"A.2" => ProcessResult::Error("A is for apple"),
144-
"A.3.i" => ProcessResult::Changed(vec![]),
145-
"D.1" => ProcessResult::Changed(vec!["D.1.i"]),
146-
"D.2" => ProcessResult::Changed(vec!["D.2.i"]),
146+
"A.3.i" => ProcessResult::Changed(thin_vec![]),
147+
"D.1" => ProcessResult::Changed(thin_vec!["D.1.i"]),
148+
"D.2" => ProcessResult::Changed(thin_vec!["D.2.i"]),
147149
"D.1.i" | "D.2.i" => ProcessResult::Unchanged,
148150
_ => unreachable!(),
149151
},
@@ -158,7 +160,7 @@ fn push_pop() {
158160
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
159161
|obligation| match *obligation {
160162
"D.1.i" => ProcessResult::Error("D is for dumb"),
161-
"D.2.i" => ProcessResult::Changed(vec![]),
163+
"D.2.i" => ProcessResult::Changed(thin_vec![]),
162164
_ => panic!("unexpected obligation {:?}", obligation),
163165
},
164166
|_| {},
@@ -184,10 +186,10 @@ fn success_in_grandchildren() {
184186

185187
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
186188
|obligation| match *obligation {
187-
"A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
188-
"A.1" => ProcessResult::Changed(vec![]),
189-
"A.2" => ProcessResult::Changed(vec!["A.2.i", "A.2.ii"]),
190-
"A.3" => ProcessResult::Changed(vec![]),
189+
"A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]),
190+
"A.1" => ProcessResult::Changed(thin_vec![]),
191+
"A.2" => ProcessResult::Changed(thin_vec!["A.2.i", "A.2.ii"]),
192+
"A.3" => ProcessResult::Changed(thin_vec![]),
191193
"A.2.i" | "A.2.ii" => ProcessResult::Unchanged,
192194
_ => unreachable!(),
193195
},
@@ -201,7 +203,7 @@ fn success_in_grandchildren() {
201203
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
202204
|obligation| match *obligation {
203205
"A.2.i" => ProcessResult::Unchanged,
204-
"A.2.ii" => ProcessResult::Changed(vec![]),
206+
"A.2.ii" => ProcessResult::Changed(thin_vec![]),
205207
_ => unreachable!(),
206208
},
207209
|_| {},
@@ -211,7 +213,7 @@ fn success_in_grandchildren() {
211213

212214
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
213215
|obligation| match *obligation {
214-
"A.2.i" => ProcessResult::Changed(vec!["A.2.i.a"]),
216+
"A.2.i" => ProcessResult::Changed(thin_vec!["A.2.i.a"]),
215217
"A.2.i.a" => ProcessResult::Unchanged,
216218
_ => unreachable!(),
217219
},
@@ -222,7 +224,7 @@ fn success_in_grandchildren() {
222224

223225
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
224226
|obligation| match *obligation {
225-
"A.2.i.a" => ProcessResult::Changed(vec![]),
227+
"A.2.i.a" => ProcessResult::Changed(thin_vec![]),
226228
_ => unreachable!(),
227229
},
228230
|_| {},
@@ -247,7 +249,7 @@ fn to_errors_no_throw() {
247249
forest.register_obligation("A");
248250
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
249251
|obligation| match *obligation {
250-
"A" => ProcessResult::Changed(vec!["A.1", "A.2", "A.3"]),
252+
"A" => ProcessResult::Changed(thin_vec!["A.1", "A.2", "A.3"]),
251253
"A.1" | "A.2" | "A.3" => ProcessResult::Unchanged,
252254
_ => unreachable!(),
253255
},
@@ -269,7 +271,7 @@ fn diamond() {
269271
forest.register_obligation("A");
270272
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
271273
|obligation| match *obligation {
272-
"A" => ProcessResult::Changed(vec!["A.1", "A.2"]),
274+
"A" => ProcessResult::Changed(thin_vec!["A.1", "A.2"]),
273275
"A.1" | "A.2" => ProcessResult::Unchanged,
274276
_ => unreachable!(),
275277
},
@@ -280,8 +282,8 @@ fn diamond() {
280282

281283
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
282284
|obligation| match *obligation {
283-
"A.1" => ProcessResult::Changed(vec!["D"]),
284-
"A.2" => ProcessResult::Changed(vec!["D"]),
285+
"A.1" => ProcessResult::Changed(thin_vec!["D"]),
286+
"A.2" => ProcessResult::Changed(thin_vec!["D"]),
285287
"D" => ProcessResult::Unchanged,
286288
_ => unreachable!(),
287289
},
@@ -295,7 +297,7 @@ fn diamond() {
295297
|obligation| match *obligation {
296298
"D" => {
297299
d_count += 1;
298-
ProcessResult::Changed(vec![])
300+
ProcessResult::Changed(thin_vec![])
299301
}
300302
_ => unreachable!(),
301303
},
@@ -313,7 +315,7 @@ fn diamond() {
313315
forest.register_obligation("A'");
314316
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
315317
|obligation| match *obligation {
316-
"A'" => ProcessResult::Changed(vec!["A'.1", "A'.2"]),
318+
"A'" => ProcessResult::Changed(thin_vec!["A'.1", "A'.2"]),
317319
"A'.1" | "A'.2" => ProcessResult::Unchanged,
318320
_ => unreachable!(),
319321
},
@@ -324,8 +326,8 @@ fn diamond() {
324326

325327
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
326328
|obligation| match *obligation {
327-
"A'.1" => ProcessResult::Changed(vec!["D'", "A'"]),
328-
"A'.2" => ProcessResult::Changed(vec!["D'"]),
329+
"A'.1" => ProcessResult::Changed(thin_vec!["D'", "A'"]),
330+
"A'.2" => ProcessResult::Changed(thin_vec!["D'"]),
329331
"D'" | "A'" => ProcessResult::Unchanged,
330332
_ => unreachable!(),
331333
},
@@ -366,7 +368,7 @@ fn done_dependency() {
366368

367369
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
368370
|obligation| match *obligation {
369-
"A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(vec![]),
371+
"A: Sized" | "B: Sized" | "C: Sized" => ProcessResult::Changed(thin_vec![]),
370372
_ => unreachable!(),
371373
},
372374
|_| {},
@@ -379,7 +381,9 @@ fn done_dependency() {
379381
forest.register_obligation("(A,B,C): Sized");
380382
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
381383
|obligation| match *obligation {
382-
"(A,B,C): Sized" => ProcessResult::Changed(vec!["A: Sized", "B: Sized", "C: Sized"]),
384+
"(A,B,C): Sized" => {
385+
ProcessResult::Changed(thin_vec!["A: Sized", "B: Sized", "C: Sized"])
386+
}
383387
_ => unreachable!(),
384388
},
385389
|_| {},
@@ -399,10 +403,10 @@ fn orphan() {
399403

400404
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
401405
|obligation| match *obligation {
402-
"A" => ProcessResult::Changed(vec!["D", "E"]),
406+
"A" => ProcessResult::Changed(thin_vec!["D", "E"]),
403407
"B" => ProcessResult::Unchanged,
404-
"C1" => ProcessResult::Changed(vec![]),
405-
"C2" => ProcessResult::Changed(vec![]),
408+
"C1" => ProcessResult::Changed(thin_vec![]),
409+
"C2" => ProcessResult::Changed(thin_vec![]),
406410
"D" | "E" => ProcessResult::Unchanged,
407411
_ => unreachable!(),
408412
},
@@ -416,7 +420,7 @@ fn orphan() {
416420
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
417421
|obligation| match *obligation {
418422
"D" | "E" => ProcessResult::Unchanged,
419-
"B" => ProcessResult::Changed(vec!["D"]),
423+
"B" => ProcessResult::Changed(thin_vec!["D"]),
420424
_ => unreachable!(),
421425
},
422426
|_| {},
@@ -459,7 +463,7 @@ fn simultaneous_register_and_error() {
459463
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
460464
|obligation| match *obligation {
461465
"A" => ProcessResult::Error("An error"),
462-
"B" => ProcessResult::Changed(vec!["A"]),
466+
"B" => ProcessResult::Changed(thin_vec!["A"]),
463467
_ => unreachable!(),
464468
},
465469
|_| {},
@@ -474,7 +478,7 @@ fn simultaneous_register_and_error() {
474478
let TestOutcome { completed: ok, errors: err, .. } = forest.process_obligations(&mut C(
475479
|obligation| match *obligation {
476480
"A" => ProcessResult::Error("An error"),
477-
"B" => ProcessResult::Changed(vec!["A"]),
481+
"B" => ProcessResult::Changed(thin_vec!["A"]),
478482
_ => unreachable!(),
479483
},
480484
|_| {},

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /