mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-01 05:11:09 +00:00
Fixed to register <builtins>
to mod_cache
This commit is contained in:
parent
f815a7df7b
commit
6f3f00a369
13 changed files with 133 additions and 83 deletions
|
@ -1,4 +1,4 @@
|
|||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::traits::{Runnable, Stream};
|
||||
|
||||
use erg_parser::ast::VarName;
|
||||
|
@ -31,25 +31,9 @@ impl HIRBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn build_and_cache(&mut self, var_name: VarName) -> Result<(), CompileErrors> {
|
||||
pub fn build_and_cache(&mut self, var_name: VarName, mode: &str) -> Result<(), CompileErrors> {
|
||||
let mut ast_builder = ASTBuilder::new(self.checker.cfg().copy());
|
||||
let ast = ast_builder.build()?;
|
||||
let ast = Reorderer::new()
|
||||
.reorder(ast)
|
||||
.map_err(|errs| self.convert(errs))?;
|
||||
let (hir, ctx) = self
|
||||
.checker
|
||||
.check(ast, "exec")
|
||||
.map_err(|errs| self.convert(errs))?;
|
||||
self.mod_cache.register(var_name, Some(hir), ctx);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build_and_cache_main(&mut self, src: String, mode: &str) -> Result<(), CompileErrors> {
|
||||
let mut cfg = self.checker.cfg().copy();
|
||||
cfg.input = Input::Str(src);
|
||||
let mut ast_builder = ASTBuilder::new(cfg);
|
||||
let ast = ast_builder.build()?;
|
||||
let ast = Reorderer::new()
|
||||
.reorder(ast)
|
||||
.map_err(|errs| self.convert(errs))?;
|
||||
|
@ -57,8 +41,7 @@ impl HIRBuilder {
|
|||
.checker
|
||||
.check(ast, mode)
|
||||
.map_err(|errs| self.convert(errs))?;
|
||||
let name = VarName::from_static("<module>");
|
||||
self.mod_cache.register(name, Some(hir), ctx);
|
||||
self.mod_cache.register(var_name, Some(hir), ctx);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use erg_common::config::ErgConfig;
|
||||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::error::MultiErrorDisplay;
|
||||
use erg_common::traits::Runnable;
|
||||
|
||||
|
@ -48,8 +48,12 @@ impl Runnable for Checker {
|
|||
}
|
||||
|
||||
fn eval(&mut self, src: String) -> Result<String, TyCheckErrors> {
|
||||
let mut builder = ASTBuilder::new(self.cfg().copy());
|
||||
let ast = builder.build_with_str(src)?;
|
||||
let cfg = ErgConfig {
|
||||
input: Input::Str(src),
|
||||
..self.cfg().copy()
|
||||
};
|
||||
let mut builder = ASTBuilder::new(cfg);
|
||||
let ast = builder.build()?;
|
||||
let (hir, _) = self.check(ast, "eval")?;
|
||||
Ok(hir.to_string())
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
//! コンパイラーを定義する
|
||||
use std::path::Path;
|
||||
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::log;
|
||||
use erg_common::traits::{Runnable, Stream};
|
||||
use erg_parser::ast::VarName;
|
||||
use erg_type::codeobj::CodeObj;
|
||||
|
||||
use crate::builder::HIRBuilder;
|
||||
|
@ -148,8 +149,12 @@ impl Compiler {
|
|||
|
||||
pub fn compile(&mut self, src: String, mode: &str) -> Result<CodeObj, CompileErrors> {
|
||||
log!(info "the compiling process has started.");
|
||||
let mut hir_builder = HIRBuilder::new(self.cfg.copy(), self.mod_cache.clone());
|
||||
hir_builder.build_and_cache_main(src, mode)?;
|
||||
let cfg = ErgConfig {
|
||||
input: Input::Str(src),
|
||||
..self.cfg.copy()
|
||||
};
|
||||
let mut hir_builder = HIRBuilder::new(cfg, self.mod_cache.clone());
|
||||
hir_builder.build_and_cache(VarName::from_static("<module>"), mode)?;
|
||||
let hir = Linker::link(self.mod_cache.clone());
|
||||
let codeobj = self.code_generator.emit(hir);
|
||||
log!(info "code object:\n{}", codeobj.code_info());
|
||||
|
|
|
@ -1770,7 +1770,7 @@ impl Context {
|
|||
// ord.register_impl("__ge__", op_t, Const, Public);
|
||||
}
|
||||
|
||||
pub(crate) fn init_builtins() -> Self {
|
||||
pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) {
|
||||
// TODO: capacityを正確に把握する
|
||||
let mut ctx = Context::module("<builtins>".into(), None, 40);
|
||||
ctx.init_builtin_funcs();
|
||||
|
@ -1780,15 +1780,15 @@ impl Context {
|
|||
ctx.init_builtin_traits();
|
||||
ctx.init_builtin_classes();
|
||||
ctx.init_builtin_patches();
|
||||
ctx
|
||||
mod_cache.register(VarName::from_static("<builtins>"), None, ctx);
|
||||
}
|
||||
|
||||
pub fn new_main_module(mod_cache: SharedModuleCache) -> Self {
|
||||
pub fn new_module(mod_cache: SharedModuleCache) -> Self {
|
||||
Context::new(
|
||||
"<module>".into(),
|
||||
"<module>".into(), // TODO:
|
||||
ContextKind::Module,
|
||||
vec![],
|
||||
Some(Context::init_builtins()),
|
||||
None,
|
||||
Some(mod_cache),
|
||||
Context::TOP_LEVEL,
|
||||
)
|
||||
|
|
|
@ -206,7 +206,7 @@ impl Context {
|
|||
self.validate_visibility(ident, vi, namespace)?;
|
||||
Ok(vi.t())
|
||||
} else {
|
||||
if let Some(parent) = self.outer.as_ref() {
|
||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
return parent.rec_get_var_t(ident, namespace);
|
||||
}
|
||||
Err(TyCheckError::no_var_error(
|
||||
|
@ -267,7 +267,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
// TODO: dependent type widening
|
||||
if let Some(parent) = self.outer.as_ref() {
|
||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
parent.rec_get_attr_t(obj, ident, namespace)
|
||||
} else {
|
||||
Err(TyCheckError::no_attr_error(
|
||||
|
@ -849,7 +849,7 @@ impl Context {
|
|||
if let Some(obj) = self.consts.get(name.inspect()) {
|
||||
Ok(obj.clone())
|
||||
} else {
|
||||
if let Some(parent) = self.outer.as_ref() {
|
||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
return parent.get_const_local(name, namespace);
|
||||
}
|
||||
Err(TyCheckError::no_var_error(
|
||||
|
@ -883,7 +883,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
// TODO: dependent type widening
|
||||
if let Some(parent) = self.outer.as_ref() {
|
||||
if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
parent._get_const_attr(obj, name, namespace)
|
||||
} else {
|
||||
Err(TyCheckError::no_attr_error(
|
||||
|
@ -912,7 +912,7 @@ impl Context {
|
|||
.inspect();
|
||||
let len = most_similar_name.len();
|
||||
if levenshtein(most_similar_name, name) >= len / 2 {
|
||||
let outer = self.outer.as_ref()?;
|
||||
let outer = self.get_outer().or_else(|| self.get_builtins())?;
|
||||
outer.get_similar_name(name)
|
||||
} else {
|
||||
Some(most_similar_name)
|
||||
|
@ -1209,7 +1209,7 @@ impl Context {
|
|||
} else {
|
||||
vec![]
|
||||
};
|
||||
if let Some(outer) = &self.outer {
|
||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
[current, outer.rec_get_trait_impls(name)].concat()
|
||||
} else {
|
||||
current
|
||||
|
@ -1219,7 +1219,7 @@ impl Context {
|
|||
pub(crate) fn _rec_get_patch(&self, name: &VarName) -> Option<&Context> {
|
||||
if let Some(patch) = self.patches.get(name) {
|
||||
Some(patch)
|
||||
} else if let Some(outer) = &self.outer {
|
||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer._rec_get_patch(name)
|
||||
} else {
|
||||
None
|
||||
|
@ -1243,7 +1243,7 @@ impl Context {
|
|||
return Some(val);
|
||||
}
|
||||
}
|
||||
if let Some(outer) = &self.outer {
|
||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.rec_get_const_obj(name)
|
||||
} else {
|
||||
None
|
||||
|
@ -1253,7 +1253,7 @@ impl Context {
|
|||
pub(crate) fn rec_get_const_param_defaults(&self, name: &str) -> Option<&Vec<ConstTemplate>> {
|
||||
if let Some(impls) = self.const_param_defaults.get(name) {
|
||||
Some(impls)
|
||||
} else if let Some(outer) = &self.outer {
|
||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.rec_get_const_param_defaults(name)
|
||||
} else {
|
||||
None
|
||||
|
@ -1271,7 +1271,7 @@ impl Context {
|
|||
} else {
|
||||
None
|
||||
}
|
||||
} else if let Some(outer) = &self.outer {
|
||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.rec_get_self_t()
|
||||
} else {
|
||||
None
|
||||
|
@ -1281,7 +1281,7 @@ impl Context {
|
|||
fn rec_get_mono_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
||||
if let Some((t, ctx)) = self.mono_types.get(name) {
|
||||
Some((t, ctx))
|
||||
} else if let Some(outer) = &self.outer {
|
||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.rec_get_mono_type(name)
|
||||
} else {
|
||||
None
|
||||
|
@ -1291,7 +1291,7 @@ impl Context {
|
|||
fn rec_get_poly_type(&self, name: &str) -> Option<(&Type, &Context)> {
|
||||
if let Some((t, ctx)) = self.poly_types.get(name) {
|
||||
Some((t, ctx))
|
||||
} else if let Some(outer) = &self.outer {
|
||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.rec_get_poly_type(name)
|
||||
} else {
|
||||
None
|
||||
|
@ -1302,6 +1302,7 @@ impl Context {
|
|||
if let Some((t, ctx)) = self.mono_types.get_mut(name) {
|
||||
Some((t, ctx))
|
||||
} else if let Some(outer) = self.outer.as_mut() {
|
||||
// builtins cannot be got as mutable
|
||||
outer.rec_get_mut_mono_type(name)
|
||||
} else {
|
||||
None
|
||||
|
@ -1323,7 +1324,7 @@ impl Context {
|
|||
Some((t, ctx))
|
||||
} else if let Some((t, ctx)) = self.poly_types.get(name) {
|
||||
Some((t, ctx))
|
||||
} else if let Some(outer) = &self.outer {
|
||||
} else if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.rec_get_type(name)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -19,7 +19,6 @@ use std::option::Option; // conflicting to Type::Option
|
|||
|
||||
use erg_common::astr::AtomicStr;
|
||||
use erg_common::dict::Dict;
|
||||
use erg_common::error::Location;
|
||||
use erg_common::impl_display_from_debug;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
use erg_common::vis::Visibility;
|
||||
|
@ -554,6 +553,23 @@ impl Context {
|
|||
AtomicStr::arc(&self.name[..])
|
||||
}
|
||||
|
||||
pub(crate) fn get_outer(&self) -> Option<&Context> {
|
||||
self.outer.as_ref().map(|x| x.as_ref())
|
||||
}
|
||||
|
||||
/// Returns None if self is `<builtins>`.
|
||||
/// This avoids infinite loops.
|
||||
pub(crate) fn get_builtins(&self) -> Option<&Context> {
|
||||
// builtins中で定義した型等はmod_cacheがNoneになっている
|
||||
if &self.name[..] != "<builtins>" {
|
||||
self.mod_cache
|
||||
.as_ref()
|
||||
.map(|cache| cache.ref_ctx("<builtins>").unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn grow(
|
||||
&mut self,
|
||||
name: &str,
|
||||
|
@ -567,7 +583,7 @@ impl Context {
|
|||
};
|
||||
log!(info "{}: current namespace: {name}", fn_name!());
|
||||
self.outer = Some(Box::new(mem::take(self)));
|
||||
self.mod_cache = self.outer.as_ref().unwrap().mod_cache.clone();
|
||||
self.mod_cache = self.get_outer().unwrap().mod_cache.clone();
|
||||
self.name = name.into();
|
||||
self.kind = kind;
|
||||
Ok(())
|
||||
|
@ -584,7 +600,7 @@ impl Context {
|
|||
&vi.t,
|
||||
));
|
||||
}
|
||||
if let Some(parent) = &mut self.outer {
|
||||
if let Some(parent) = self.outer.as_mut() {
|
||||
let parent = mem::take(parent);
|
||||
let ctx = mem::take(self);
|
||||
*self = *parent;
|
||||
|
@ -595,12 +611,14 @@ impl Context {
|
|||
Ok(ctx)
|
||||
}
|
||||
} else {
|
||||
Err(TyCheckErrors::from(TyCheckError::checker_bug(
|
||||
0,
|
||||
Location::Unknown,
|
||||
fn_name!(),
|
||||
line!(),
|
||||
)))
|
||||
// toplevel
|
||||
let ctx = mem::take(self);
|
||||
log!(info "{}: current namespace: {}", fn_name!(), self.name);
|
||||
if !uninited_errs.is_empty() {
|
||||
Err(uninited_errs)
|
||||
} else {
|
||||
Ok(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ impl Context {
|
|||
return Some((name, vi));
|
||||
}
|
||||
if is_const {
|
||||
if let Some(outer) = &self.outer {
|
||||
if let Some(outer) = self.get_outer().or_else(|| self.get_builtins()) {
|
||||
outer.registered_info(name, is_const)
|
||||
} else {
|
||||
None
|
||||
|
@ -871,7 +871,7 @@ impl Context {
|
|||
..ErgConfig::default()
|
||||
};
|
||||
let mut hir_builder = HIRBuilder::new(cfg, mod_cache.clone());
|
||||
if let Err(errs) = hir_builder.build_and_cache(var_name.clone()) {
|
||||
if let Err(errs) = hir_builder.build_and_cache(var_name.clone(), "exec") {
|
||||
errs.fmt_all_stderr();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//! ASTLowerer(ASTからHIRへの変換器)を実装
|
||||
|
||||
use erg_common::astr::AtomicStr;
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::error::{Location, MultiErrorDisplay};
|
||||
use erg_common::set::Set;
|
||||
use erg_common::traits::{Locational, Runnable, Stream};
|
||||
|
@ -81,8 +81,12 @@ impl Runnable for ASTLowerer {
|
|||
}
|
||||
|
||||
fn eval(&mut self, src: String) -> Result<String, CompileErrors> {
|
||||
let mut ast_builder = ASTBuilder::new(self.cfg.copy());
|
||||
let ast = ast_builder.build_with_str(src)?;
|
||||
let cfg = ErgConfig {
|
||||
input: Input::Str(src),
|
||||
..self.cfg.copy()
|
||||
};
|
||||
let mut ast_builder = ASTBuilder::new(cfg);
|
||||
let ast = ast_builder.build()?;
|
||||
let (hir, ..) = self.lower(ast, "eval").map_err(|errs| self.convert(errs))?;
|
||||
Ok(format!("{hir}"))
|
||||
}
|
||||
|
@ -92,7 +96,7 @@ impl ASTLowerer {
|
|||
pub fn new_with_cache(cfg: ErgConfig, mod_cache: SharedModuleCache) -> Self {
|
||||
Self {
|
||||
cfg,
|
||||
ctx: Context::new_main_module(mod_cache),
|
||||
ctx: Context::new_module(mod_cache),
|
||||
errs: LowerErrors::empty(),
|
||||
warns: LowerWarnings::empty(),
|
||||
}
|
||||
|
|
|
@ -128,7 +128,9 @@ impl fmt::Display for SharedModuleCache {
|
|||
|
||||
impl SharedModuleCache {
|
||||
pub fn new() -> Self {
|
||||
Self(Shared::new(ModuleCache::new()))
|
||||
let self_ = Self(Shared::new(ModuleCache::new()));
|
||||
Context::init_builtins(&self_);
|
||||
self_
|
||||
}
|
||||
|
||||
pub fn get_ctx<Q: Eq + Hash + ?Sized>(&self, name: &Q) -> Option<Rc<Context>>
|
||||
|
|
|
@ -3,14 +3,14 @@ use erg_compiler::mod_cache::SharedModuleCache;
|
|||
|
||||
#[test]
|
||||
fn test_subtyping() -> Result<(), ()> {
|
||||
let context = Context::new_main_module(SharedModuleCache::new());
|
||||
let context = Context::new_module(SharedModuleCache::new());
|
||||
context.test_refinement_subtyping()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_instantiation_and_generalization() -> Result<(), ()> {
|
||||
let context = Context::new_main_module(SharedModuleCache::new());
|
||||
let context = Context::new_module(SharedModuleCache::new());
|
||||
context.test_instantiation_and_generalization()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -25,17 +25,7 @@ impl ASTBuilder {
|
|||
let module = desugarer.desugar(module);
|
||||
let mut desugarer = Desugarer::new();
|
||||
let module = desugarer.desugar(module);
|
||||
let ast = AST::new(Str::ever(self.runner.cfg().module), module);
|
||||
Ok(ast)
|
||||
}
|
||||
|
||||
pub fn build_with_str(&mut self, src: String) -> Result<AST, ParserRunnerErrors> {
|
||||
let module = self.runner.parse_with_str(src)?;
|
||||
let mut desugarer = Desugarer::new();
|
||||
let module = desugarer.desugar(module);
|
||||
let mut desugarer = Desugarer::new();
|
||||
let module = desugarer.desugar(module);
|
||||
let ast = AST::new(Str::ever(self.runner.cfg().module), module);
|
||||
let ast = AST::new(Str::rc(self.runner.cfg().input.filename()), module);
|
||||
Ok(ast)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -337,6 +337,20 @@ impl<T> FreeKind<T> {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn linked(&self) -> Option<&T> {
|
||||
match self {
|
||||
Self::Linked(typ) => Some(typ),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linked_mut(&mut self) -> Option<&mut T> {
|
||||
match self {
|
||||
Self::Linked(typ) => Some(typ),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
|
@ -1104,6 +1104,10 @@ pub enum Type {
|
|||
Ellipsis, // これはクラスのほうで型推論用のマーカーではない
|
||||
Never, // {}
|
||||
Mono(Str),
|
||||
ForeignMono {
|
||||
path: Str,
|
||||
name: Str,
|
||||
},
|
||||
/* Polymorphic types */
|
||||
Ref(Box<Type>),
|
||||
RefMut {
|
||||
|
@ -1174,6 +1178,10 @@ impl PartialEq for Type {
|
|||
| (Self::Ellipsis, Self::Ellipsis)
|
||||
| (Self::Never, Self::Never) => true,
|
||||
(Self::Mono(l), Self::Mono(r)) => l == r,
|
||||
(
|
||||
Self::ForeignMono { path: lp, name: ln },
|
||||
Self::ForeignMono { path: rp, name: rn },
|
||||
) => lp == rp && ln == rn,
|
||||
(Self::MonoQVar(l), Self::MonoQVar(r)) => l == r,
|
||||
(Self::Ref(l), Self::Ref(r)) => l == r,
|
||||
(
|
||||
|
@ -1269,6 +1277,7 @@ impl LimitedDisplay for Type {
|
|||
}
|
||||
match self {
|
||||
Self::Mono(name) => write!(f, "{name}"),
|
||||
Self::ForeignMono { path, name } => write!(f, "{name}(of {path})"),
|
||||
Self::Ref(t) => {
|
||||
write!(f, "{}(", self.name())?;
|
||||
t.limited_fmt(f, limit - 1)?;
|
||||
|
@ -1758,7 +1767,9 @@ impl Type {
|
|||
Self::Error => Str::ever("Error"),
|
||||
Self::Inf => Str::ever("Inf"),
|
||||
Self::NegInf => Str::ever("NegInf"),
|
||||
Self::Mono(name) | Self::MonoQVar(name) => name.clone(),
|
||||
Self::Mono(name) | Self::MonoQVar(name) | Self::ForeignMono { name, .. } => {
|
||||
name.clone()
|
||||
}
|
||||
Self::And(_, _) => Str::ever("And"),
|
||||
Self::Not(_, _) => Str::ever("Not"),
|
||||
Self::Or(_, _) => Str::ever("Or"),
|
||||
|
@ -1991,16 +2002,22 @@ impl Type {
|
|||
|
||||
pub fn self_t(&self) -> Option<&Type> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => todo!("linked: {fv}"),
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.self_t()),
|
||||
Self::Refinement(refine) => refine.t.self_t(),
|
||||
Self::Subr(subr) => subr.self_t(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn non_default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
pub fn non_default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
match self {
|
||||
Self::FreeVar(_) => panic!("fv"),
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.non_default_params()),
|
||||
Self::Refinement(refine) => refine.t.non_default_params(),
|
||||
Self::Subr(SubrType {
|
||||
non_default_params, ..
|
||||
|
@ -2012,7 +2029,10 @@ impl Type {
|
|||
|
||||
pub fn var_args(&self) -> Option<&ParamTy> {
|
||||
match self {
|
||||
Self::FreeVar(_) => panic!("fv"),
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.var_args()),
|
||||
Self::Refinement(refine) => refine.t.var_args(),
|
||||
Self::Subr(SubrType {
|
||||
var_params: var_args,
|
||||
|
@ -2023,18 +2043,24 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
pub fn default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
match self {
|
||||
Self::FreeVar(_) => panic!("fv"),
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.linked()
|
||||
.and_then(|t| t.default_params()),
|
||||
Self::Refinement(refine) => refine.t.default_params(),
|
||||
Self::Subr(SubrType { default_params, .. }) => Some(default_params),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn return_t(&self) -> Option<&Type> {
|
||||
pub fn return_t(&self) -> Option<&Type> {
|
||||
match self {
|
||||
Self::FreeVar(_) => panic!("fv"),
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_ref() }
|
||||
.unwrap()
|
||||
.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)
|
||||
|
@ -2045,7 +2071,10 @@ impl Type {
|
|||
|
||||
pub fn mut_return_t(&mut self) -> Option<&mut Type> {
|
||||
match self {
|
||||
Self::FreeVar(_) => panic!("fv"),
|
||||
Self::FreeVar(fv) if fv.is_linked() => unsafe { fv.as_ptr().as_mut() }
|
||||
.unwrap()
|
||||
.linked_mut()
|
||||
.and_then(|t| t.mut_return_t()),
|
||||
Self::Refinement(refine) => refine.t.mut_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