Skip to content

Commit d998059

Browse files
committed
Move opaque type cache into InferCtxt
1 parent 1f94abc commit d998059

File tree

7 files changed

+102
-107
lines changed

7 files changed

+102
-107
lines changed

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub use self::RegionVariableOrigin::*;
44
pub use self::SubregionOrigin::*;
55
pub use self::ValuePairs::*;
66

7+
use self::opaque_types::OpaqueTypeDecl;
78
pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
89

910
use crate::traits::{self, ObligationCause, PredicateObligations, TraitEngine};
@@ -12,6 +13,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1213
use rustc_data_structures::sync::Lrc;
1314
use rustc_data_structures::undo_log::Rollback;
1415
use rustc_data_structures::unify as ut;
16+
use rustc_data_structures::vec_map::VecMap;
1517
use rustc_errors::DiagnosticBuilder;
1618
use rustc_hir as hir;
1719
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -25,6 +27,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
2527
use rustc_middle::ty::relate::RelateResult;
2628
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
2729
pub use rustc_middle::ty::IntVarValue;
30+
use rustc_middle::ty::OpaqueTypeKey;
2831
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
2932
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
3033
use rustc_session::config::BorrowckMode;
@@ -59,6 +62,7 @@ pub mod lattice;
5962
mod lexical_region_resolve;
6063
mod lub;
6164
pub mod nll_relate;
65+
pub mod opaque_types;
6266
pub mod outlives;
6367
pub mod region_constraints;
6468
pub mod resolve;
@@ -191,6 +195,19 @@ pub struct InferCtxtInner<'tcx> {
191195
region_obligations: Vec<(hir::HirId, RegionObligation<'tcx>)>,
192196

193197
undo_log: InferCtxtUndoLogs<'tcx>,
198+
199+
// Opaque types found in explicit return types and their
200+
// associated fresh inference variable. Writeback resolves these
201+
// variables to get the concrete type, which can be used to
202+
// 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
203+
pub opaque_types: VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>,
204+
205+
/// A map from inference variables created from opaque
206+
/// type instantiations (`ty::Infer`) to the actual opaque
207+
/// type (`ty::Opaque`). Used during fallback to map unconstrained
208+
/// opaque type inference variables to their corresponding
209+
/// opaque type.
210+
pub opaque_types_vars: FxHashMap<Ty<'tcx>, Ty<'tcx>>,
194211
}
195212

196213
impl<'tcx> InferCtxtInner<'tcx> {
@@ -204,6 +221,8 @@ impl<'tcx> InferCtxtInner<'tcx> {
204221
float_unification_storage: ut::UnificationTableStorage::new(),
205222
region_constraint_storage: Some(RegionConstraintStorage::new()),
206223
region_obligations: vec![],
224+
opaque_types: Default::default(),
225+
opaque_types_vars: Default::default(),
207226
}
208227
}
209228

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use rustc_data_structures::vec_map::VecMap;
2+
use rustc_hir as hir;
3+
use rustc_middle::ty::{OpaqueTypeKey, Ty};
4+
use rustc_span::Span;
5+
6+
pub type OpaqueTypeMap<'tcx> = VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
7+
8+
/// Information about the opaque types whose values we
9+
/// are inferring in this function (these are the `impl Trait` that
10+
/// appear in the return type).
11+
#[derive(Copy, Clone, Debug)]
12+
pub struct OpaqueTypeDecl<'tcx> {
13+
/// The opaque type (`ty::Opaque`) for this declaration.
14+
pub opaque_type: Ty<'tcx>,
15+
16+
/// The span of this particular definition of the opaque type. So
17+
/// for example:
18+
///
19+
/// ```ignore (incomplete snippet)
20+
/// type Foo = impl Baz;
21+
/// fn bar() -> Foo {
22+
/// // ^^^ This is the span we are looking for!
23+
/// }
24+
/// ```
25+
///
26+
/// In cases where the fn returns `(impl Trait, impl Trait)` or
27+
/// other such combinations, the result is currently
28+
/// over-approximated, but better than nothing.
29+
pub definition_span: Span,
30+
31+
/// The type variable that represents the value of the opaque type
32+
/// that we require. In other words, after we compile this function,
33+
/// we will be created a constraint like:
34+
///
35+
/// Foo<'a, T> = ?C
36+
///
37+
/// where `?C` is the value of this type variable. =) It may
38+
/// naturally refer to the type and lifetime parameters in scope
39+
/// in this function, though ultimately it should only reference
40+
/// those that are arguments to `Foo` in the constraint above. (In
41+
/// other words, `?C` should not include `'b`, even though it's a
42+
/// lifetime parameter on `foo`.)
43+
pub concrete_ty: Ty<'tcx>,
44+
45+
/// Returns `true` if the `impl Trait` bounds include region bounds.
46+
/// For example, this would be true for:
47+
///
48+
/// fn foo<'a, 'b, 'c>() -> impl Trait<'c> + 'a + 'b
49+
///
50+
/// but false for:
51+
///
52+
/// fn foo<'c>() -> impl Trait<'c>
53+
///
54+
/// unless `Trait` was declared like:
55+
///
56+
/// trait Trait<'c>: 'c
57+
///
58+
/// in which case it would be true.
59+
///
60+
/// This is used during regionck to decide whether we need to
61+
/// impose any additional constraints to ensure that region
62+
/// variables in `concrete_ty` wind up being constrained to
63+
/// something from `substs` (or, at minimum, things that outlive
64+
/// the fn body). (Ultimately, writeback is responsible for this
65+
/// check.)
66+
pub has_required_region_bounds: bool,
67+
68+
/// The origin of the opaque type.
69+
pub origin: hir::OpaqueTyOrigin,
70+
}

compiler/rustc_trait_selection/src/opaque_types.rs

Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use crate::infer::InferCtxtExt as _;
22
use crate::traits::{self, ObligationCause, PredicateObligation};
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_data_structures::sync::Lrc;
5-
use rustc_data_structures::vec_map::VecMap;
65
use rustc_hir as hir;
76
use rustc_hir::def_id::{DefId, LocalDefId};
87
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
98
use rustc_infer::infer::free_regions::FreeRegionRelations;
9+
use rustc_infer::infer::opaque_types::{OpaqueTypeDecl, OpaqueTypeMap};
1010
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
1111
use rustc_infer::infer::{self, InferCtxt, InferOk};
1212
use rustc_middle::ty::fold::{BottomUpFolder, TypeFoldable, TypeFolder, TypeVisitor};
@@ -16,72 +16,6 @@ use rustc_span::Span;
1616

1717
use std::ops::ControlFlow;
1818

19-
pub type OpaqueTypeMap<'tcx> = VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
20-
21-
/// Information about the opaque types whose values we
22-
/// are inferring in this function (these are the `impl Trait` that
23-
/// appear in the return type).
24-
#[derive(Copy, Clone, Debug)]
25-
pub struct OpaqueTypeDecl<'tcx> {
26-
/// The opaque type (`ty::Opaque`) for this declaration.
27-
pub opaque_type: Ty<'tcx>,
28-
29-
/// The span of this particular definition of the opaque type. So
30-
/// for example:
31-
///
32-
/// ```ignore (incomplete snippet)
33-
/// type Foo = impl Baz;
34-
/// fn bar() -> Foo {
35-
/// // ^^^ This is the span we are looking for!
36-
/// }
37-
/// ```
38-
///
39-
/// In cases where the fn returns `(impl Trait, impl Trait)` or
40-
/// other such combinations, the result is currently
41-
/// over-approximated, but better than nothing.
42-
pub definition_span: Span,
43-
44-
/// The type variable that represents the value of the opaque type
45-
/// that we require. In other words, after we compile this function,
46-
/// we will be created a constraint like:
47-
///
48-
/// Foo<'a, T> = ?C
49-
///
50-
/// where `?C` is the value of this type variable. =) It may
51-
/// naturally refer to the type and lifetime parameters in scope
52-
/// in this function, though ultimately it should only reference
53-
/// those that are arguments to `Foo` in the constraint above. (In
54-
/// other words, `?C` should not include `'b`, even though it's a
55-
/// lifetime parameter on `foo`.)
56-
pub concrete_ty: Ty<'tcx>,
57-
58-
/// Returns `true` if the `impl Trait` bounds include region bounds.
59-
/// For example, this would be true for:
60-
///
61-
/// fn foo<'a, 'b, 'c>() -> impl Trait<'c> + 'a + 'b
62-
///
63-
/// but false for:
64-
///
65-
/// fn foo<'c>() -> impl Trait<'c>
66-
///
67-
/// unless `Trait` was declared like:
68-
///
69-
/// trait Trait<'c>: 'c
70-
///
71-
/// in which case it would be true.
72-
///
73-
/// This is used during regionck to decide whether we need to
74-
/// impose any additional constraints to ensure that region
75-
/// variables in `concrete_ty` wind up being constrained to
76-
/// something from `substs` (or, at minimum, things that outlive
77-
/// the fn body). (Ultimately, writeback is responsible for this
78-
/// check.)
79-
pub has_required_region_bounds: bool,
80-
81-
/// The origin of the opaque type.
82-
pub origin: hir::OpaqueTyOrigin,
83-
}
84-
8519
/// Whether member constraints should be generated for all opaque types
8620
#[derive(Debug)]
8721
pub enum GenerateMemberConstraints {
@@ -105,11 +39,7 @@ pub trait InferCtxtExt<'tcx> {
10539
value_span: Span,
10640
) -> InferOk<'tcx, (T, OpaqueTypeMap<'tcx>)>;
10741

108-
fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(
109-
&self,
110-
opaque_types: &OpaqueTypeMap<'tcx>,
111-
free_region_relations: &FRR,
112-
);
42+
fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(&self, free_region_relations: &FRR);
11343

11444
fn constrain_opaque_type<FRR: FreeRegionRelations<'tcx>>(
11545
&self,
@@ -350,12 +280,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
350280
/// - `opaque_types` -- the map produced by `instantiate_opaque_types`
351281
/// - `free_region_relations` -- something that can be used to relate
352282
/// the free regions (`'a`) that appear in the impl trait.
353-
fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(
354-
&self,
355-
opaque_types: &OpaqueTypeMap<'tcx>,
356-
free_region_relations: &FRR,
357-
) {
358-
for &(opaque_type_key, opaque_defn) in opaque_types {
283+
fn constrain_opaque_types<FRR: FreeRegionRelations<'tcx>>(&self, free_region_relations: &FRR) {
284+
let opaque_types = self.inner.borrow().opaque_types.clone();
285+
for (opaque_type_key, opaque_defn) in opaque_types {
359286
self.constrain_opaque_type(
360287
opaque_type_key,
361288
&opaque_defn,

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
385385
value_span,
386386
));
387387

388-
let mut opaque_types = self.opaque_types.borrow_mut();
389-
let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
388+
let mut infcx = self.infcx.inner.borrow_mut();
390389

391390
for (ty, decl) in opaque_type_map {
392391
if let Some(feature) = feature {
@@ -402,8 +401,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
402401
}
403402
}
404403
}
405-
let _ = opaque_types.insert(ty, decl);
406-
let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
404+
let _ = infcx.opaque_types.insert(ty, decl);
405+
let _ = infcx.opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
407406
}
408407

409408
value
@@ -726,7 +725,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
726725
// We treat this as a non-defining use by making the inference
727726
// variable fall back to the opaque type itself.
728727
if let FallbackMode::All = mode {
729-
if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
728+
if let Some(opaque_ty) = self.infcx.inner.borrow().opaque_types_vars.get(ty) {
730729
debug!(
731730
"fallback_if_possible: falling back opaque type var {:?} to {:?}",
732731
ty, opaque_ty

compiler/rustc_typeck/src/check/inherited.rs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
use super::callee::DeferredCallResolution;
22
use super::MaybeInProgressTables;
33

4-
use rustc_data_structures::fx::FxHashMap;
5-
use rustc_data_structures::vec_map::VecMap;
64
use rustc_hir as hir;
75
use rustc_hir::def_id::{DefIdMap, LocalDefId};
86
use rustc_hir::HirIdMap;
97
use rustc_infer::infer;
108
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
119
use rustc_middle::ty::fold::TypeFoldable;
12-
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt};
10+
use rustc_middle::ty::{self, Ty, TyCtxt};
1311
use rustc_span::{self, Span};
1412
use rustc_trait_selection::infer::InferCtxtExt as _;
15-
use rustc_trait_selection::opaque_types::OpaqueTypeDecl;
1613
use rustc_trait_selection::traits::{self, ObligationCause, TraitEngine, TraitEngineExt};
1714

1815
use std::cell::RefCell;
@@ -55,19 +52,6 @@ pub struct Inherited<'a, 'tcx> {
5552
pub(super) deferred_generator_interiors:
5653
RefCell<Vec<(hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
5754

58-
// Opaque types found in explicit return types and their
59-
// associated fresh inference variable. Writeback resolves these
60-
// variables to get the concrete type, which can be used to
61-
// 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
62-
pub(super) opaque_types: RefCell<VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>>,
63-
64-
/// A map from inference variables created from opaque
65-
/// type instantiations (`ty::Infer`) to the actual opaque
66-
/// type (`ty::Opaque`). Used during fallback to map unconstrained
67-
/// opaque type inference variables to their corresponding
68-
/// opaque type.
69-
pub(super) opaque_types_vars: RefCell<FxHashMap<Ty<'tcx>, Ty<'tcx>>>,
70-
7155
pub(super) body_id: Option<hir::BodyId>,
7256
}
7357

@@ -124,8 +108,6 @@ impl Inherited<'a, 'tcx> {
124108
deferred_call_resolutions: RefCell::new(Default::default()),
125109
deferred_cast_checks: RefCell::new(Vec::new()),
126110
deferred_generator_interiors: RefCell::new(Vec::new()),
127-
opaque_types: RefCell::new(Default::default()),
128-
opaque_types_vars: RefCell::new(Default::default()),
129111
body_id,
130112
}
131113
}

compiler/rustc_typeck/src/check/regionck.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
291291
self.visit_body(body);
292292
self.visit_region_obligations(body_id.hir_id);
293293

294-
self.constrain_opaque_types(
295-
&self.fcx.opaque_types.borrow(),
296-
self.outlives_environment.free_region_map(),
297-
);
294+
self.constrain_opaque_types(self.outlives_environment.free_region_map());
298295
}
299296

300297
fn visit_region_obligations(&mut self, hir_id: hir::HirId) {

compiler/rustc_typeck/src/check/writeback.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
498498
}
499499

500500
fn visit_opaque_types(&mut self, span: Span) {
501-
for &(opaque_type_key, opaque_defn) in self.fcx.opaque_types.borrow().iter() {
501+
let opaque_types = self.fcx.infcx.inner.borrow().opaque_types.clone();
502+
for (opaque_type_key, opaque_defn) in opaque_types {
502503
let hir_id =
503504
self.tcx().hir().local_def_id_to_hir_id(opaque_type_key.def_id.expect_local());
504505
let instantiated_ty = self.resolve(opaque_defn.concrete_ty, &hir_id);

0 commit comments

Comments
 (0)