Skip to content

Commit 7637cbb

Browse files
committed
Auto merge of rust-lang#75055 - cjgillot:clean-cache, r=oli-obk
Introduce an abstraction for EvaluationCache and SelectionCache The small duplicated code has been moved to librustc_query_system. The remaining changes are some cleanups of structural impls.
2 parents 8244b1b + 058e021 commit 7637cbb

File tree

8 files changed

+145
-367
lines changed

8 files changed

+145
-367
lines changed

src/librustc_middle/mir/interpret/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub enum ErrorHandled {
2727
TooGeneric,
2828
}
2929

30-
CloneTypeFoldableImpls! {
30+
CloneTypeFoldableAndLiftImpls! {
3131
ErrorHandled,
3232
}
3333

src/librustc_middle/traits/mod.rs

+17-18
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ pub type ChalkCanonicalGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx
3030

3131
pub use self::ImplSource::*;
3232
pub use self::ObligationCauseCode::*;
33-
pub use self::SelectionError::*;
3433

3534
pub use self::chalk::{
3635
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, RustInterner as ChalkRustInterner,
@@ -86,7 +85,7 @@ pub enum Reveal {
8685
///
8786
/// We do not want to intern this as there are a lot of obligation causes which
8887
/// only live for a short period of time.
89-
#[derive(Clone, PartialEq, Eq, Hash)]
88+
#[derive(Clone, PartialEq, Eq, Hash, Lift)]
9089
pub struct ObligationCause<'tcx> {
9190
/// `None` for `ObligationCause::dummy`, `Some` otherwise.
9291
data: Option<Rc<ObligationCauseData<'tcx>>>,
@@ -111,7 +110,7 @@ impl Deref for ObligationCause<'tcx> {
111110
}
112111
}
113112

114-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
113+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
115114
pub struct ObligationCauseData<'tcx> {
116115
pub span: Span,
117116

@@ -169,14 +168,14 @@ impl<'tcx> ObligationCause<'tcx> {
169168
}
170169
}
171170

172-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
171+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
173172
pub struct UnifyReceiverContext<'tcx> {
174173
pub assoc_item: ty::AssocItem,
175174
pub param_env: ty::ParamEnv<'tcx>,
176175
pub substs: SubstsRef<'tcx>,
177176
}
178177

179-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
178+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
180179
pub enum ObligationCauseCode<'tcx> {
181180
/// Not well classified or should be obvious from the span.
182181
MiscObligation,
@@ -343,7 +342,7 @@ impl ObligationCauseCode<'_> {
343342
#[cfg(target_arch = "x86_64")]
344343
static_assert_size!(ObligationCauseCode<'_>, 32);
345344

346-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
345+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
347346
pub struct MatchExpressionArmCause<'tcx> {
348347
pub arm_span: Span,
349348
pub source: hir::MatchSource,
@@ -359,7 +358,7 @@ pub struct IfExpressionCause {
359358
pub semicolon: Option<Span>,
360359
}
361360

362-
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
361+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
363362
pub struct DerivedObligationCause<'tcx> {
364363
/// The trait reference of the parent obligation that led to the
365364
/// current obligation. Note that only trait obligations lead to
@@ -371,7 +370,7 @@ pub struct DerivedObligationCause<'tcx> {
371370
pub parent_code: Rc<ObligationCauseCode<'tcx>>,
372371
}
373372

374-
#[derive(Clone, Debug, TypeFoldable)]
373+
#[derive(Clone, Debug, TypeFoldable, Lift)]
375374
pub enum SelectionError<'tcx> {
376375
Unimplemented,
377376
OutputTypeParameterMismatch(
@@ -427,7 +426,7 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
427426
/// ### The type parameter `N`
428427
///
429428
/// See explanation on `ImplSourceUserDefinedData`.
430-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
429+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
431430
pub enum ImplSource<'tcx, N> {
432431
/// ImplSource identifying a particular impl.
433432
ImplSourceUserDefined(ImplSourceUserDefinedData<'tcx, N>),
@@ -558,14 +557,14 @@ impl<'tcx, N> ImplSource<'tcx, N> {
558557
/// is `Obligation`, as one might expect. During codegen, however, this
559558
/// is `()`, because codegen only requires a shallow resolution of an
560559
/// impl, and nested obligations are satisfied later.
561-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
560+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
562561
pub struct ImplSourceUserDefinedData<'tcx, N> {
563562
pub impl_def_id: DefId,
564563
pub substs: SubstsRef<'tcx>,
565564
pub nested: Vec<N>,
566565
}
567566

568-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
567+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
569568
pub struct ImplSourceGeneratorData<'tcx, N> {
570569
pub generator_def_id: DefId,
571570
pub substs: SubstsRef<'tcx>,
@@ -574,7 +573,7 @@ pub struct ImplSourceGeneratorData<'tcx, N> {
574573
pub nested: Vec<N>,
575574
}
576575

577-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
576+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
578577
pub struct ImplSourceClosureData<'tcx, N> {
579578
pub closure_def_id: DefId,
580579
pub substs: SubstsRef<'tcx>,
@@ -583,18 +582,18 @@ pub struct ImplSourceClosureData<'tcx, N> {
583582
pub nested: Vec<N>,
584583
}
585584

586-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
585+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
587586
pub struct ImplSourceAutoImplData<N> {
588587
pub trait_def_id: DefId,
589588
pub nested: Vec<N>,
590589
}
591590

592-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
591+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
593592
pub struct ImplSourceBuiltinData<N> {
594593
pub nested: Vec<N>,
595594
}
596595

597-
#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
596+
#[derive(PartialEq, Eq, Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
598597
pub struct ImplSourceObjectData<'tcx, N> {
599598
/// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
600599
pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
@@ -607,17 +606,17 @@ pub struct ImplSourceObjectData<'tcx, N> {
607606
pub nested: Vec<N>,
608607
}
609608

610-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
609+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
611610
pub struct ImplSourceFnPointerData<'tcx, N> {
612611
pub fn_ty: Ty<'tcx>,
613612
pub nested: Vec<N>,
614613
}
615614

616615
// FIXME(@lcnr): This should be refactored and merged with other builtin vtables.
617-
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
616+
#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable)]
618617
pub struct ImplSourceDiscriminantKindData;
619618

620-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
619+
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, HashStable, TypeFoldable, Lift)]
621620
pub struct ImplSourceTraitAliasData<'tcx, N> {
622621
pub alias_def_id: DefId,
623622
pub substs: SubstsRef<'tcx>,

src/librustc_middle/traits/select.rs

+8-91
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,18 @@ use self::EvaluationResult::*;
66

77
use super::{SelectionError, SelectionResult};
88

9-
use crate::dep_graph::DepNodeIndex;
10-
use crate::ty::{self, TyCtxt};
9+
use crate::ty;
1110

12-
use rustc_data_structures::fx::FxHashMap;
13-
use rustc_data_structures::sync::Lock;
1411
use rustc_hir::def_id::DefId;
12+
use rustc_query_system::cache::Cache;
1513

16-
#[derive(Clone, Default)]
17-
pub struct SelectionCache<'tcx> {
18-
pub hashmap: Lock<
19-
FxHashMap<
20-
ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
21-
WithDepNode<SelectionResult<'tcx, SelectionCandidate<'tcx>>>,
22-
>,
23-
>,
24-
}
14+
pub type SelectionCache<'tcx> = Cache<
15+
ty::ParamEnvAnd<'tcx, ty::TraitRef<'tcx>>,
16+
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
17+
>;
2518

26-
impl<'tcx> SelectionCache<'tcx> {
27-
/// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
28-
pub fn clear(&self) {
29-
*self.hashmap.borrow_mut() = Default::default();
30-
}
31-
}
19+
pub type EvaluationCache<'tcx> =
20+
Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, EvaluationResult>;
3221

3322
/// The selection process begins by considering all impls, where
3423
/// clauses, and so forth that might resolve an obligation. Sometimes
@@ -264,75 +253,3 @@ impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
264253
SelectionError::Overflow
265254
}
266255
}
267-
268-
#[derive(Clone, Default)]
269-
pub struct EvaluationCache<'tcx> {
270-
pub hashmap: Lock<
271-
FxHashMap<ty::ParamEnvAnd<'tcx, ty::PolyTraitRef<'tcx>>, WithDepNode<EvaluationResult>>,
272-
>,
273-
}
274-
275-
impl<'tcx> EvaluationCache<'tcx> {
276-
/// Actually frees the underlying memory in contrast to what stdlib containers do on `clear`
277-
pub fn clear(&self) {
278-
*self.hashmap.borrow_mut() = Default::default();
279-
}
280-
}
281-
282-
#[derive(Clone, Eq, PartialEq)]
283-
pub struct WithDepNode<T> {
284-
dep_node: DepNodeIndex,
285-
cached_value: T,
286-
}
287-
288-
impl<T: Clone> WithDepNode<T> {
289-
pub fn new(dep_node: DepNodeIndex, cached_value: T) -> Self {
290-
WithDepNode { dep_node, cached_value }
291-
}
292-
293-
pub fn get(&self, tcx: TyCtxt<'_>) -> T {
294-
tcx.dep_graph.read_index(self.dep_node);
295-
self.cached_value.clone()
296-
}
297-
}
298-
299-
#[derive(Clone, Debug)]
300-
pub enum IntercrateAmbiguityCause {
301-
DownstreamCrate { trait_desc: String, self_desc: Option<String> },
302-
UpstreamCrateUpdate { trait_desc: String, self_desc: Option<String> },
303-
ReservationImpl { message: String },
304-
}
305-
306-
impl IntercrateAmbiguityCause {
307-
/// Emits notes when the overlap is caused by complex intercrate ambiguities.
308-
/// See #23980 for details.
309-
pub fn add_intercrate_ambiguity_hint(&self, err: &mut rustc_errors::DiagnosticBuilder<'_>) {
310-
err.note(&self.intercrate_ambiguity_hint());
311-
}
312-
313-
pub fn intercrate_ambiguity_hint(&self) -> String {
314-
match self {
315-
&IntercrateAmbiguityCause::DownstreamCrate { ref trait_desc, ref self_desc } => {
316-
let self_desc = if let &Some(ref ty) = self_desc {
317-
format!(" for type `{}`", ty)
318-
} else {
319-
String::new()
320-
};
321-
format!("downstream crates may implement trait `{}`{}", trait_desc, self_desc)
322-
}
323-
&IntercrateAmbiguityCause::UpstreamCrateUpdate { ref trait_desc, ref self_desc } => {
324-
let self_desc = if let &Some(ref ty) = self_desc {
325-
format!(" for type `{}`", ty)
326-
} else {
327-
String::new()
328-
};
329-
format!(
330-
"upstream crates may add a new impl of trait `{}`{} \
331-
in future versions",
332-
trait_desc, self_desc
333-
)
334-
}
335-
&IntercrateAmbiguityCause::ReservationImpl { ref message } => message.clone(),
336-
}
337-
}
338-
}

0 commit comments

Comments
 (0)