Skip to content

Commit 8e48139

Browse files
committed
chore: eliminate unsafe operations
1 parent 7049faf commit 8e48139

File tree

17 files changed

+196
-118
lines changed

17 files changed

+196
-118
lines changed

crates/els/completion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ fn load_modules(cfg: ErgConfig, cache: Cache) {
297297
cache.insert("<module>".into(), module_completions());
298298
}
299299
let std_path = erg_pystd_path().display().to_string().replace('\\', "/");
300-
for (path, entry) in shared.py_mod_cache.iter() {
300+
for (path, entry) in shared.py_mod_cache.ref_inner().iter() {
301301
let dir = entry.module.context.local_dir();
302302
let mod_name = path.display().to_string().replace('\\', "/");
303303
let mod_name = mod_name

crates/els/rename.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
149149
graph.sort().unwrap();
150150
let self_node = graph.get_node(&path).unwrap();
151151
graph
152+
.ref_inner()
152153
.iter()
153154
.filter(|node| node.id == path || self_node.depends_on(&node.id))
154155
.map(|node| NormalizedUrl::new(Url::from_file_path(&node.id).unwrap()))
@@ -160,6 +161,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
160161
let graph = &self.get_shared().unwrap().graph;
161162
let path = util::uri_to_path(uri);
162163
graph
164+
.ref_inner()
163165
.iter()
164166
.filter(|node| node.depends_on(&path))
165167
.map(|node| NormalizedUrl::new(Url::from_file_path(&node.id).unwrap()))

crates/els/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
651651

652652
pub(crate) fn get_builtin_module(&self) -> Option<&Context> {
653653
self.get_shared()
654-
.and_then(|mode| mode.mod_cache.ref_ctx(Path::new("<builtins>")))
654+
.and_then(|mode| mode.mod_cache.raw_ref_ctx(Path::new("<builtins>")))
655655
.map(|mc| &mc.context)
656656
}
657657

crates/erg_common/spawn.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ where
2929
.spawn(run)
3030
.unwrap();
3131
// Wait for thread to join
32-
child.join().unwrap()
32+
child.join().unwrap_or_else(|err| {
33+
eprintln!("Thread panicked: {err:?}");
34+
std::process::exit(1);
35+
})
3336
} else {
3437
run()
3538
}

crates/erg_compiler/context/generalize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ impl Generalizer {
135135
/// ```
136136
fn generalize_t(&mut self, free_type: Type, uninit: bool) -> Type {
137137
match free_type {
138-
FreeVar(fv) if fv.is_linked() => self.generalize_t(fv.crack().clone(), uninit),
138+
FreeVar(fv) if fv.is_linked() => self.generalize_t(fv.unsafe_crack().clone(), uninit),
139139
FreeVar(fv) if fv.is_generalized() => Type::FreeVar(fv),
140140
// TODO: Polymorphic generalization
141141
FreeVar(fv) if fv.level().unwrap() > self.level => {

crates/erg_compiler/context/initialize/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ impl Context {
772772
);
773773
self.consts.insert(name.clone(), val);
774774
for impl_trait in ctx.super_traits.iter() {
775-
if let Some(impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
775+
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
776776
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
777777
} else {
778778
self.trait_impls().register(
@@ -848,7 +848,7 @@ impl Context {
848848
}
849849
self.consts.insert(name.clone(), val);
850850
for impl_trait in ctx.super_traits.iter() {
851-
if let Some(impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
851+
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
852852
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
853853
} else {
854854
self.trait_impls().register(
@@ -912,7 +912,8 @@ impl Context {
912912
}
913913
}
914914
if let ContextKind::GluePatch(tr_impl) = &ctx.kind {
915-
if let Some(impls) = self.trait_impls().get_mut(&tr_impl.sup_trait.qual_name()) {
915+
if let Some(mut impls) = self.trait_impls().get_mut(&tr_impl.sup_trait.qual_name())
916+
{
916917
impls.insert(tr_impl.clone());
917918
} else {
918919
self.trait_impls()

crates/erg_compiler/context/inquire.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ impl Context {
5555
return Some(self.get_module().unwrap())
5656
}
5757
self.opt_mod_cache()?
58-
.ref_ctx(path)
59-
.or_else(|| self.opt_py_mod_cache()?.ref_ctx(path))
58+
.raw_ref_ctx(path)
59+
.or_else(|| self.opt_py_mod_cache()?.raw_ref_ctx(path))
6060
.map(|mod_ctx| &mod_ctx.context)
6161
}
6262

@@ -2463,7 +2463,10 @@ impl Context {
24632463
pub(crate) fn get_mod_with_path(&self, path: &Path) -> Option<&Context> {
24642464
(self.cfg.input.path() == Some(path)) // module itself
24652465
.then_some(self)
2466-
.or(self.mod_cache().get(path).map(|ent| &ent.module.context))
2466+
.or(self
2467+
.mod_cache()
2468+
.raw_ref_ctx(path)
2469+
.map(|mod_ctx| &mod_ctx.context))
24672470
}
24682471

24692472
// FIXME: 現在の実装だとimportしたモジュールはどこからでも見れる

crates/erg_compiler/context/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,12 @@ impl Context {
977977
if self.kind != ContextKind::Module || &self.path()[..] != "<builtins>" {
978978
self.shared
979979
.as_ref()
980-
.map(|shared| shared.mod_cache.ref_ctx(Path::new("<builtins>")).unwrap())
980+
.map(|shared| {
981+
shared
982+
.mod_cache
983+
.raw_ref_ctx(Path::new("<builtins>"))
984+
.unwrap()
985+
})
981986
.map(|mod_ctx| &mod_ctx.context)
982987
} else {
983988
None

crates/erg_compiler/context/register.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,7 +1653,7 @@ impl Context {
16531653
self.decls.insert(name.clone(), vi);
16541654
self.consts.insert(name.clone(), val);
16551655
for impl_trait in ctx.super_traits.iter() {
1656-
if let Some(impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
1656+
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
16571657
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
16581658
} else {
16591659
self.trait_impls().register(
@@ -1733,7 +1733,7 @@ impl Context {
17331733
self.consts
17341734
.insert(name.clone(), ValueObj::Type(TypeObj::Generated(gen)));
17351735
for impl_trait in ctx.super_traits.iter() {
1736-
if let Some(impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
1736+
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
17371737
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
17381738
} else {
17391739
self.trait_impls().register(

crates/erg_compiler/lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl ASTLowerer {
169169
if mode == "eval" {
170170
return;
171171
}
172-
for (referee, value) in self.module.context.index().iter() {
172+
for (referee, value) in self.module.context.index().members().iter() {
173173
let code = referee.code();
174174
let name = code.as_ref().map(|s| &s[..]).unwrap_or("");
175175
let name_is_auto =

crates/erg_compiler/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1892,7 +1892,7 @@ impl ASTLowerer {
18921892
trait_loc: &impl Locational,
18931893
) -> LowerResult<()> {
18941894
// TODO: polymorphic trait
1895-
if let Some(impls) = self
1895+
if let Some(mut impls) = self
18961896
.module
18971897
.context
18981898
.trait_impls()

crates/erg_compiler/module/cache.rs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::borrow::Borrow;
2+
use std::cell::{Ref, RefMut};
23
use std::fmt;
34
use std::hash::Hash;
45
use std::path::PathBuf;
@@ -173,20 +174,28 @@ impl SharedModuleCache {
173174
self.0.borrow().cache.len()
174175
}
175176

176-
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleEntry>
177+
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Ref<ModuleEntry>>
177178
where
178179
PathBuf: Borrow<Q>,
179180
{
180-
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
181-
ref_.get(path)
181+
if self.0.borrow().get(path).is_some() {
182+
Some(Ref::map(self.0.borrow(), |cache| cache.get(path).unwrap()))
183+
} else {
184+
None
185+
}
182186
}
183187

184-
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&mut ModuleEntry>
188+
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<RefMut<ModuleEntry>>
185189
where
186190
PathBuf: Borrow<Q>,
187191
{
188-
let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() };
189-
ref_.get_mut(path)
192+
if self.0.borrow().get(path).is_some() {
193+
Some(RefMut::map(self.0.borrow_mut(), |cache| {
194+
cache.get_mut(path).unwrap()
195+
}))
196+
} else {
197+
None
198+
}
190199
}
191200

192201
pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Rc<ModuleContext>>
@@ -196,7 +205,20 @@ impl SharedModuleCache {
196205
self.0.borrow().get(path).map(|entry| entry.module.clone())
197206
}
198207

199-
pub fn ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleContext>
208+
pub fn ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Ref<ModuleContext>>
209+
where
210+
PathBuf: Borrow<Q>,
211+
{
212+
if self.0.borrow().get(path).is_some() {
213+
Some(Ref::map(self.0.borrow(), |cache| {
214+
cache.get(path).unwrap().module.as_ref()
215+
}))
216+
} else {
217+
None
218+
}
219+
}
220+
221+
pub fn raw_ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleContext>
200222
where
201223
PathBuf: Borrow<Q>,
202224
{
@@ -223,18 +245,13 @@ impl SharedModuleCache {
223245
self.0.borrow().get_similar_name(name)
224246
}
225247

226-
pub fn keys(&self) -> impl Iterator<Item = PathBuf> {
227-
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
228-
ref_.cache.keys().cloned()
229-
}
230-
231248
pub fn initialize(&self) {
232249
let builtin_path = PathBuf::from("<builtins>");
233250
let Some(builtin) = self.remove(&builtin_path) else {
234251
return;
235252
};
236-
for path in self.keys() {
237-
self.remove(&path);
253+
for path in self.ref_inner().keys() {
254+
self.remove(path);
238255
}
239256
self.register(builtin_path, None, Rc::try_unwrap(builtin.module).unwrap());
240257
}
@@ -243,8 +260,7 @@ impl SharedModuleCache {
243260
self.0.borrow_mut().rename_path(path, new);
244261
}
245262

246-
pub fn iter(&self) -> impl Iterator<Item = (&PathBuf, &ModuleEntry)> {
247-
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
248-
ref_.iter()
263+
pub fn ref_inner(&self) -> Ref<Dict<PathBuf, ModuleEntry>> {
264+
Ref::map(self.0.borrow(), |mc| &mc.cache)
249265
}
250266
}

crates/erg_compiler/module/graph.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::Ref;
12
use std::fmt;
23
use std::path::{Path, PathBuf};
34

@@ -109,10 +110,14 @@ impl SharedModuleGraph {
109110
Self(Shared::new(ModuleGraph::new()))
110111
}
111112

112-
/// SAFETY: don't hold this reference before sorting
113-
pub fn get_node(&self, path: &Path) -> Option<&Node<PathBuf, ()>> {
114-
let ref_graph = unsafe { self.0.as_ptr().as_ref().unwrap() };
115-
ref_graph.get_node(path)
113+
pub fn get_node(&self, path: &Path) -> Option<Ref<Node<PathBuf, ()>>> {
114+
if self.0.borrow().get_node(path).is_some() {
115+
Some(Ref::map(self.0.borrow(), |graph| {
116+
graph.get_node(path).unwrap()
117+
}))
118+
} else {
119+
None
120+
}
116121
}
117122

118123
pub fn add_node_if_none(&self, path: &Path) {
@@ -123,10 +128,8 @@ impl SharedModuleGraph {
123128
self.0.borrow_mut().inc_ref(referrer, depends_on);
124129
}
125130

126-
/// SAFETY: don't hold this iterator before sorting
127-
pub fn iter(&self) -> impl Iterator<Item = &Node<PathBuf, ()>> {
128-
let ref_graph = unsafe { self.0.as_ptr().as_ref().unwrap() };
129-
ref_graph.iter()
131+
pub fn ref_inner(&self) -> Ref<ModuleGraph> {
132+
self.0.borrow()
130133
}
131134

132135
pub fn remove(&self, path: &Path) {

crates/erg_compiler/module/impls.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::borrow::Borrow;
2+
use std::cell::{Ref, RefMut};
23
use std::fmt;
34
use std::hash::Hash;
45

@@ -76,20 +77,28 @@ impl SharedTraitImpls {
7677
Self(Shared::new(TraitImpls::new()))
7778
}
7879

79-
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&Set<TraitImpl>>
80+
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Ref<Set<TraitImpl>>>
8081
where
8182
Str: Borrow<Q>,
8283
{
83-
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
84-
ref_.get(path)
84+
if self.0.borrow().get(path).is_some() {
85+
Some(Ref::map(self.0.borrow(), |tis| tis.get(path).unwrap()))
86+
} else {
87+
None
88+
}
8589
}
8690

87-
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&mut Set<TraitImpl>>
91+
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<RefMut<Set<TraitImpl>>>
8892
where
8993
Str: Borrow<Q>,
9094
{
91-
let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() };
92-
ref_.get_mut(path)
95+
if self.0.borrow().get(path).is_some() {
96+
Some(RefMut::map(self.0.borrow_mut(), |tis| {
97+
tis.get_mut(path).unwrap()
98+
}))
99+
} else {
100+
None
101+
}
93102
}
94103

95104
pub fn register(&self, name: Str, impls: Set<TraitImpl>) {
@@ -103,9 +112,8 @@ impl SharedTraitImpls {
103112
self.0.borrow_mut().remove(path)
104113
}
105114

106-
pub fn keys(&self) -> impl Iterator<Item = Str> {
107-
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
108-
ref_.cache.keys().cloned()
115+
pub fn ref_inner(&self) -> Ref<Dict<Str, Set<TraitImpl>>> {
116+
Ref::map(self.0.borrow(), |tis| &tis.cache)
109117
}
110118

111119
pub fn initialize(&self) {

crates/erg_compiler/module/index.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::cell::Ref;
12
use std::collections::hash_map::{Iter, Keys, Values};
23
use std::fmt;
34
use std::path::Path;
@@ -9,6 +10,22 @@ use erg_common::shared::Shared;
910

1011
use crate::varinfo::{AbsLocation, VarInfo};
1112

13+
pub struct Members<'a>(Ref<'a, Dict<AbsLocation, ModuleIndexValue>>);
14+
15+
impl<'a> Members<'a> {
16+
pub fn iter(&self) -> Iter<AbsLocation, ModuleIndexValue> {
17+
self.0.iter()
18+
}
19+
20+
pub fn keys(&self) -> Keys<AbsLocation, ModuleIndexValue> {
21+
self.0.keys()
22+
}
23+
24+
pub fn values(&self) -> Values<AbsLocation, ModuleIndexValue> {
25+
self.0.values()
26+
}
27+
}
28+
1229
#[derive(Debug, Clone, Default)]
1330
pub struct ModuleIndexValue {
1431
pub vi: VarInfo,
@@ -101,20 +118,18 @@ impl SharedModuleIndex {
101118
self.0.borrow_mut().register(vi);
102119
}
103120

104-
pub fn get_refs(&self, referee: &AbsLocation) -> Option<&ModuleIndexValue> {
105-
unsafe { self.0.as_ptr().as_ref().unwrap().get_refs(referee) }
106-
}
107-
108-
pub fn referees(&self) -> Keys<AbsLocation, ModuleIndexValue> {
109-
unsafe { self.0.as_ptr().as_ref().unwrap().members.keys() }
110-
}
111-
112-
pub fn referrers(&self) -> Values<AbsLocation, ModuleIndexValue> {
113-
unsafe { self.0.as_ptr().as_ref().unwrap().members.values() }
121+
pub fn get_refs(&self, referee: &AbsLocation) -> Option<Ref<ModuleIndexValue>> {
122+
if self.0.borrow().get_refs(referee).is_some() {
123+
Some(Ref::map(self.0.borrow(), |index| {
124+
index.get_refs(referee).unwrap()
125+
}))
126+
} else {
127+
None
128+
}
114129
}
115130

116-
pub fn iter(&self) -> Iter<AbsLocation, ModuleIndexValue> {
117-
unsafe { self.0.as_ptr().as_ref().unwrap().members.iter() }
131+
pub fn members(&self) -> Members {
132+
Members(Ref::map(self.0.borrow(), |mi| &mi.members))
118133
}
119134

120135
pub fn initialize(&self) {

0 commit comments

Comments
 (0)