mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
merge from main
This commit is contained in:
commit
980be54590
17 changed files with 197 additions and 139 deletions
|
@ -297,7 +297,7 @@ fn load_modules(cfg: ErgConfig, cache: Cache) {
|
|||
cache.insert("<module>".into(), module_completions());
|
||||
}
|
||||
let std_path = ERG_PYSTD_PATH.display().to_string().replace('\\', "/");
|
||||
for (path, entry) in shared.py_mod_cache.iter() {
|
||||
for (path, entry) in shared.py_mod_cache.ref_inner().iter() {
|
||||
let dir = entry.module.context.local_dir();
|
||||
let mod_name = path.display().to_string().replace('\\', "/");
|
||||
let mod_name = mod_name
|
||||
|
|
|
@ -149,6 +149,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
|
|||
graph.sort().unwrap();
|
||||
let self_node = graph.get_node(&path).unwrap();
|
||||
graph
|
||||
.ref_inner()
|
||||
.iter()
|
||||
.filter(|node| node.id == path || self_node.depends_on(&node.id))
|
||||
.map(|node| NormalizedUrl::new(Url::from_file_path(&node.id).unwrap()))
|
||||
|
@ -160,6 +161,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
|
|||
let graph = &self.get_shared().unwrap().graph;
|
||||
let path = util::uri_to_path(uri);
|
||||
graph
|
||||
.ref_inner()
|
||||
.iter()
|
||||
.filter(|node| node.depends_on(&path))
|
||||
.map(|node| NormalizedUrl::new(Url::from_file_path(&node.id).unwrap()))
|
||||
|
|
|
@ -651,7 +651,7 @@ impl<Checker: BuildRunnable> Server<Checker> {
|
|||
|
||||
pub(crate) fn get_builtin_module(&self) -> Option<&Context> {
|
||||
self.get_shared()
|
||||
.and_then(|mode| mode.mod_cache.ref_ctx(Path::new("<builtins>")))
|
||||
.and_then(|mode| mode.mod_cache.raw_ref_ctx(Path::new("<builtins>")))
|
||||
.map(|mc| &mc.context)
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,10 @@ where
|
|||
.spawn(run)
|
||||
.unwrap();
|
||||
// Wait for thread to join
|
||||
child.join().unwrap()
|
||||
child.join().unwrap_or_else(|err| {
|
||||
eprintln!("Thread panicked: {err:?}");
|
||||
std::process::exit(1);
|
||||
})
|
||||
} else {
|
||||
run()
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ impl Generalizer {
|
|||
/// ```
|
||||
fn generalize_t(&mut self, free_type: Type, uninit: bool) -> Type {
|
||||
match free_type {
|
||||
FreeVar(fv) if fv.is_linked() => self.generalize_t(fv.crack().clone(), uninit),
|
||||
FreeVar(fv) if fv.is_linked() => self.generalize_t(fv.unsafe_crack().clone(), uninit),
|
||||
FreeVar(fv) if fv.is_generalized() => Type::FreeVar(fv),
|
||||
// TODO: Polymorphic generalization
|
||||
FreeVar(fv) if fv.level().unwrap() > self.level => {
|
||||
|
|
|
@ -773,8 +773,7 @@ impl Context {
|
|||
);
|
||||
self.consts.insert(name.clone(), val);
|
||||
for impl_trait in ctx.super_traits.iter() {
|
||||
if self.trait_impls().get(&impl_trait.qual_name()).is_some() {
|
||||
let mut impls = self.trait_impls().get_mut(&impl_trait.qual_name());
|
||||
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
|
||||
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
|
||||
} else {
|
||||
self.trait_impls().register(
|
||||
|
@ -850,8 +849,7 @@ impl Context {
|
|||
}
|
||||
self.consts.insert(name.clone(), val);
|
||||
for impl_trait in ctx.super_traits.iter() {
|
||||
if self.trait_impls().get(&impl_trait.qual_name()).is_some() {
|
||||
let mut impls = self.trait_impls().get_mut(&impl_trait.qual_name());
|
||||
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
|
||||
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
|
||||
} else {
|
||||
self.trait_impls().register(
|
||||
|
@ -915,12 +913,8 @@ impl Context {
|
|||
}
|
||||
}
|
||||
if let ContextKind::GluePatch(tr_impl) = &ctx.kind {
|
||||
if self
|
||||
.trait_impls()
|
||||
.get(&tr_impl.sup_trait.qual_name())
|
||||
.is_some()
|
||||
if let Some(mut impls) = self.trait_impls().get_mut(&tr_impl.sup_trait.qual_name())
|
||||
{
|
||||
let mut impls = self.trait_impls().get_mut(&tr_impl.sup_trait.qual_name());
|
||||
impls.insert(tr_impl.clone());
|
||||
} else {
|
||||
self.trait_impls()
|
||||
|
|
|
@ -55,8 +55,8 @@ impl Context {
|
|||
return Some(self.get_module().unwrap())
|
||||
}
|
||||
self.opt_mod_cache()?
|
||||
.ref_ctx(path)
|
||||
.or_else(|| self.opt_py_mod_cache()?.ref_ctx(path))
|
||||
.raw_ref_ctx(path)
|
||||
.or_else(|| self.opt_py_mod_cache()?.raw_ref_ctx(path))
|
||||
.map(|mod_ctx| &mod_ctx.context)
|
||||
}
|
||||
|
||||
|
@ -2463,7 +2463,10 @@ impl Context {
|
|||
pub(crate) fn get_mod_with_path(&self, path: &Path) -> Option<&Context> {
|
||||
(self.cfg.input.path() == Some(path)) // module itself
|
||||
.then_some(self)
|
||||
.or(self.mod_cache().get(path).map(|ent| &ent.module.context))
|
||||
.or(self
|
||||
.mod_cache()
|
||||
.raw_ref_ctx(path)
|
||||
.map(|mod_ctx| &mod_ctx.context))
|
||||
}
|
||||
|
||||
// FIXME: 現在の実装だとimportしたモジュールはどこからでも見れる
|
||||
|
|
|
@ -977,7 +977,12 @@ impl Context {
|
|||
if self.kind != ContextKind::Module || &self.path()[..] != "<builtins>" {
|
||||
self.shared
|
||||
.as_ref()
|
||||
.map(|shared| shared.mod_cache.ref_ctx(Path::new("<builtins>")).unwrap())
|
||||
.map(|shared| {
|
||||
shared
|
||||
.mod_cache
|
||||
.raw_ref_ctx(Path::new("<builtins>"))
|
||||
.unwrap()
|
||||
})
|
||||
.map(|mod_ctx| &mod_ctx.context)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -1653,8 +1653,7 @@ impl Context {
|
|||
self.decls.insert(name.clone(), vi);
|
||||
self.consts.insert(name.clone(), val);
|
||||
for impl_trait in ctx.super_traits.iter() {
|
||||
if self.trait_impls().get(&impl_trait.qual_name()).is_some() {
|
||||
let mut impls = self.trait_impls().get_mut(&impl_trait.qual_name());
|
||||
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
|
||||
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
|
||||
} else {
|
||||
self.trait_impls().register(
|
||||
|
@ -1734,8 +1733,7 @@ impl Context {
|
|||
self.consts
|
||||
.insert(name.clone(), ValueObj::Type(TypeObj::Generated(gen)));
|
||||
for impl_trait in ctx.super_traits.iter() {
|
||||
if self.trait_impls().get(&impl_trait.qual_name()).is_some() {
|
||||
let mut impls = self.trait_impls().get_mut(&impl_trait.qual_name());
|
||||
if let Some(mut impls) = self.trait_impls().get_mut(&impl_trait.qual_name()) {
|
||||
impls.insert(TraitImpl::new(t.clone(), impl_trait.clone()));
|
||||
} else {
|
||||
self.trait_impls().register(
|
||||
|
|
|
@ -169,7 +169,7 @@ impl ASTLowerer {
|
|||
if mode == "eval" {
|
||||
return;
|
||||
}
|
||||
for (referee, value) in self.module.context.index().iter() {
|
||||
for (referee, value) in self.module.context.index().members().iter() {
|
||||
let code = referee.code();
|
||||
let name = code.as_ref().map(|s| &s[..]).unwrap_or("");
|
||||
let name_is_auto =
|
||||
|
|
|
@ -1892,18 +1892,12 @@ impl ASTLowerer {
|
|||
trait_loc: &impl Locational,
|
||||
) -> LowerResult<()> {
|
||||
// TODO: polymorphic trait
|
||||
if self
|
||||
if let Some(mut impls) = self
|
||||
.module
|
||||
.context
|
||||
.trait_impls()
|
||||
.get(&trait_.qual_name())
|
||||
.is_some()
|
||||
.get_mut(&trait_.qual_name())
|
||||
{
|
||||
let mut impls = self
|
||||
.module
|
||||
.context
|
||||
.trait_impls()
|
||||
.get_mut(&trait_.qual_name());
|
||||
impls.insert(TraitImpl::new(class.clone(), trait_.clone()));
|
||||
} else {
|
||||
self.module.context.trait_impls().register(
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::sync::Arc;
|
|||
use erg_common::config::ErgConfig;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::levenshtein::get_similar_name;
|
||||
use erg_common::shared::Shared;
|
||||
use erg_common::shared::{Shared, MappedRwLockReadGuard, RwLockReadGuard, MappedRwLockWriteGuard, RwLockWriteGuard};
|
||||
use erg_common::Str;
|
||||
|
||||
use crate::context::ModuleContext;
|
||||
|
@ -173,20 +173,28 @@ impl SharedModuleCache {
|
|||
self.0.borrow().cache.len()
|
||||
}
|
||||
|
||||
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleEntry>
|
||||
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<MappedRwLockReadGuard<ModuleEntry>>
|
||||
where
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_.get(path)
|
||||
if self.0.borrow().get(path).is_some() {
|
||||
Some(RwLockReadGuard::map(self.0.borrow(), |cache| cache.get(path).unwrap()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&mut ModuleEntry>
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<MappedRwLockWriteGuard<ModuleEntry>>
|
||||
where
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() };
|
||||
ref_.get_mut(path)
|
||||
if self.0.borrow().get(path).is_some() {
|
||||
Some(RwLockWriteGuard::map(self.0.borrow_mut(), |cache| {
|
||||
cache.get_mut(path).unwrap()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<Arc<ModuleContext>>
|
||||
|
@ -196,7 +204,20 @@ impl SharedModuleCache {
|
|||
self.0.borrow().get(path).map(|entry| entry.module.clone())
|
||||
}
|
||||
|
||||
pub fn ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleContext>
|
||||
pub fn ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<MappedRwLockReadGuard<ModuleContext>>
|
||||
where
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
if self.0.borrow().get(path).is_some() {
|
||||
Some(RwLockReadGuard::map(self.0.borrow(), |cache| {
|
||||
cache.get(path).unwrap().module.as_ref()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn raw_ref_ctx<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&ModuleContext>
|
||||
where
|
||||
PathBuf: Borrow<Q>,
|
||||
{
|
||||
|
@ -223,18 +244,13 @@ impl SharedModuleCache {
|
|||
self.0.borrow().get_similar_name(name)
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> impl Iterator<Item = PathBuf> {
|
||||
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_.cache.keys().cloned()
|
||||
}
|
||||
|
||||
pub fn initialize(&self) {
|
||||
let builtin_path = PathBuf::from("<builtins>");
|
||||
let Some(builtin) = self.remove(&builtin_path) else {
|
||||
return;
|
||||
};
|
||||
for path in self.keys() {
|
||||
self.remove(&path);
|
||||
for path in self.ref_inner().keys() {
|
||||
self.remove(path);
|
||||
}
|
||||
self.register(builtin_path, None, Arc::try_unwrap(builtin.module).unwrap());
|
||||
}
|
||||
|
@ -243,8 +259,7 @@ impl SharedModuleCache {
|
|||
self.0.borrow_mut().rename_path(path, new);
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&PathBuf, &ModuleEntry)> {
|
||||
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_.iter()
|
||||
pub fn ref_inner(&self) -> MappedRwLockReadGuard<Dict<PathBuf, ModuleEntry>> {
|
||||
RwLockReadGuard::map(self.0.borrow(), |mc| &mc.cache)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::fmt;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use erg_common::shared::Shared;
|
||||
use erg_common::shared::{Shared, MappedRwLockReadGuard, RwLockReadGuard};
|
||||
use erg_common::tsort::{tsort, Graph, Node, TopoSortError};
|
||||
use erg_common::{normalize_path, set};
|
||||
|
||||
|
@ -109,10 +109,14 @@ impl SharedModuleGraph {
|
|||
Self(Shared::new(ModuleGraph::new()))
|
||||
}
|
||||
|
||||
/// SAFETY: don't hold this reference before sorting
|
||||
pub fn get_node(&self, path: &Path) -> Option<&Node<PathBuf, ()>> {
|
||||
let ref_graph = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_graph.get_node(path)
|
||||
pub fn get_node(&self, path: &Path) -> Option<MappedRwLockReadGuard<Node<PathBuf, ()>>> {
|
||||
if self.0.borrow().get_node(path).is_some() {
|
||||
Some(RwLockReadGuard::map(self.0.borrow(), |graph| {
|
||||
graph.get_node(path).unwrap()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_node_if_none(&self, path: &Path) {
|
||||
|
@ -123,10 +127,8 @@ impl SharedModuleGraph {
|
|||
self.0.borrow_mut().inc_ref(referrer, depends_on);
|
||||
}
|
||||
|
||||
/// SAFETY: don't hold this iterator before sorting
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Node<PathBuf, ()>> {
|
||||
let ref_graph = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_graph.iter()
|
||||
pub fn ref_inner(&self) -> RwLockReadGuard<ModuleGraph> {
|
||||
self.0.borrow()
|
||||
}
|
||||
|
||||
pub fn remove(&self, path: &Path) {
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::hash::Hash;
|
|||
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::shared::{MappedRwLockWriteGuard, RwLockWriteGuard, Shared};
|
||||
use erg_common::shared::{MappedRwLockWriteGuard, RwLockWriteGuard, Shared, MappedRwLockReadGuard, RwLockReadGuard};
|
||||
use erg_common::Str;
|
||||
|
||||
use crate::context::TraitImpl;
|
||||
|
@ -76,21 +76,28 @@ impl SharedTraitImpls {
|
|||
Self(Shared::new(TraitImpls::new()))
|
||||
}
|
||||
|
||||
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<&Set<TraitImpl>>
|
||||
pub fn get<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<MappedRwLockReadGuard<Set<TraitImpl>>>
|
||||
where
|
||||
Str: Borrow<Q>,
|
||||
{
|
||||
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_.get(path)
|
||||
if self.0.borrow().get(path).is_some() {
|
||||
Some(RwLockReadGuard::map(self.0.borrow(), |tis| tis.get(path).unwrap()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> MappedRwLockWriteGuard<Set<TraitImpl>>
|
||||
pub fn get_mut<Q: Eq + Hash + ?Sized>(&self, path: &Q) -> Option<MappedRwLockWriteGuard<Set<TraitImpl>>>
|
||||
where
|
||||
Str: Borrow<Q>,
|
||||
{
|
||||
// let ref_ = unsafe { self.0.as_ptr().as_mut().unwrap() };
|
||||
// ref_.get_mut(path)
|
||||
RwLockWriteGuard::map(self.0.borrow_mut(), |tis| tis.get_mut(path).unwrap())
|
||||
if self.0.borrow().get(path).is_some() {
|
||||
Some(RwLockWriteGuard::map(self.0.borrow_mut(), |tis| {
|
||||
tis.get_mut(path).unwrap()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register(&self, name: Str, impls: Set<TraitImpl>) {
|
||||
|
@ -104,9 +111,8 @@ impl SharedTraitImpls {
|
|||
self.0.borrow_mut().remove(path)
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> impl Iterator<Item = Str> {
|
||||
let ref_ = unsafe { self.0.as_ptr().as_ref().unwrap() };
|
||||
ref_.cache.keys().cloned()
|
||||
pub fn ref_inner(&self) -> MappedRwLockReadGuard<Dict<Str, Set<TraitImpl>>> {
|
||||
RwLockReadGuard::map(self.0.borrow(), |tis| &tis.cache)
|
||||
}
|
||||
|
||||
pub fn initialize(&self) {
|
||||
|
|
|
@ -5,10 +5,26 @@ use std::path::Path;
|
|||
use erg_common::dict::Dict;
|
||||
use erg_common::set;
|
||||
use erg_common::set::Set;
|
||||
use erg_common::shared::Shared;
|
||||
use erg_common::shared::{Shared, MappedRwLockReadGuard, RwLockReadGuard};
|
||||
|
||||
use crate::varinfo::{AbsLocation, VarInfo};
|
||||
|
||||
pub struct Members<'a>(MappedRwLockReadGuard<'a, Dict<AbsLocation, ModuleIndexValue>>);
|
||||
|
||||
impl<'a> Members<'a> {
|
||||
pub fn iter(&self) -> Iter<AbsLocation, ModuleIndexValue> {
|
||||
self.0.iter()
|
||||
}
|
||||
|
||||
pub fn keys(&self) -> Keys<AbsLocation, ModuleIndexValue> {
|
||||
self.0.keys()
|
||||
}
|
||||
|
||||
pub fn values(&self) -> Values<AbsLocation, ModuleIndexValue> {
|
||||
self.0.values()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ModuleIndexValue {
|
||||
pub vi: VarInfo,
|
||||
|
@ -101,20 +117,18 @@ impl SharedModuleIndex {
|
|||
self.0.borrow_mut().register(vi);
|
||||
}
|
||||
|
||||
pub fn get_refs(&self, referee: &AbsLocation) -> Option<&ModuleIndexValue> {
|
||||
unsafe { self.0.as_ptr().as_ref().unwrap().get_refs(referee) }
|
||||
pub fn get_refs(&self, referee: &AbsLocation) -> Option<MappedRwLockReadGuard<ModuleIndexValue>> {
|
||||
if self.0.borrow().get_refs(referee).is_some() {
|
||||
Some(RwLockReadGuard::map(self.0.borrow(), |index| {
|
||||
index.get_refs(referee).unwrap()
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn referees(&self) -> Keys<AbsLocation, ModuleIndexValue> {
|
||||
unsafe { self.0.as_ptr().as_ref().unwrap().members.keys() }
|
||||
}
|
||||
|
||||
pub fn referrers(&self) -> Values<AbsLocation, ModuleIndexValue> {
|
||||
unsafe { self.0.as_ptr().as_ref().unwrap().members.values() }
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> Iter<AbsLocation, ModuleIndexValue> {
|
||||
unsafe { self.0.as_ptr().as_ref().unwrap().members.iter() }
|
||||
pub fn members(&self) -> Members {
|
||||
Members(RwLockReadGuard::map(self.0.borrow(), |mi| &mi.members))
|
||||
}
|
||||
|
||||
pub fn initialize(&self) {
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher};
|
|||
use std::mem;
|
||||
|
||||
use erg_common::fresh::VAR_ID;
|
||||
use erg_common::shared::Shared;
|
||||
use erg_common::shared::{Shared, MappedRwLockWriteGuard};
|
||||
use erg_common::shared::{MappedRwLockReadGuard, RwLockReadGuard, RwLockWriteGuard};
|
||||
use erg_common::traits::{LimitedDisplay, StructuralEq};
|
||||
use erg_common::Str;
|
||||
|
@ -662,26 +662,25 @@ impl<T: Clone> Free<T> {
|
|||
|
||||
impl HasLevel for Free<Type> {
|
||||
fn set_level(&self, level: Level) {
|
||||
match unsafe { &mut *self.as_ptr() as &mut FreeKind<Type> } {
|
||||
match &mut *self.borrow_mut() {
|
||||
FreeKind::Unbound { lev, .. } | FreeKind::NamedUnbound { lev, .. } => {
|
||||
if addr_eq!(*lev, level) {
|
||||
return;
|
||||
}
|
||||
*lev = level;
|
||||
if let Some((sub, sup)) = self.get_subsup() {
|
||||
self.dummy_link();
|
||||
sub.set_level(level);
|
||||
sup.set_level(level);
|
||||
self.undo();
|
||||
} else if let Some(t) = self.get_type() {
|
||||
t.set_level(level);
|
||||
}
|
||||
}
|
||||
FreeKind::Linked(t) => {
|
||||
t.set_level(level);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(linked) = self.raw_get_linked() {
|
||||
linked.set_level(level);
|
||||
} else if let Some((sub, sup)) = self.get_subsup() {
|
||||
self.dummy_link();
|
||||
sub.set_level(level);
|
||||
sup.set_level(level);
|
||||
self.undo();
|
||||
} else if let Some(t) = self.get_type() {
|
||||
t.set_level(level);
|
||||
}
|
||||
}
|
||||
|
||||
fn level(&self) -> Option<Level> {
|
||||
|
@ -694,21 +693,20 @@ impl HasLevel for Free<Type> {
|
|||
|
||||
impl HasLevel for Free<TyParam> {
|
||||
fn set_level(&self, level: Level) {
|
||||
match unsafe { &mut *self.as_ptr() as &mut FreeKind<TyParam> } {
|
||||
match &mut *self.borrow_mut() {
|
||||
FreeKind::Unbound { lev, .. } | FreeKind::NamedUnbound { lev, .. } => {
|
||||
if addr_eq!(*lev, level) {
|
||||
return;
|
||||
}
|
||||
*lev = level;
|
||||
if let Some(t) = self.get_type() {
|
||||
t.set_level(level);
|
||||
}
|
||||
}
|
||||
FreeKind::Linked(t) => {
|
||||
t.set_level(level);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Some(linked) = self.raw_get_linked() {
|
||||
linked.set_level(level);
|
||||
} else if let Some(t) = self.get_type() {
|
||||
t.set_level(level);
|
||||
}
|
||||
}
|
||||
|
||||
fn level(&self) -> Option<Level> {
|
||||
|
@ -860,17 +858,50 @@ impl<T: Clone + fmt::Debug> Free<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_linked(&self) -> Option<T> {
|
||||
match &*self.borrow() {
|
||||
FreeKind::Linked(t) | FreeKind::UndoableLinked { t, .. } => Some(t.clone()),
|
||||
FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => None,
|
||||
pub fn raw_get_linked(&self) -> Option<&T> {
|
||||
if !self.is_linked() {
|
||||
None
|
||||
} else {
|
||||
Some(self.unsafe_crack())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_previous(&self) -> Option<FreeKind<T>> {
|
||||
match &*self.borrow() {
|
||||
FreeKind::UndoableLinked { previous, .. } => Some(*previous.clone()),
|
||||
_other => None,
|
||||
#[track_caller]
|
||||
pub fn get_linked_ref(&self) -> Option<MappedRwLockReadGuard<T>> {
|
||||
if !self.is_linked() {
|
||||
None
|
||||
} else {
|
||||
let mapped = RwLockReadGuard::map(self.borrow(), |f| match f {
|
||||
FreeKind::Linked(t) | FreeKind::UndoableLinked { t, .. } => t,
|
||||
FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => unreachable!(),
|
||||
});
|
||||
Some(mapped)
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn get_linked_refmut(&self) -> Option<MappedRwLockWriteGuard<T>> {
|
||||
if !self.is_linked() {
|
||||
None
|
||||
} else {
|
||||
let mapped = RwLockWriteGuard::map(self.borrow_mut(), |f| match f {
|
||||
FreeKind::Linked(t) | FreeKind::UndoableLinked { t, .. } => t,
|
||||
FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => unreachable!(),
|
||||
});
|
||||
Some(mapped)
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn get_previous(&self) -> Option<MappedRwLockReadGuard<Box<FreeKind<T>>>> {
|
||||
if !self.is_undoable_linked() {
|
||||
None
|
||||
} else {
|
||||
let mapped = RwLockReadGuard::map(self.borrow(), |f| match f {
|
||||
FreeKind::UndoableLinked { previous, .. } => previous,
|
||||
_ => unreachable!(),
|
||||
});
|
||||
Some(mapped)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -933,7 +964,7 @@ impl<T: CanbeFree> Free<T> {
|
|||
|
||||
/// if `in_inst_or_gen` is true, constraint will be updated forcibly
|
||||
pub fn update_constraint(&self, new_constraint: Constraint, in_inst_or_gen: bool) {
|
||||
match unsafe { &mut *self.as_ptr() as &mut FreeKind<T> } {
|
||||
match &mut *self.borrow_mut() {
|
||||
FreeKind::Unbound {
|
||||
lev, constraint, ..
|
||||
}
|
||||
|
@ -979,13 +1010,9 @@ impl Free<TyParam> {
|
|||
where
|
||||
F: Fn(TyParam) -> TyParam,
|
||||
{
|
||||
match unsafe { &mut *self.as_ptr() as &mut FreeKind<TyParam> } {
|
||||
FreeKind::Unbound { .. } | FreeKind::NamedUnbound { .. } => {
|
||||
panic!("the value is unbounded")
|
||||
}
|
||||
FreeKind::Linked(t) | FreeKind::UndoableLinked { t, .. } => {
|
||||
*t = f(mem::take(t));
|
||||
}
|
||||
if let Some(mut linked) = self.get_linked_refmut() {
|
||||
let mapped = f(mem::take(&mut *linked));
|
||||
*linked = mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2570,10 +2570,9 @@ impl Type {
|
|||
|
||||
pub fn self_t(&self) -> Option<&Type> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.self_t()),
|
||||
Self::FreeVar(fv) if fv.is_linked() => {
|
||||
fv.forced_as_ref().linked().and_then(|t| t.self_t())
|
||||
}
|
||||
Self::Refinement(refine) => refine.t.self_t(),
|
||||
Self::Subr(subr) => subr.self_t(),
|
||||
Self::Quantified(quant) => quant.self_t(),
|
||||
|
@ -2583,8 +2582,8 @@ impl Type {
|
|||
|
||||
pub fn non_default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv
|
||||
.forced_as_ref()
|
||||
.linked()
|
||||
.and_then(|t| t.non_default_params()),
|
||||
Self::Refinement(refine) => refine.t.non_default_params(),
|
||||
|
@ -2599,10 +2598,9 @@ impl Type {
|
|||
|
||||
pub fn var_params(&self) -> Option<&ParamTy> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.var_params()),
|
||||
Self::FreeVar(fv) if fv.is_linked() => {
|
||||
fv.forced_as_ref().linked().and_then(|t| t.var_params())
|
||||
}
|
||||
Self::Refinement(refine) => refine.t.var_params(),
|
||||
Self::Subr(SubrType {
|
||||
var_params: var_args,
|
||||
|
@ -2616,10 +2614,9 @@ impl Type {
|
|||
|
||||
pub fn default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.default_params()),
|
||||
Self::FreeVar(fv) if fv.is_linked() => {
|
||||
fv.forced_as_ref().linked().and_then(|t| t.default_params())
|
||||
}
|
||||
Self::Refinement(refine) => refine.t.default_params(),
|
||||
Self::Subr(SubrType { default_params, .. }) => Some(default_params),
|
||||
Self::Quantified(quant) => quant.default_params(),
|
||||
|
@ -2629,10 +2626,9 @@ impl Type {
|
|||
|
||||
pub fn non_var_params(&self) -> Option<impl Iterator<Item = &ParamTy> + Clone> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.non_var_params()),
|
||||
Self::FreeVar(fv) if fv.is_linked() => {
|
||||
fv.forced_as_ref().linked().and_then(|t| t.non_var_params())
|
||||
}
|
||||
Self::Refinement(refine) => refine.t.non_var_params(),
|
||||
Self::Subr(subr) => Some(subr.non_var_params()),
|
||||
Self::Quantified(quant) => quant.non_var_params(),
|
||||
|
@ -2642,10 +2638,9 @@ impl Type {
|
|||
|
||||
pub fn return_t(&self) -> Option<&Type> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.return_t()),
|
||||
Self::FreeVar(fv) if fv.is_linked() => {
|
||||
fv.forced_as_ref().linked().and_then(|t| t.return_t())
|
||||
}
|
||||
Self::Refinement(refine) => refine.t.return_t(),
|
||||
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
||||
Some(return_t)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue