mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 12:51:10 +00:00
Fix an Erg standard library loading bug
This commit is contained in:
parent
a460b431a3
commit
a395938413
7 changed files with 68 additions and 47 deletions
|
@ -64,8 +64,8 @@ impl From<Str> for String {
|
|||
impl<'a> From<Str> for Cow<'a, str> {
|
||||
fn from(s: Str) -> Self {
|
||||
match s {
|
||||
Str::Static(s) => Cow::Owned(s.to_owned()),
|
||||
_ => unreachable!(),
|
||||
Str::Static(s) => Cow::Borrowed(s),
|
||||
Str::Rc(s) => Cow::Owned(s.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
use std::option::Option; // conflicting to Type::Option
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use erg_common::config::Input;
|
||||
use erg_common::env::erg_pystd_path;
|
||||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::env::{erg_pystd_path, erg_std_path};
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||
use erg_common::levenshtein::get_similar_name;
|
||||
use erg_common::set::Set;
|
||||
|
@ -1736,7 +1736,7 @@ impl Context {
|
|||
}
|
||||
let type_name = namespaces.pop().unwrap(); // Response
|
||||
let path = Path::new(namespaces.remove(0));
|
||||
let mut path = self.resolve_path(path);
|
||||
let mut path = Self::resolve_path(&self.cfg, path)?;
|
||||
for p in namespaces.into_iter() {
|
||||
path = self.push_path(path, Path::new(p));
|
||||
}
|
||||
|
@ -1766,7 +1766,7 @@ impl Context {
|
|||
}
|
||||
let type_name = namespaces.pop().unwrap(); // Response
|
||||
let path = Path::new(namespaces.remove(0));
|
||||
let mut path = self.resolve_path(path);
|
||||
let mut path = Self::resolve_path(&self.cfg, path)?;
|
||||
for p in namespaces.into_iter() {
|
||||
path = self.push_path(path, Path::new(p));
|
||||
}
|
||||
|
@ -1925,23 +1925,45 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: erg std
|
||||
pub(crate) fn resolve_path(&self, path: &Path) -> PathBuf {
|
||||
if let Ok(path) = self.cfg.input.local_resolve(path) {
|
||||
path
|
||||
pub(crate) fn resolve_path(cfg: &ErgConfig, path: &Path) -> Option<PathBuf> {
|
||||
Self::resolve_real_path(cfg, path).or_else(|| Self::resolve_d_path(cfg, path))
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_real_path(cfg: &ErgConfig, path: &Path) -> Option<PathBuf> {
|
||||
if let Ok(path) = cfg.input.local_resolve(path) {
|
||||
Some(path)
|
||||
} else if let Ok(path) = erg_std_path()
|
||||
.join(format!("{}.er", path.display()))
|
||||
.canonicalize()
|
||||
{
|
||||
Some(path)
|
||||
} else if let Ok(path) = erg_std_path()
|
||||
.join(format!("{}", path.display()))
|
||||
.join("__init__.er")
|
||||
.canonicalize()
|
||||
{
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_d_path(cfg: &ErgConfig, path: &Path) -> Option<PathBuf> {
|
||||
if let Ok(path) = cfg.input.local_resolve(path) {
|
||||
Some(path)
|
||||
} else if let Ok(path) = erg_pystd_path()
|
||||
.join(format!("{}.d.er", path.display()))
|
||||
.canonicalize()
|
||||
{
|
||||
path
|
||||
Some(path)
|
||||
} else if let Ok(path) = erg_pystd_path()
|
||||
.join(format!("{}.d", path.display()))
|
||||
.join("__init__.d.er")
|
||||
.canonicalize()
|
||||
{
|
||||
path
|
||||
Some(path)
|
||||
} else {
|
||||
PathBuf::from(format!("<builtins>.{}", path.display()))
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1968,7 +1990,7 @@ impl Context {
|
|||
if t.is_module() {
|
||||
let path =
|
||||
option_enum_unwrap!(t.typarams().remove(0), TyParam::Value:(ValueObj::Str:(_)))?;
|
||||
let path = self.resolve_path(Path::new(&path[..]));
|
||||
let path = Self::resolve_path(&self.cfg, Path::new(&path[..]))?;
|
||||
self.mod_cache
|
||||
.as_ref()
|
||||
.and_then(|cache| cache.ref_ctx(&path))
|
||||
|
|
|
@ -1008,6 +1008,12 @@ impl Context {
|
|||
self.params.retain(|(_, v)| v.t != Failure);
|
||||
}
|
||||
|
||||
pub(crate) fn clear_all_vars(&mut self) {
|
||||
self.locals.clear();
|
||||
self.decls.clear();
|
||||
self.params.retain(|(_, v)| v.t != Failure);
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Context {
|
||||
if let Some(parent) = self.outer.as_mut() {
|
||||
let parent = mem::take(parent);
|
||||
|
|
|
@ -1168,22 +1168,18 @@ impl Context {
|
|||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
||||
let mod_cache = self.mod_cache.as_ref().unwrap();
|
||||
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||
let path = match self.cfg.input.local_resolve(Path::new(&__name__[..])) {
|
||||
Ok(path) => path,
|
||||
Err(err) => {
|
||||
let path = match Self::resolve_real_path(&self.cfg, Path::new(&__name__[..])) {
|
||||
Some(path) => path,
|
||||
None => {
|
||||
let err = TyCheckErrors::from(TyCheckError::import_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
err.to_string(),
|
||||
format!("module {__name__} not found"),
|
||||
mod_name.loc(),
|
||||
self.caused_by(),
|
||||
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
|
||||
self.similar_builtin_py_mod_name(&__name__).or_else(|| {
|
||||
self.py_mod_cache
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get_similar_name(&__name__)
|
||||
}),
|
||||
self.similar_builtin_py_mod_name(&__name__)
|
||||
.or_else(|| py_mod_cache.get_similar_name(&__name__)),
|
||||
));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -1250,9 +1246,8 @@ impl Context {
|
|||
let __name__ = enum_unwrap!(mod_name.value.clone(), ValueObj::Str);
|
||||
let mod_cache = self.mod_cache.as_ref().unwrap();
|
||||
let py_mod_cache = self.py_mod_cache.as_ref().unwrap();
|
||||
let path = self.resolve_path(Path::new(&__name__[..]));
|
||||
let path = match path.canonicalize() {
|
||||
Ok(path) => {
|
||||
let path = match Self::resolve_d_path(&self.cfg, Path::new(&__name__[..])) {
|
||||
Some(path) => {
|
||||
if self.is_pystd_main_module(path.as_path())
|
||||
&& !BUILTIN_PYTHON_MODS.contains(&&__name__[..])
|
||||
{
|
||||
|
@ -1267,11 +1262,11 @@ impl Context {
|
|||
}
|
||||
path
|
||||
}
|
||||
Err(err) => {
|
||||
None => {
|
||||
let err = TyCheckError::import_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
err.to_string(),
|
||||
format!("module {__name__} not found"),
|
||||
mod_name.loc(),
|
||||
self.caused_by(),
|
||||
self.mod_cache.as_ref().unwrap().get_similar_name(&__name__),
|
||||
|
|
|
@ -10,6 +10,7 @@ use erg_common::{enum_unwrap, log};
|
|||
use erg_parser::ast::{DefId, OperationKind};
|
||||
use erg_parser::token::{Token, TokenKind, DOT, EQUAL};
|
||||
|
||||
use crate::context::Context;
|
||||
use crate::ty::typaram::TyParam;
|
||||
use crate::ty::value::ValueObj;
|
||||
use crate::ty::HasType;
|
||||
|
@ -297,7 +298,7 @@ impl<'a> Linker<'a> {
|
|||
let path =
|
||||
enum_unwrap!(expr.ref_t().typarams().remove(0), TyParam::Value:(ValueObj::Str:(_)));
|
||||
let path = Path::new(&path[..]);
|
||||
let path = self.cfg.input.local_resolve(path).unwrap();
|
||||
let path = Context::resolve_real_path(self.cfg, path).unwrap();
|
||||
// In the case of REPL, entries cannot be used up
|
||||
let hir = if self.cfg.input.is_repl() {
|
||||
self.mod_cache
|
||||
|
|
|
@ -2051,6 +2051,15 @@ impl ASTLowerer {
|
|||
HIR::new(ast.name, module)
|
||||
}
|
||||
|
||||
fn return_incomplete_artifact(&mut self, hir: HIR) -> IncompleteArtifact {
|
||||
self.ctx.clear_all_vars();
|
||||
IncompleteArtifact::new(
|
||||
Some(hir),
|
||||
LowerErrors::from(self.errs.take_all()),
|
||||
LowerWarnings::from(self.warns.take_all()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn lower(&mut self, ast: AST, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||
log!(info "the AST lowering process has started.");
|
||||
log!(info "the type-checking process has started.");
|
||||
|
@ -2070,11 +2079,7 @@ impl ASTLowerer {
|
|||
));
|
||||
} else {
|
||||
log!(err "the declaring process has failed.");
|
||||
return Err(IncompleteArtifact::new(
|
||||
Some(hir),
|
||||
LowerErrors::from(self.errs.take_all()),
|
||||
LowerWarnings::from(self.warns.take_all()),
|
||||
));
|
||||
return Err(self.return_incomplete_artifact(hir));
|
||||
}
|
||||
}
|
||||
let mut module = hir::Module::with_capacity(ast.module.len());
|
||||
|
@ -2105,11 +2110,7 @@ impl ASTLowerer {
|
|||
Err((hir, errs)) => {
|
||||
self.errs.extend(errs);
|
||||
log!(err "the resolving process has failed. errs: {}", self.errs.len());
|
||||
return Err(IncompleteArtifact::new(
|
||||
Some(hir),
|
||||
LowerErrors::from(self.errs.take_all()),
|
||||
LowerWarnings::from(self.warns.take_all()),
|
||||
));
|
||||
return Err(self.return_incomplete_artifact(hir));
|
||||
}
|
||||
};
|
||||
// TODO: recursive check
|
||||
|
@ -2126,11 +2127,7 @@ impl ASTLowerer {
|
|||
))
|
||||
} else {
|
||||
log!(err "the AST lowering process has failed. errs: {}", self.errs.len());
|
||||
Err(IncompleteArtifact::new(
|
||||
Some(hir),
|
||||
LowerErrors::from(self.errs.take_all()),
|
||||
LowerWarnings::from(self.warns.take_all()),
|
||||
))
|
||||
Err(self.return_incomplete_artifact(hir))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue