merge from main

This commit is contained in:
Shunsuke Shibayama 2023-05-28 10:01:00 +09:00
commit 980be54590
17 changed files with 197 additions and 139 deletions

View file

@ -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

View file

@ -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()))

View file

@ -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)
}

View file

@ -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()
}

View file

@ -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 => {

View file

@ -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()

View file

@ -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したモジュールはどこからでも見れる

View file

@ -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

View file

@ -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(

View file

@ -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 =

View file

@ -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(

View file

@ -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)
}
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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;
}
}
}

View file

@ -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)