Skip to content

Commit da4e33a

Browse files
committed
move frozen to rustc_data_structures
1 parent 508d4a2 commit da4e33a

File tree

6 files changed

+66
-26
lines changed

6 files changed

+66
-26
lines changed
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! An immutable, owned value.
2+
//!
3+
//! The purpose of `Frozen` is to make a value immutable for the sake of defensive programming. For example,
4+
//! suppose we have the following:
5+
//!
6+
//! ```rust
7+
//! struct Bar { /* some data */ }
8+
//!
9+
//! struct Foo {
10+
//! /// Some computed data that should never change after construction.
11+
//! pub computed: Bar,
12+
//!
13+
//! /* some other fields */
14+
//! }
15+
//!
16+
//! impl Bar {
17+
//! /// Mutate the `Bar`.
18+
//! pub fn mutate(&mut self) { }
19+
//! }
20+
//! ```
21+
//!
22+
//! Now suppose we want to pass around a mutable `Foo` instance but, we want to make sure that
23+
//! `computed` does not change accidentally (e.g. somebody might accidentally call
24+
//! `foo.computed.mutate()`). This is what `Frozen` is for. We can do the following:
25+
//!
26+
//! ```rust
27+
//! use rustc_data_structures::frozen::Frozen;
28+
//!
29+
//! struct Foo {
30+
//! /// Some computed data that should never change after construction.
31+
//! pub computed: Frozen<Bar>,
32+
//!
33+
//! /* some other fields */
34+
//! }
35+
//! ```
36+
//!
37+
//! `Frozen` impls `Deref`, so we can ergonomically call methods on `Bar`, but it doesn't `impl
38+
//! DerefMut`. Now calling `foo.compute.mutate()` will result in a compile-time error stating that
39+
//! `mutate` requires a mutable reference but we don't have one.
40+
41+
/// An owned immutable value.
42+
#[derive(Debug)]
43+
pub struct Frozen<T>(T);
44+
45+
impl<T> Frozen<T> {
46+
pub fn freeze(val: T) -> Self {
47+
Frozen(val)
48+
}
49+
}
50+
51+
impl<T> std::ops::Deref for Frozen<T> {
52+
type Target = T;
53+
54+
fn deref(&self) -> &T {
55+
&self.0
56+
}
57+
}

src/librustc_data_structures/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub mod profiling;
9494
pub mod vec_linked_list;
9595
pub mod work_queue;
9696
pub use atomic_ref::AtomicRef;
97+
pub mod frozen;
9798

9899
pub struct OnDrop<F: Fn()>(pub F);
99100

src/librustc_mir/borrow_check/mod.rs

+5-23
Original file line numberDiff line numberDiff line change
@@ -73,24 +73,6 @@ crate use place_ext::PlaceExt;
7373
crate use places_conflict::{places_conflict, PlaceConflictBias};
7474
crate use region_infer::RegionInferenceContext;
7575

76-
/// An owned immutable value.
77-
#[derive(Debug)]
78-
struct Frozen<T>(T);
79-
80-
impl<T> Frozen<T> {
81-
pub fn freeze(val: T) -> Self {
82-
Frozen(val)
83-
}
84-
}
85-
86-
impl<T> std::ops::Deref for Frozen<T> {
87-
type Target = T;
88-
89-
fn deref(&self) -> &T {
90-
&self.0
91-
}
92-
}
93-
9476
// FIXME(eddyb) perhaps move this somewhere more centrally.
9577
#[derive(Debug)]
9678
crate struct Upvar {
@@ -1595,11 +1577,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15951577
mpi,
15961578
);
15971579
} // Only query longest prefix with a MovePath, not further
1598-
// ancestors; dataflow recurs on children when parents
1599-
// move (to support partial (re)inits).
1600-
//
1601-
// (I.e., querying parents breaks scenario 7; but may want
1602-
// to do such a query based on partial-init feature-gate.)
1580+
// ancestors; dataflow recurs on children when parents
1581+
// move (to support partial (re)inits).
1582+
//
1583+
// (I.e., querying parents breaks scenario 7; but may want
1584+
// to do such a query based on partial-init feature-gate.)
16031585
}
16041586

16051587
/// Subslices correspond to multiple move paths, so we iterate through the

src/librustc_mir/borrow_check/region_infer/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc::mir::{
77
};
88
use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
99
use rustc_data_structures::binary_search_util;
10+
use rustc_data_structures::frozen::Frozen;
1011
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1112
use rustc_data_structures::graph::scc::Sccs;
1213
use rustc_hir::def_id::DefId;
@@ -31,7 +32,6 @@ use crate::borrow_check::{
3132
},
3233
type_check::{free_region_relations::UniversalRegionRelations, Locations},
3334
universal_regions::UniversalRegions,
34-
Frozen,
3535
};
3636

3737
mod dump_mir;

src/librustc_mir/borrow_check/type_check/free_region_relations.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc::mir::ConstraintCategory;
22
use rustc::ty::free_region_map::FreeRegionRelations;
33
use rustc::ty::{self, RegionVid, Ty, TyCtxt};
4+
use rustc_data_structures::frozen::Frozen;
45
use rustc_data_structures::transitive_relation::TransitiveRelation;
56
use rustc_infer::infer::canonical::QueryRegionConstraints;
67
use rustc_infer::infer::region_constraints::GenericKind;
@@ -15,7 +16,6 @@ use crate::borrow_check::{
1516
type_check::constraint_conversion,
1617
type_check::{Locations, MirTypeckRegionConstraints},
1718
universal_regions::UniversalRegions,
18-
Frozen,
1919
};
2020

2121
#[derive(Debug)]

src/librustc_mir/borrow_check/type_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc::ty::{
1818
self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, RegionVid, ToPolyTraitRef, Ty,
1919
TyCtxt, UserType, UserTypeAnnotationIndex,
2020
};
21+
use rustc_data_structures::frozen::Frozen;
2122
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2223
use rustc_errors::struct_span_err;
2324
use rustc_hir as hir;
@@ -55,7 +56,6 @@ use crate::borrow_check::{
5556
renumber,
5657
type_check::free_region_relations::{CreateResult, UniversalRegionRelations},
5758
universal_regions::{DefiningTy, UniversalRegions},
58-
Frozen,
5959
};
6060

6161
macro_rules! span_mirbug {

0 commit comments

Comments
 (0)