diff --git a/Cargo.lock b/Cargo.lock index 792f8a446..c3084d24c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,9 +57,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "hermit-abi" @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "libc" @@ -244,9 +244,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.2" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8c786513eb403643f2a88c244c2aaa270ef2153f55094587d0c48a3cf22a83" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] @@ -288,9 +288,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", @@ -307,9 +307,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -340,9 +340,9 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "scopeguard" @@ -372,9 +372,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", @@ -394,9 +394,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -415,9 +415,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -430,9 +430,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -450,21 +450,21 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7" [[package]] name = "unicode-normalization" @@ -523,9 +523,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", diff --git a/crates/els/hir_visitor.rs b/crates/els/hir_visitor.rs index 35c756510..395933cba 100644 --- a/crates/els/hir_visitor.rs +++ b/crates/els/hir_visitor.rs @@ -200,9 +200,9 @@ impl<'a> HIRVisitor<'a> { token: &Token, ) -> Option<&Expr> { match acc { - Accessor::Ident(ident) => self.return_expr_if_same(expr, ident.name.token(), token), + Accessor::Ident(ident) => self.return_expr_if_same(expr, ident.raw.name.token(), token), Accessor::Attr(attr) => self - .return_expr_if_same(expr, attr.ident.name.token(), token) + .return_expr_if_same(expr, attr.ident.raw.name.token(), token) .or_else(|| self.get_expr(&attr.obj, token)), } } @@ -234,7 +234,7 @@ impl<'a> HIRVisitor<'a> { .or_else(|| { call.attr_name .as_ref() - .and_then(|attr| self.return_expr_if_same(expr, attr.name.token(), token)) + .and_then(|attr| self.return_expr_if_same(expr, attr.raw.name.token(), token)) }) .or_else(|| self.get_expr(&call.obj, token)) .or_else(|| self.get_expr_from_args(&call.args, token)) @@ -266,7 +266,7 @@ impl<'a> HIRVisitor<'a> { def: &'e Def, token: &Token, ) -> Option<&Expr> { - self.return_expr_if_same(expr, def.sig.ident().name.token(), token) + self.return_expr_if_same(expr, def.sig.ident().raw.name.token(), token) .or_else(|| self.get_expr_from_block(&def.body.block, token)) .or_else(|| def.loc().contains(token.loc()).then_some(expr)) } @@ -319,7 +319,7 @@ impl<'a> HIRVisitor<'a> { patch_def: &'e PatchDef, token: &Token, ) -> Option<&Expr> { - self.return_expr_if_same(expr, patch_def.sig.ident().name.token(), token) + self.return_expr_if_same(expr, patch_def.sig.name().token(), token) .or_else(|| self.get_expr(&patch_def.base, token)) .or_else(|| self.get_expr_from_block(&patch_def.methods, token)) .or_else(|| patch_def.loc().contains(token.loc()).then_some(expr)) @@ -489,10 +489,10 @@ impl<'a> HIRVisitor<'a> { fn get_acc_info(&self, acc: &Accessor, token: &Token) -> Option { match acc { Accessor::Ident(ident) => { - self.return_var_info_if_same(ident, ident.name.token(), token) + self.return_var_info_if_same(ident, ident.raw.name.token(), token) } Accessor::Attr(attr) => self - .return_var_info_if_same(&attr.ident, attr.ident.name.token(), token) + .return_var_info_if_same(&attr.ident, attr.ident.raw.name.token(), token) .or_else(|| self.get_expr_info(&attr.obj, token)), } } @@ -504,7 +504,7 @@ impl<'a> HIRVisitor<'a> { fn get_call_info(&self, call: &Call, token: &Token) -> Option { if let Some(attr) = &call.attr_name { - if let Some(t) = self.return_var_info_if_same(attr, attr.name.token(), token) { + if let Some(t) = self.return_var_info_if_same(attr, attr.raw.name.token(), token) { return Some(t); } } @@ -534,10 +534,10 @@ impl<'a> HIRVisitor<'a> { fn get_sig_info(&self, sig: &Signature, token: &Token) -> Option { match sig { Signature::Var(var) => { - self.return_var_info_if_same(&var.ident, var.ident.name.token(), token) + self.return_var_info_if_same(&var.ident, var.name().token(), token) } Signature::Subr(subr) => self - .return_var_info_if_same(&subr.ident, subr.ident.name.token(), token) + .return_var_info_if_same(&subr.ident, subr.name().token(), token) .or_else(|| self.get_params_info(&subr.params, token)), } } diff --git a/crates/els/server.rs b/crates/els/server.rs index 79a841399..5921ccd33 100644 --- a/crates/els/server.rs +++ b/crates/els/server.rs @@ -526,7 +526,7 @@ impl Server { ctxs.extend(type_ctxs); if let Ok(singular_ctx) = module .context - .get_singular_ctx_by_hir_expr(expr, &"".into()) + .get_singular_ctx_by_hir_expr(expr, &module.context) { ctxs.push(singular_ctx); } diff --git a/crates/erg_common/config.rs b/crates/erg_common/config.rs index 06c96734e..b92fc3a2f 100644 --- a/crates/erg_common/config.rs +++ b/crates/erg_common/config.rs @@ -117,48 +117,120 @@ impl DummyStdin { } } -/// Since input is not always only from files -/// Unify operations with `Input` #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum Input { +pub enum InputKind { File(PathBuf), - REPL(u64), + REPL, DummyREPL(DummyStdin), /// same content as cfg.command - Pipe(u64, String), + Pipe(String), /// from command option | eval - Str(u64, String), + Str(String), Dummy, } +impl InputKind { + pub const fn is_repl(&self) -> bool { + matches!(self, Self::REPL | Self::DummyREPL(_)) + } + + pub fn path(&self) -> Option<&Path> { + match self { + Self::File(path) => Some(path), + _ => None, + } + } + + pub fn enclosed_name(&self) -> &str { + match self { + Self::File(filename) => filename.to_str().unwrap_or("_"), + Self::REPL | Self::DummyREPL(_) | Self::Pipe(_) => "", + Self::Str(_) => "", + Self::Dummy => "", + } + } + + pub fn dir(&self) -> PathBuf { + if let Self::File(path) = self { + let mut path = path.clone(); + path.pop(); + path + } else { + PathBuf::new() + } + } +} + +/// Since input is not always only from files +/// Unify operations with `Input` +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Input { + pub(crate) kind: InputKind, + /// Unique id to avoid file name collision + id: u64, +} + impl From for Input { fn from(path: PathBuf) -> Self { - Self::File(path) + Self::file(path) } } impl From<&Path> for Input { fn from(path: &Path) -> Self { - Self::File(path.to_path_buf()) + Self::file(path.to_path_buf()) } } impl Input { - pub const fn is_repl(&self) -> bool { - matches!(self, Input::REPL(_) | Input::DummyREPL(_)) + pub const fn new(kind: InputKind, id: u64) -> Self { + Self { kind, id } + } + + pub fn file(path: PathBuf) -> Self { + Self::new(InputKind::File(path), random()) } pub fn pipe(src: String) -> Self { - Self::Pipe(random(), src) + Self::new(InputKind::Pipe(src), random()) } pub fn str(src: String) -> Self { - Self::Str(random(), src) + Self::new(InputKind::Str(src), random()) } pub fn repl() -> Self { - Self::REPL(random()) + Self::new(InputKind::REPL, random()) } + + pub fn dummy() -> Self { + Self::new(InputKind::Dummy, random()) + } + + pub fn dummy_repl(stdin: DummyStdin) -> Self { + Self::new(InputKind::DummyREPL(stdin), random()) + } + + pub const fn is_repl(&self) -> bool { + self.kind.is_repl() + } + + pub const fn id(&self) -> u64 { + self.id + } + + pub fn path(&self) -> Option<&Path> { + self.kind.path() + } + + pub fn dir(&self) -> PathBuf { + self.kind.dir() + } + + pub fn enclosed_name(&self) -> &str { + self.kind.enclosed_name() + } + pub fn lineno(&self) -> usize { GLOBAL_STDIN.lineno() } @@ -179,70 +251,43 @@ impl Input { GLOBAL_STDIN.set_indent(indent); } - pub fn path(&self) -> Option<&Path> { - match self { - Input::File(path) => Some(path), - _ => None, - } - } - - pub const fn id(&self) -> u64 { - match self { - Input::File(_) | Input::DummyREPL(_) | Input::Dummy => 0, - Input::REPL(id) | Input::Pipe(id, _) | Input::Str(id, _) => *id, - } - } - - pub fn enclosed_name(&self) -> &str { - match self { - Self::File(filename) => filename.to_str().unwrap_or("_"), - Self::REPL(_) | Self::DummyREPL(_) | Self::Pipe(_, _) => "", - Self::Str(_, _) => "", - Self::Dummy => "", + pub fn file_stem(&self) -> String { + match &self.kind { + InputKind::File(filename) => format!( + "{}_{}", + filename.file_stem().and_then(|f| f.to_str()).unwrap_or("_"), + self.id + ), + InputKind::REPL | InputKind::Pipe(_) => format!("stdin_{}", self.id), + InputKind::DummyREPL(stdin) => format!("stdin_{}_{}", stdin.name, self.id), + InputKind::Str(_) => format!("string_{}", self.id), + InputKind::Dummy => "dummy".to_string(), } } pub fn full_path(&self) -> PathBuf { - match self { - Self::File(filename) => filename.clone(), - Self::REPL(id) | Self::Pipe(id, _) => PathBuf::from(format!("stdin_{id}")), - Self::DummyREPL(dummy) => PathBuf::from(format!("stdin_{}", dummy.name)), - Self::Str(id, _) => PathBuf::from(format!("string_{id}")), - Self::Dummy => PathBuf::from("dummy"), - } - } - - pub fn file_stem(&self) -> String { - match self { - Self::File(filename) => filename - .file_stem() - .and_then(|f| f.to_str()) - .unwrap_or("_") - .to_string(), - Self::REPL(id) | Self::Pipe(id, _) => format!("stdin_{id}"), - Self::DummyREPL(stdin) => format!("stdin_{}", stdin.name), - Self::Str(id, _) => format!("string_{id}"), - Self::Dummy => "dummy".to_string(), + match &self.kind { + InputKind::File(filename) => { + PathBuf::from(format!("{}_{}", filename.display(), self.id)) + } + _ => PathBuf::from(self.file_stem()), } } pub fn filename(&self) -> String { - match self { - Self::File(filename) => filename - .file_name() - .and_then(|f| f.to_str()) - .unwrap_or("_") - .to_string(), - Self::REPL(id) | Self::Pipe(id, _) => format!("stdin_{id}"), - Self::DummyREPL(stdin) => format!("stdin_{}", stdin.name), - Self::Str(id, _) => format!("string_{id}"), - Self::Dummy => "dummy".to_string(), + match &self.kind { + InputKind::File(filename) => format!( + "{}_{}", + filename.file_name().and_then(|f| f.to_str()).unwrap_or("_"), + self.id + ), + _ => self.file_stem(), } } pub fn read(&mut self) -> String { - match self { - Self::File(filename) => { + match &mut self.kind { + InputKind::File(filename) => { let file = match File::open(&filename) { Ok(f) => f, Err(e) => { @@ -264,16 +309,16 @@ impl Input { } } } - Self::Pipe(_, s) | Self::Str(_, s) => s.clone(), - Self::REPL(_) => GLOBAL_STDIN.read(), - Self::DummyREPL(dummy) => dummy.read_line(), - Self::Dummy => panic!("cannot read from a dummy file"), + InputKind::Pipe(s) | InputKind::Str(s) => s.clone(), + InputKind::REPL => GLOBAL_STDIN.read(), + InputKind::DummyREPL(dummy) => dummy.read_line(), + InputKind::Dummy => panic!("cannot read from a dummy file"), } } pub fn read_non_dummy(&self) -> String { - match self { - Self::File(filename) => { + match &self.kind { + InputKind::File(filename) => { let file = match File::open(filename) { Ok(f) => f, Err(e) => { @@ -295,16 +340,16 @@ impl Input { } } } - Self::Pipe(_, s) | Self::Str(_, s) => s.clone(), - Self::REPL(_) => GLOBAL_STDIN.read(), - Self::Dummy | Self::DummyREPL(_) => panic!("cannot read from a dummy file"), + InputKind::Pipe(s) | InputKind::Str(s) => s.clone(), + InputKind::REPL => GLOBAL_STDIN.read(), + InputKind::Dummy | InputKind::DummyREPL(_) => panic!("cannot read from a dummy file"), } } pub fn reread_lines(&self, ln_begin: usize, ln_end: usize) -> Vec { power_assert!(ln_begin, >=, 1); - match self { - Self::File(filename) => match File::open(filename) { + match &self.kind { + InputKind::File(filename) => match File::open(filename) { Ok(file) => { let mut codes = vec![]; let mut lines = BufReader::new(file).lines().skip(ln_begin - 1); @@ -315,40 +360,35 @@ impl Input { } Err(_) => vec!["".into()], }, - Self::Pipe(_, s) | Self::Str(_, s) => s.split('\n').collect::>() + InputKind::Pipe(s) | InputKind::Str(s) => s.split('\n').collect::>() [ln_begin - 1..=ln_end - 1] .iter() .map(|s| s.to_string()) .collect(), - Self::REPL(_) => { + InputKind::REPL => { if ln_begin == ln_end { vec![GLOBAL_STDIN.reread()] } else { GLOBAL_STDIN.reread_lines(ln_begin, ln_end) } } - Self::DummyREPL(dummy) => dummy.reread_lines(ln_begin, ln_end), - Self::Dummy => panic!("cannot read lines from a dummy file"), + InputKind::DummyREPL(dummy) => dummy.reread_lines(ln_begin, ln_end), + InputKind::Dummy => panic!("cannot read lines from a dummy file"), } } pub fn reread(&self) -> String { - match self { - Self::File(_filename) => todo!(), - Self::Pipe(_, s) | Self::Str(_, s) => s.clone(), - Self::REPL(_) => GLOBAL_STDIN.reread().trim_end().to_owned(), - Self::DummyREPL(dummy) => dummy.reread().unwrap_or_default(), - Self::Dummy => panic!("cannot read from a dummy file"), + match &self.kind { + InputKind::File(_filename) => todo!(), + InputKind::Pipe(s) | InputKind::Str(s) => s.clone(), + InputKind::REPL => GLOBAL_STDIN.reread().trim_end().to_owned(), + InputKind::DummyREPL(dummy) => dummy.reread().unwrap_or_default(), + InputKind::Dummy => panic!("cannot read from a dummy file"), } } pub fn local_resolve(&self, path: &Path) -> Result { - let mut dir = if let Self::File(mut file_path) = self.clone() { - file_path.pop(); - file_path - } else { - PathBuf::new() - }; + let mut dir = self.dir(); dir.push(path); dir.set_extension("er"); // {path}.er let path = dir.canonicalize().or_else(|_| { @@ -361,12 +401,7 @@ impl Input { } pub fn local_decl_resolve(&self, path: &Path) -> Result { - let mut dir = if let Self::File(mut file_path) = self.clone() { - file_path.pop(); - file_path - } else { - PathBuf::new() - }; + let mut dir = self.dir(); let path = add_postfix_foreach(path, ".d"); let mut comps = path.components(); let last = comps.next_back().unwrap(); @@ -394,12 +429,7 @@ impl Input { } pub fn local_py_resolve(&self, path: &Path) -> Result { - let mut dir = if let Self::File(mut path) = self.clone() { - path.pop(); - path - } else { - PathBuf::new() - }; + let mut dir = self.dir(); dir.push(path); dir.set_extension("py"); let path = dir.canonicalize().or_else(|_| { @@ -471,7 +501,7 @@ impl ErgConfig { let path = normalize_path(path); Self { module: "", - input: Input::File(path), + input: Input::file(path), ..ErgConfig::default() } } @@ -517,7 +547,7 @@ impl ErgConfig { let path = normalize_path(path); Self { module: Box::leak(path.to_str().unwrap().to_string().into_boxed_str()), - input: Input::File(path), + input: Input::file(path), ..self.copy() } } @@ -709,7 +739,7 @@ USAGE: let path = PathBuf::from_str(&arg[..]) .unwrap_or_else(|_| panic!("invalid file path: {arg}")); let path = normalize_path(path); - cfg.input = Input::File(path); + cfg.input = Input::file(path); if let Some("--") = args.next().as_ref().map(|s| &s[..]) { for arg in args { cfg.runtime_args.push(Box::leak(arg.into_boxed_str())); diff --git a/crates/erg_common/error.rs b/crates/erg_common/error.rs index 4146a28c0..33380dc45 100644 --- a/crates/erg_common/error.rs +++ b/crates/erg_common/error.rs @@ -5,7 +5,7 @@ use std::cmp::{self, Ordering}; use std::fmt; use std::io::{stderr, BufWriter, Write as _}; -use crate::config::Input; +use crate::config::{Input, InputKind}; use crate::style::Attribute; use crate::style::Characters; use crate::style::Color; @@ -707,13 +707,13 @@ impl SubMessage { cxt.push_str("\n"); cxt.to_string() } - Location::Unknown => match e.input() { - Input::File(_) => "\n".to_string(), - other => { + Location::Unknown => match &e.input().kind { + InputKind::File(_) => "\n".to_string(), + _other => { let (_, vbar) = chars.gutters(); let mut cxt = StyledStrings::default(); cxt.push_str_with_color(&format!(" ? {vbar} "), gutter_color); - cxt.push_str(&other.reread()); + cxt.push_str(&e.input().reread()); cxt.push_str("\n"); for msg in self.msg.iter() { cxt.push_str(msg); @@ -910,7 +910,7 @@ pub trait ErrorDisplay { let (color, mark) = core.specified_theme(); let (gutter_color, chars) = core.theme.characters(); let mut msg = String::new(); - msg += &core.fmt_header(color, self.caused_by(), self.input().enclosed_name()); + msg += &core.fmt_header(color, self.caused_by(), self.input().kind.enclosed_name()); msg += "\n\n"; for sub_msg in &core.sub_messages { msg += &sub_msg.format_code_and_pointer(self, color, gutter_color, mark, chars); @@ -930,7 +930,7 @@ pub trait ErrorDisplay { write!( f, "{}\n\n", - core.fmt_header(color, self.caused_by(), self.input().enclosed_name()) + core.fmt_header(color, self.caused_by(), self.input().kind.enclosed_name()) )?; for sub_msg in &core.sub_messages { write!( diff --git a/crates/erg_common/levenshtein.rs b/crates/erg_common/levenshtein.rs index fe25971cf..84e0c278d 100644 --- a/crates/erg_common/levenshtein.rs +++ b/crates/erg_common/levenshtein.rs @@ -40,14 +40,17 @@ pub fn levenshtein(a: &str, b: &str, limit: usize) -> Option { (dcol[m] <= limit).then_some(dcol[m]) } -pub fn get_similar_name<'a, I: Iterator + Clone>( +pub fn get_similar_name<'a, S: ?Sized, I: Iterator + Clone>( candidates: I, name: &str, -) -> Option<&'a str> { - let limit = (name.len() as f64).sqrt() as usize; +) -> Option<&'a S> +where + S: std::borrow::Borrow, +{ + let limit = (name.len() as f64).sqrt().round() as usize; let most_similar_name = - candidates.min_by_key(|v| levenshtein(v, name, limit).unwrap_or(usize::MAX))?; - let dist = levenshtein(most_similar_name, name, limit); + candidates.min_by_key(|v| levenshtein(v.borrow(), name, limit).unwrap_or(usize::MAX))?; + let dist = levenshtein(most_similar_name.borrow(), name, limit); if dist.is_none() || dist.unwrap() >= limit { None } else { @@ -55,6 +58,24 @@ pub fn get_similar_name<'a, I: Iterator + Clone>( } } +pub fn get_similar_name_and_some<'a, S: ?Sized, T, I: Iterator + Clone>( + candidates: I, + name: &str, +) -> Option<(&'a T, &'a S)> +where + S: std::borrow::Borrow, +{ + let limit = (name.len() as f64).sqrt().round() as usize; + let most_similar_name_and_some = candidates + .min_by_key(|(_, v)| levenshtein(v.borrow(), name, limit).unwrap_or(usize::MAX))?; + let dist = levenshtein(most_similar_name_and_some.1.borrow(), name, limit); + if dist.is_none() || dist.unwrap() >= limit { + None + } else { + Some(most_similar_name_and_some) + } +} + #[cfg(test)] mod tests { use crate::levenshtein::get_similar_name; diff --git a/crates/erg_common/lib.rs b/crates/erg_common/lib.rs index ef5d44569..c38821699 100644 --- a/crates/erg_common/lib.rs +++ b/crates/erg_common/lib.rs @@ -31,9 +31,9 @@ pub mod stdin; pub mod str; pub mod style; pub mod traits; +pub mod triple; pub mod tsort; pub mod tty; -pub mod vis; use crate::set::Set; pub use crate::str::Str; diff --git a/crates/erg_common/str.rs b/crates/erg_common/str.rs index 9a1740e6b..23414414b 100644 --- a/crates/erg_common/str.rs +++ b/crates/erg_common/str.rs @@ -199,6 +199,30 @@ impl Str { ret } + /// ``` + /// use erg_common::str::Str; + /// let s = Str::rc("a.b.c"); + /// assert_eq!(s.rpartition_with(&[".", "/"]), ("a.b", "c")); + /// let s = Str::rc("a::b.c"); + /// assert_eq!(s.rpartition_with(&["/", "::"]), ("a", "b.c")); + /// ``` + pub fn rpartition_with(&self, seps: &[&str]) -> (&str, &str) { + let mut i = self.len(); + while i > 0 { + for sep in seps { + if self[i..].starts_with(sep) { + return (&self[..i], &self[i + sep.len()..]); + } + } + i -= 1; + } + (&self[..], "") + } + + pub fn reversed(&self) -> Str { + Str::rc(&self.chars().rev().collect::()) + } + pub fn multi_replace(&self, paths: &[(&str, &str)]) -> Self { let mut self_ = self.to_string(); for (from, to) in paths { @@ -237,11 +261,6 @@ impl Str { mod tests { use super::*; - use crate::dict; - // use crate::dict::Dict; - - use crate::vis::Field; - #[test] fn test_split_with() { assert_eq!( @@ -261,17 +280,4 @@ mod tests { vec!["aa", "bb", "ff"] ); } - - #[test] - fn test_std_key() { - let dict = dict! {Str::ever("a") => 1, Str::rc("b") => 2}; - assert_eq!(dict.get("a"), Some(&1)); - assert_eq!(dict.get("b"), Some(&2)); - assert_eq!(dict.get(&Str::ever("b")), Some(&2)); - assert_eq!(dict.get(&Str::rc("b")), Some(&2)); - - let dict = dict! {Field::private(Str::ever("a")) => 1, Field::public(Str::ever("b")) => 2}; - assert_eq!(dict.get("a"), Some(&1)); - assert_eq!(dict.get("b"), Some(&2)); - } } diff --git a/crates/erg_common/traits.rs b/crates/erg_common/traits.rs index c5e9ab120..1cde0d6a2 100644 --- a/crates/erg_common/traits.rs +++ b/crates/erg_common/traits.rs @@ -9,7 +9,7 @@ use std::mem; use std::process; use std::slice::{Iter, IterMut}; -use crate::config::{ErgConfig, Input}; +use crate::config::{ErgConfig, Input, InputKind}; use crate::consts::{BUILD_DATE, GIT_HASH_SHORT, SEMVER}; use crate::error::{ErrorDisplay, ErrorKind, Location, MultiErrorDisplay}; use crate::{addr_eq, chomp, log, switch_unreachable}; @@ -713,9 +713,9 @@ pub trait Runnable: Sized + Default { let quiet_repl = cfg.quiet_repl; let mut num_errors = 0; let mut instance = Self::new(cfg); - let res = match instance.input() { - Input::File(_) | Input::Pipe(_, _) | Input::Str(_, _) => instance.exec(), - Input::REPL(_) | Input::DummyREPL(_) => { + let res = match &instance.input().kind { + InputKind::File(_) | InputKind::Pipe(_) | InputKind::Str(_) => instance.exec(), + InputKind::REPL | InputKind::DummyREPL(_) => { let output = stdout(); let mut output = BufWriter::new(output.lock()); if !quiet_repl { @@ -907,7 +907,7 @@ pub trait Runnable: Sized + Default { } } } - Input::Dummy => switch_unreachable!(), + InputKind::Dummy => switch_unreachable!(), }; match res { Ok(i) => ExitStatus::new(i, num_errors), diff --git a/crates/erg_common/triple.rs b/crates/erg_common/triple.rs new file mode 100644 index 000000000..f598ef7a4 --- /dev/null +++ b/crates/erg_common/triple.rs @@ -0,0 +1,82 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Triple { + Ok(T), + Err(E), + None, +} + +impl Triple { + pub fn none_then(self, err: E) -> Result { + match self { + Triple::None => Err(err), + Triple::Ok(ok) => Ok(ok), + Triple::Err(err) => Err(err), + } + } + + pub fn none_or_result(self, f: impl FnOnce() -> E) -> Result { + match self { + Triple::None => Err(f()), + Triple::Ok(ok) => Ok(ok), + Triple::Err(err) => Err(err), + } + } + + pub fn none_or_else(self, f: impl FnOnce() -> Triple) -> Triple { + match self { + Triple::None => f(), + Triple::Ok(ok) => Triple::Ok(ok), + Triple::Err(err) => Triple::Err(err), + } + } + + pub fn unwrap_to_result(self) -> Result { + match self { + Triple::None => panic!("unwrapping Triple::None"), + Triple::Ok(ok) => Ok(ok), + Triple::Err(err) => Err(err), + } + } + + pub fn ok(self) -> Option { + match self { + Triple::None => None, + Triple::Ok(ok) => Some(ok), + Triple::Err(_) => None, + } + } + + pub fn or_else(self, f: impl FnOnce() -> Result) -> Result { + match self { + Triple::None => f(), + Triple::Ok(ok) => Ok(ok), + Triple::Err(err) => Err(err), + } + } + + pub fn unwrap_or(self, default: T) -> T { + match self { + Triple::None => default, + Triple::Ok(ok) => ok, + Triple::Err(_) => default, + } + } + + pub fn unwrap_err(self) -> E { + match self { + Triple::None => panic!("unwrapping Triple::None"), + Triple::Ok(_) => panic!("unwrapping Triple::Ok"), + Triple::Err(err) => err, + } + } +} + +impl Triple { + pub fn unwrap(self) -> T { + match self { + Triple::None => panic!("unwrapping Triple::None"), + Triple::Ok(ok) => ok, + Triple::Err(err) => panic!("unwrapping Triple::Err({err})"), + } + } +} diff --git a/crates/erg_common/vis.rs b/crates/erg_common/vis.rs deleted file mode 100644 index 0dbcf5fbe..000000000 --- a/crates/erg_common/vis.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::borrow::Borrow; -use std::fmt; - -use crate::Str; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[repr(u8)] -pub enum Visibility { - Private, - Public, -} - -impl Visibility { - pub const fn is_public(&self) -> bool { - matches!(self, Self::Public) - } - pub const fn is_private(&self) -> bool { - matches!(self, Self::Private) - } -} - -/// same structure as `Identifier`, but only for Record fields. -#[derive(Debug, Clone, Eq)] -pub struct Field { - pub vis: Visibility, - pub symbol: Str, -} - -impl PartialEq for Field { - fn eq(&self, other: &Self) -> bool { - self.symbol == other.symbol - } -} - -impl std::hash::Hash for Field { - fn hash(&self, state: &mut H) { - self.symbol.hash(state); - } -} - -impl fmt::Display for Field { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if self.vis.is_public() { - write!(f, ".{}", self.symbol) - } else { - write!(f, "::{}", self.symbol) - } - } -} - -impl Borrow for Field { - #[inline] - fn borrow(&self) -> &str { - &self.symbol[..] - } -} - -impl Borrow for Field { - #[inline] - fn borrow(&self) -> &Str { - &self.symbol - } -} - -impl Field { - pub const fn new(vis: Visibility, symbol: Str) -> Self { - Field { vis, symbol } - } - - pub const fn private(symbol: Str) -> Self { - Field::new(Visibility::Private, symbol) - } - - pub const fn public(symbol: Str) -> Self { - Field::new(Visibility::Public, symbol) - } - - pub fn is_const(&self) -> bool { - self.symbol.starts_with(char::is_uppercase) - } -} diff --git a/crates/erg_compiler/codegen.rs b/crates/erg_compiler/codegen.rs index 1d7fe7ec0..317d1bdbb 100644 --- a/crates/erg_compiler/codegen.rs +++ b/crates/erg_compiler/codegen.rs @@ -17,11 +17,11 @@ use erg_common::opcode311::{BinOpCode, Opcode311}; use erg_common::option_enum_unwrap; use erg_common::python_util::{env_python_version, PythonVersion}; use erg_common::traits::{Locational, Stream}; -use erg_common::vis::Visibility; use erg_common::Str; use erg_common::{ debug_power_assert, enum_unwrap, fn_name, fn_name_full, impl_stream, log, switch_unreachable, }; +use erg_parser::ast::VisModifierSpec; use erg_parser::ast::{DefId, DefKind}; use CommonOpcode::*; @@ -38,7 +38,7 @@ use crate::hir::{ SubrSignature, Tuple, UnaryOp, VarSignature, HIR, }; use crate::ty::value::ValueObj; -use crate::ty::{HasType, Type, TypeCode, TypePair}; +use crate::ty::{HasType, Type, TypeCode, TypePair, VisibilityModifier}; use crate::varinfo::VarInfo; use erg_common::fresh::fresh_varname; use AccessKind::*; @@ -70,7 +70,7 @@ fn debind(ident: &Identifier) -> Option { } } -fn escape_name(name: &str, vis: Visibility) -> Str { +fn escape_name(name: &str, vis: &VisibilityModifier) -> Str { let name = name.replace('!', "__erg_proc__"); let name = name.replace('$', "__erg_shared__"); if vis.is_private() { @@ -908,7 +908,7 @@ impl PyCodeGenerator { if s == "_" { format!("_{i}") } else { - escape_name(s, Visibility::Private).to_string() + escape_name(s, &VisibilityModifier::Private).to_string() } }) .map(|s| self.get_cached(&s)) @@ -930,11 +930,11 @@ impl PyCodeGenerator { // Since Erg does not allow the coexistence of private and public variables with the same name, there is no problem in this trick. let is_record = a.obj.ref_t().is_record(); if is_record { - a.ident.dot = Some(DOT); + a.ident.raw.vis = VisModifierSpec::Public(DOT); } if let Some(varname) = debind(&a.ident) { - a.ident.dot = None; - a.ident.name = VarName::from_str(varname); + a.ident.raw.vis = VisModifierSpec::Private; + a.ident.raw.name = VarName::from_str(varname); self.emit_load_name_instr(a.ident); } else { self.emit_expr(*a.obj); @@ -1153,9 +1153,9 @@ impl PyCodeGenerator { self.emit_load_const(code); if self.py_version.minor < Some(11) { if let Some(class) = class_name { - self.emit_load_const(Str::from(format!("{class}.{}", ident.name.inspect()))); + self.emit_load_const(Str::from(format!("{class}.{}", ident.inspect()))); } else { - self.emit_load_const(ident.name.inspect().clone()); + self.emit_load_const(ident.inspect().clone()); } } else { self.stack_inc(); @@ -1213,8 +1213,8 @@ impl PyCodeGenerator { patch_def.sig.ident().to_string_notype(), def.sig.ident().to_string_notype() ); - def.sig.ident_mut().name = VarName::from_str(Str::from(name)); - def.sig.ident_mut().dot = None; + def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name)); + def.sig.ident_mut().raw.vis = VisModifierSpec::Private; self.emit_def(def); } } @@ -1925,7 +1925,8 @@ impl PyCodeGenerator { } match param.raw.pat { ParamPattern::VarName(name) => { - let ident = Identifier::bare(None, name); + let ident = erg_parser::ast::Identifier::private_from_varname(name); + let ident = Identifier::bare(ident); self.emit_store_instr(ident, AccessKind::Name); } ParamPattern::Discard(_) => { @@ -2190,7 +2191,7 @@ impl PyCodeGenerator { let kw = if is_py_api { arg.keyword.content } else { - escape_name(&arg.keyword.content, Visibility::Private) + escape_name(&arg.keyword.content, &VisibilityModifier::Private) }; kws.push(ValueObj::Str(kw)); self.emit_expr(arg.expr); @@ -2301,7 +2302,7 @@ impl PyCodeGenerator { mut args: Args, ) { log!(info "entered {}", fn_name!()); - method_name.dot = None; + method_name.raw.vis = VisModifierSpec::Private; method_name.vi.py_name = Some(func_name); self.emit_push_null(); self.emit_load_name_instr(method_name); @@ -2785,6 +2786,7 @@ impl PyCodeGenerator { let vi = VarInfo::nd_parameter( __new__.return_t().unwrap().clone(), ident.vi.def_loc.clone(), + "?".into(), ); let raw = erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(self_param), None); @@ -2797,7 +2799,11 @@ impl PyCodeGenerator { let param = VarName::from_str_and_line(Str::from(param_name.clone()), line); let raw = erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None); - let vi = VarInfo::nd_parameter(new_first_param.typ().clone(), ident.vi.def_loc.clone()); + let vi = VarInfo::nd_parameter( + new_first_param.typ().clone(), + ident.vi.def_loc.clone(), + "?".into(), + ); let param = NonDefaultParamSignature::new(raw, vi, None); let params = Params::new(vec![self_param, param], None, vec![], None); (param_name, params) @@ -2818,20 +2824,19 @@ impl PyCodeGenerator { for field in rec.keys() { let obj = Expr::Accessor(Accessor::private_with_line(Str::from(¶m_name), line)); - let expr = obj.attr_expr(Identifier::bare( - Some(DOT), - VarName::from_str(field.symbol.clone()), - )); + let ident = erg_parser::ast::Identifier::public(field.symbol.clone()); + let expr = obj.attr_expr(Identifier::bare(ident)); let obj = Expr::Accessor(Accessor::private_with_line(Str::ever("self"), line)); let dot = if field.vis.is_private() { - None + VisModifierSpec::Private } else { - Some(DOT) + VisModifierSpec::Public(DOT) }; - let attr = obj.attr(Identifier::bare( + let attr = erg_parser::ast::Identifier::new( dot, VarName::from_str(field.symbol.clone()), - )); + ); + let attr = obj.attr(Identifier::bare(attr)); let redef = ReDef::new(attr, Block::new(vec![expr])); attrs.push(Expr::ReDef(redef)); } @@ -2865,8 +2870,7 @@ impl PyCodeGenerator { let line = sig.ln_begin().unwrap(); let mut ident = Identifier::public_with_line(DOT, Str::ever("new"), line); let class = Expr::Accessor(Accessor::Ident(class_ident.clone())); - let mut new_ident = - Identifier::bare(None, VarName::from_str_and_line(Str::ever("__new__"), line)); + let mut new_ident = Identifier::private_with_line(Str::ever("__new__"), line); new_ident.vi.py_name = Some(Str::ever("__call__")); let class_new = class.attr_expr(new_ident); ident.vi.t = __new__; @@ -2876,7 +2880,11 @@ impl PyCodeGenerator { .map(|s| s.to_string()) .unwrap_or_else(fresh_varname); let param = VarName::from_str_and_line(Str::from(param_name.clone()), line); - let vi = VarInfo::nd_parameter(new_first_param.typ().clone(), ident.vi.def_loc.clone()); + let vi = VarInfo::nd_parameter( + new_first_param.typ().clone(), + ident.vi.def_loc.clone(), + "?".into(), + ); let raw = erg_parser::ast::NonDefaultParamSignature::new(ParamPattern::VarName(param), None); let param = NonDefaultParamSignature::new(raw, vi, None); diff --git a/crates/erg_compiler/context/compare.rs b/crates/erg_compiler/context/compare.rs index 68497f181..24ff39ad0 100644 --- a/crates/erg_compiler/context/compare.rs +++ b/crates/erg_compiler/context/compare.rs @@ -1,21 +1,20 @@ //! provides type-comparison use std::option::Option; // conflicting to Type::Option +use erg_common::dict::Dict; use erg_common::error::MultiErrorDisplay; use erg_common::style::colors::DEBUG_ERROR; use erg_common::traits::StructuralEq; +use erg_common::{assume_unreachable, log}; use crate::ty::constructors::{and, not, or, poly}; use crate::ty::free::{Constraint, FreeKind}; use crate::ty::typaram::{OpKind, TyParam, TyParamOrdering}; use crate::ty::value::ValueObj; use crate::ty::value::ValueObj::Inf; -use crate::ty::{Predicate, RefinementType, SubrKind, SubrType, Type}; +use crate::ty::{Field, Predicate, RefinementType, SubrKind, SubrType, Type}; use Predicate as Pred; -use erg_common::dict::Dict; -use erg_common::vis::Field; -use erg_common::{assume_unreachable, log}; use TyParamOrdering::*; use Type::*; @@ -455,9 +454,12 @@ impl Context { } }, (Type::Record(lhs), Type::Record(rhs)) => { - for (k, l) in lhs.iter() { - if let Some(r) = rhs.get(k) { - if !self.supertype_of(l, r) { + for (l_k, l_t) in lhs.iter() { + if let Some((r_k, r_t)) = rhs.get_key_value(l_k) { + // public <: private (private fields cannot be public) + if (l_k.vis.is_public() && r_k.vis.is_private()) + || !self.supertype_of(l_t, r_t) + { return false; } } else { @@ -705,7 +707,12 @@ impl Context { .unwrap_or_else(|| panic!("{other} is not found")); ctx.type_dir() .into_iter() - .map(|(name, vi)| (Field::new(vi.vis, name.inspect().clone()), vi.t.clone())) + .map(|(name, vi)| { + ( + Field::new(vi.vis.modifier.clone(), name.inspect().clone()), + vi.t.clone(), + ) + }) .collect() } } diff --git a/crates/erg_compiler/context/eval.rs b/crates/erg_compiler/context/eval.rs index 7c6e0cd8d..6a49e1ecc 100644 --- a/crates/erg_compiler/context/eval.rs +++ b/crates/erg_compiler/context/eval.rs @@ -7,7 +7,6 @@ use erg_common::log; use erg_common::set::Set; use erg_common::shared::Shared; use erg_common::traits::{Locational, Stream}; -use erg_common::vis::Field; use erg_common::{dict, fn_name, option_enum_unwrap, set}; use erg_common::{enum_unwrap, fmt_vec}; use erg_common::{RcArray, Str}; @@ -27,7 +26,7 @@ use crate::ty::typaram::{OpKind, TyParam}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, Type, UserConstSubr, ValueArgs}; -use crate::context::instantiate::ParamKind; +use crate::context::instantiate_spec::ParamKind; use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode}; use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult}; @@ -166,7 +165,10 @@ impl Context { } fn eval_attr(&self, obj: ValueObj, ident: &Identifier) -> SingleEvalResult { - if let Some(val) = obj.try_get_attr(&Field::from(ident)) { + let field = self + .instantiate_field(ident) + .map_err(|mut errs| errs.remove(0))?; + if let Some(val) = obj.try_get_attr(&field) { return Ok(val); } if let ValueObj::Type(t) = &obj { @@ -301,7 +303,7 @@ impl Context { fn eval_const_def(&mut self, def: &Def) -> EvalResult { if def.is_const() { let __name__ = def.sig.ident().unwrap().inspect(); - let vis = def.sig.vis(); + let vis = self.instantiate_vis_modifier(def.sig.vis())?; let tv_cache = match &def.sig { Signature::Subr(subr) => { let ty_cache = @@ -430,7 +432,7 @@ impl Context { let elem = record_ctx.eval_const_block(&attr.body.block)?; let ident = match &attr.sig { Signature::Var(var) => match &var.pat { - VarPattern::Ident(ident) => Field::new(ident.vis(), ident.inspect().clone()), + VarPattern::Ident(ident) => self.instantiate_field(ident)?, other => { return feature_error!(self, other.loc(), &format!("record field: {other}")) } diff --git a/crates/erg_compiler/context/initialize/classes.rs b/crates/erg_compiler/context/initialize/classes.rs index 71ba67220..98b6cab98 100644 --- a/crates/erg_compiler/context/initialize/classes.rs +++ b/crates/erg_compiler/context/initialize/classes.rs @@ -1,12 +1,11 @@ #[allow(unused_imports)] use erg_common::log; -use erg_common::vis::Visibility; use erg_common::Str as StrStruct; use crate::ty::constructors::*; use crate::ty::typaram::TyParam; use crate::ty::value::ValueObj; -use crate::ty::Type; +use crate::ty::{Type, Visibility}; use ParamSpec as PS; use Type::*; @@ -14,14 +13,13 @@ use crate::context::initialize::*; use crate::context::{Context, ParamSpec}; use crate::varinfo::Mutability; use Mutability::*; -use Visibility::*; impl Context { pub(super) fn init_builtin_classes(&mut self) { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; let T = mono_q(TY_T, instanceof(Type)); let U = mono_q(TY_U, instanceof(Type)); @@ -62,12 +60,17 @@ impl Context { ); obj.register_py_builtin(FUNDAMENTAL_STR, fn0_met(Obj, Str), Some(FUNDAMENTAL_STR), 9); let mut obj_in = Self::builtin_methods(Some(poly(IN, vec![ty_tp(Type)])), 2); - obj_in.register_builtin_erg_impl(OP_IN, fn1_met(Obj, Type, Bool), Const, Public); + obj_in.register_builtin_erg_impl( + OP_IN, + fn1_met(Obj, Type, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); obj.register_trait(Obj, obj_in); let mut obj_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 1); obj_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUTABLE_OBJ)), ); obj.register_trait(Obj, obj_mutizable); @@ -77,9 +80,25 @@ impl Context { let mut float = Self::builtin_mono_class(FLOAT, 2); float.register_superclass(Obj, &obj); // TODO: support multi platform - float.register_builtin_const(EPSILON, Public, ValueObj::Float(2.220446049250313e-16)); - float.register_builtin_py_impl(REAL, Float, Const, Public, Some(FUNC_REAL)); - float.register_builtin_py_impl(IMAG, Float, Const, Public, Some(FUNC_IMAG)); + float.register_builtin_const( + EPSILON, + Visibility::BUILTIN_PUBLIC, + ValueObj::Float(2.220446049250313e-16), + ); + float.register_builtin_py_impl( + REAL, + Float, + Const, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_REAL), + ); + float.register_builtin_py_impl( + IMAG, + Float, + Const, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_IMAG), + ); float.register_py_builtin( FUNC_AS_INTEGER_RATIO, fn0_met(Float, tuple_t(vec![Int, Int])), @@ -112,58 +131,139 @@ impl Context { OP_CMP, fn1_met(Float, Float, mono(ORDERING)), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); float.register_trait(Float, float_ord); // Float doesn't have an `Eq` implementation let op_t = fn1_met(Float, Float, Float); let mut float_add = Self::builtin_methods(Some(poly(ADD, vec![ty_tp(Float)])), 2); - float_add.register_builtin_erg_impl(OP_ADD, op_t.clone(), Const, Public); - float_add.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Float)); + float_add.register_builtin_erg_impl( + OP_ADD, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + float_add.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); float.register_trait(Float, float_add); let mut float_sub = Self::builtin_methods(Some(poly(SUB, vec![ty_tp(Float)])), 2); - float_sub.register_builtin_erg_impl(OP_SUB, op_t.clone(), Const, Public); - float_sub.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Float)); + float_sub.register_builtin_erg_impl( + OP_SUB, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + float_sub.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); float.register_trait(Float, float_sub); let mut float_mul = Self::builtin_methods(Some(poly(MUL, vec![ty_tp(Float)])), 2); - float_mul.register_builtin_erg_impl(OP_MUL, op_t.clone(), Const, Public); - float_mul.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Float)); - float_mul.register_builtin_const(POW_OUTPUT, Public, ValueObj::builtin_t(Float)); + float_mul.register_builtin_erg_impl( + OP_MUL, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + float_mul.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); + float_mul.register_builtin_const( + POW_OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); float.register_trait(Float, float_mul); let mut float_div = Self::builtin_methods(Some(poly(DIV, vec![ty_tp(Float)])), 2); - float_div.register_builtin_erg_impl(OP_DIV, op_t.clone(), Const, Public); - float_div.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Float)); - float_div.register_builtin_const(MOD_OUTPUT, Public, ValueObj::builtin_t(Float)); + float_div.register_builtin_erg_impl( + OP_DIV, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + float_div.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); + float_div.register_builtin_const( + MOD_OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); float.register_trait(Float, float_div); let mut float_floordiv = Self::builtin_methods(Some(poly(FLOOR_DIV, vec![ty_tp(Float)])), 2); - float_floordiv.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Public); - float_floordiv.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Float)); + float_floordiv.register_builtin_erg_impl( + OP_FLOOR_DIV, + op_t, + Const, + Visibility::BUILTIN_PUBLIC, + ); + float_floordiv.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); float.register_trait(Float, float_floordiv); let mut float_pos = Self::builtin_methods(Some(mono(POS)), 1); - float_pos.register_builtin_erg_impl(OP_POS, fn0_met(Float, Float), Const, Public); + float_pos.register_builtin_erg_impl( + OP_POS, + fn0_met(Float, Float), + Const, + Visibility::BUILTIN_PUBLIC, + ); float.register_trait(Float, float_pos); let mut float_neg = Self::builtin_methods(Some(mono(NEG)), 1); - float_neg.register_builtin_erg_impl(OP_NEG, fn0_met(Float, Float), Const, Public); + float_neg.register_builtin_erg_impl( + OP_NEG, + fn0_met(Float, Float), + Const, + Visibility::BUILTIN_PUBLIC, + ); float.register_trait(Float, float_neg); let mut float_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); float_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUT_FLOAT)), ); float.register_trait(Float, float_mutizable); let mut float_show = Self::builtin_methods(Some(mono(SHOW)), 1); let t = fn0_met(Float, Str); - float_show.register_builtin_py_impl(TO_STR, t, Immutable, Public, Some(FUNDAMENTAL_STR)); + float_show.register_builtin_py_impl( + TO_STR, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNDAMENTAL_STR), + ); float.register_trait(Float, float_show); /* Ratio */ // TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat) let mut ratio = Self::builtin_mono_class(RATIO, 2); ratio.register_superclass(Obj, &obj); - ratio.register_builtin_py_impl(REAL, Ratio, Const, Public, Some(FUNC_REAL)); - ratio.register_builtin_py_impl(IMAG, Ratio, Const, Public, Some(FUNC_IMAG)); + ratio.register_builtin_py_impl( + REAL, + Ratio, + Const, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_REAL), + ); + ratio.register_builtin_py_impl( + IMAG, + Ratio, + Const, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_IMAG), + ); ratio.register_marker_trait(mono(NUM)); ratio.register_marker_trait(mono(ORD)); let mut ratio_ord = Self::builtin_methods(Some(mono(ORD)), 2); @@ -171,46 +271,104 @@ impl Context { OP_CMP, fn1_met(Ratio, Ratio, mono(ORDERING)), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); ratio.register_trait(Ratio, ratio_ord); let mut ratio_eq = Self::builtin_methods(Some(mono(EQ)), 2); - ratio_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Ratio, Ratio, Bool), Const, Public); + ratio_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Ratio, Ratio, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); ratio.register_trait(Ratio, ratio_eq); let op_t = fn1_met(Ratio, Ratio, Ratio); let mut ratio_add = Self::builtin_methods(Some(poly(ADD, vec![ty_tp(Ratio)])), 2); - ratio_add.register_builtin_erg_impl(OP_ADD, op_t.clone(), Const, Public); - ratio_add.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Ratio)); + ratio_add.register_builtin_erg_impl( + OP_ADD, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + ratio_add.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); ratio.register_trait(Ratio, ratio_add); let mut ratio_sub = Self::builtin_methods(Some(poly(SUB, vec![ty_tp(Ratio)])), 2); - ratio_sub.register_builtin_erg_impl(OP_SUB, op_t.clone(), Const, Public); - ratio_sub.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Ratio)); + ratio_sub.register_builtin_erg_impl( + OP_SUB, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + ratio_sub.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); ratio.register_trait(Ratio, ratio_sub); let mut ratio_mul = Self::builtin_methods(Some(poly(MUL, vec![ty_tp(Ratio)])), 2); - ratio_mul.register_builtin_erg_impl(OP_MUL, op_t.clone(), Const, Public); - ratio_mul.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Ratio)); - ratio_mul.register_builtin_const(POW_OUTPUT, Public, ValueObj::builtin_t(Ratio)); + ratio_mul.register_builtin_erg_impl( + OP_MUL, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + ratio_mul.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); + ratio_mul.register_builtin_const( + POW_OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); ratio.register_trait(Ratio, ratio_mul); let mut ratio_div = Self::builtin_methods(Some(poly(DIV, vec![ty_tp(Ratio)])), 2); - ratio_div.register_builtin_erg_impl(OP_DIV, op_t.clone(), Const, Public); - ratio_div.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Ratio)); - ratio_div.register_builtin_const(MOD_OUTPUT, Public, ValueObj::builtin_t(Ratio)); + ratio_div.register_builtin_erg_impl( + OP_DIV, + op_t.clone(), + Const, + Visibility::BUILTIN_PUBLIC, + ); + ratio_div.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); + ratio_div.register_builtin_const( + MOD_OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); ratio.register_trait(Ratio, ratio_div); let mut ratio_floordiv = Self::builtin_methods(Some(poly(FLOOR_DIV, vec![ty_tp(Ratio)])), 2); - ratio_floordiv.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Public); - ratio_floordiv.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Ratio)); + ratio_floordiv.register_builtin_erg_impl( + OP_FLOOR_DIV, + op_t, + Const, + Visibility::BUILTIN_PUBLIC, + ); + ratio_floordiv.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); ratio.register_trait(Ratio, ratio_floordiv); let mut ratio_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); ratio_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUT_RATIO)), ); ratio.register_trait(Ratio, ratio_mutizable); let mut ratio_show = Self::builtin_methods(Some(mono(SHOW)), 1); let t = fn0_met(Ratio, Str); - ratio_show.register_builtin_erg_impl(TO_STR, t, Immutable, Public); + ratio_show.register_builtin_erg_impl(TO_STR, t, Immutable, Visibility::BUILTIN_PUBLIC); ratio.register_trait(Ratio, ratio_show); /* Int */ @@ -267,50 +425,108 @@ impl Context { OP_PARTIAL_CMP, fn1_met(Int, Int, or(mono(ORDERING), NoneType)), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); int.register_trait(Int, int_ord); let mut int_eq = Self::builtin_methods(Some(mono(EQ)), 2); - int_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Int, Int, Bool), Const, Public); + int_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Int, Int, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); int.register_trait(Int, int_eq); // __div__ is not included in Int (cast to Ratio) let op_t = fn1_met(Int, Int, Int); let mut int_add = Self::builtin_methods(Some(poly(ADD, vec![ty_tp(Int)])), 2); - int_add.register_builtin_erg_impl(OP_ADD, op_t.clone(), Const, Public); - int_add.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Int)); + int_add.register_builtin_erg_impl(OP_ADD, op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + int_add.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Int), + ); int.register_trait(Int, int_add); let mut int_sub = Self::builtin_methods(Some(poly(SUB, vec![ty_tp(Int)])), 2); - int_sub.register_builtin_erg_impl(OP_SUB, op_t.clone(), Const, Public); - int_sub.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Int)); + int_sub.register_builtin_erg_impl(OP_SUB, op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + int_sub.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Int), + ); int.register_trait(Int, int_sub); let mut int_mul = Self::builtin_methods(Some(poly(MUL, vec![ty_tp(Int)])), 2); - int_mul.register_builtin_erg_impl(OP_MUL, op_t.clone(), Const, Public); - int_mul.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Int)); - int_mul.register_builtin_const(POW_OUTPUT, Public, ValueObj::builtin_t(Nat)); + int_mul.register_builtin_erg_impl(OP_MUL, op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + int_mul.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Int), + ); + int_mul.register_builtin_const( + POW_OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Nat), + ); int.register_trait(Int, int_mul); let mut int_floordiv = Self::builtin_methods(Some(poly(FLOOR_DIV, vec![ty_tp(Int)])), 2); - int_floordiv.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Public); - int_floordiv.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Int)); + int_floordiv.register_builtin_erg_impl( + OP_FLOOR_DIV, + op_t, + Const, + Visibility::BUILTIN_PUBLIC, + ); + int_floordiv.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Int), + ); int.register_trait(Int, int_floordiv); let mut int_pos = Self::builtin_methods(Some(mono(POS)), 2); - int_pos.register_builtin_erg_impl(OP_POS, fn0_met(Int, Int), Const, Public); + int_pos.register_builtin_erg_impl( + OP_POS, + fn0_met(Int, Int), + Const, + Visibility::BUILTIN_PUBLIC, + ); int.register_trait(Int, int_pos); let mut int_neg = Self::builtin_methods(Some(mono(NEG)), 2); - int_neg.register_builtin_erg_impl(OP_NEG, fn0_met(Int, Int), Const, Public); + int_neg.register_builtin_erg_impl( + OP_NEG, + fn0_met(Int, Int), + Const, + Visibility::BUILTIN_PUBLIC, + ); int.register_trait(Int, int_neg); let mut int_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); int_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUT_INT)), ); int.register_trait(Int, int_mutizable); let mut int_show = Self::builtin_methods(Some(mono(SHOW)), 1); let t = fn0_met(Int, Str); - int_show.register_builtin_py_impl(TO_STR, t, Immutable, Public, Some(FUNDAMENTAL_STR)); + int_show.register_builtin_py_impl( + TO_STR, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNDAMENTAL_STR), + ); int.register_trait(Int, int_show); - int.register_builtin_py_impl(REAL, Int, Const, Public, Some(FUNC_REAL)); - int.register_builtin_py_impl(IMAG, Int, Const, Public, Some(FUNC_IMAG)); + int.register_builtin_py_impl( + REAL, + Int, + Const, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_REAL), + ); + int.register_builtin_py_impl( + IMAG, + Int, + Const, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_IMAG), + ); /* Nat */ let mut nat = Self::builtin_mono_class(NAT, 10); @@ -331,63 +547,110 @@ impl Context { ); nat.register_marker_trait(mono(NUM)); let mut nat_eq = Self::builtin_methods(Some(mono(EQ)), 2); - nat_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Nat, Nat, Bool), Const, Public); + nat_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Nat, Nat, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); nat.register_trait(Nat, nat_eq); let mut nat_ord = Self::builtin_methods(Some(mono(ORD)), 2); - nat_ord.register_builtin_erg_impl(OP_CMP, fn1_met(Nat, Nat, mono(ORDERING)), Const, Public); + nat_ord.register_builtin_erg_impl( + OP_CMP, + fn1_met(Nat, Nat, mono(ORDERING)), + Const, + Visibility::BUILTIN_PUBLIC, + ); nat.register_trait(Nat, nat_ord); // __sub__, __div__ is not included in Nat (cast to Int/ Ratio) let op_t = fn1_met(Nat, Nat, Nat); let mut nat_add = Self::builtin_methods(Some(poly(ADD, vec![ty_tp(Nat)])), 2); - nat_add.register_builtin_erg_impl(OP_ADD, op_t.clone(), Const, Public); - nat_add.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Nat)); + nat_add.register_builtin_erg_impl(OP_ADD, op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + nat_add.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Nat), + ); nat.register_trait(Nat, nat_add); let mut nat_mul = Self::builtin_methods(Some(poly(MUL, vec![ty_tp(Nat)])), 2); - nat_mul.register_builtin_erg_impl(OP_MUL, op_t.clone(), Const, Public); - nat_mul.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Nat)); + nat_mul.register_builtin_erg_impl(OP_MUL, op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + nat_mul.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Nat), + ); nat.register_trait(Nat, nat_mul); let mut nat_floordiv = Self::builtin_methods(Some(poly(FLOOR_DIV, vec![ty_tp(Nat)])), 2); - nat_floordiv.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Public); - nat_floordiv.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Nat)); + nat_floordiv.register_builtin_erg_impl( + OP_FLOOR_DIV, + op_t, + Const, + Visibility::BUILTIN_PUBLIC, + ); + nat_floordiv.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Nat), + ); nat.register_trait(Nat, nat_floordiv); let mut nat_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); nat_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUT_NAT)), ); nat.register_trait(Nat, nat_mutizable); - nat.register_builtin_erg_impl(REAL, Nat, Const, Public); - nat.register_builtin_erg_impl(IMAG, Nat, Const, Public); + nat.register_builtin_erg_impl(REAL, Nat, Const, Visibility::BUILTIN_PUBLIC); + nat.register_builtin_erg_impl(IMAG, Nat, Const, Visibility::BUILTIN_PUBLIC); /* Bool */ let mut bool_ = Self::builtin_mono_class(BOOL, 10); bool_.register_superclass(Nat, &nat); // class("Rational"), // class("Integral"), - bool_.register_builtin_erg_impl(OP_AND, fn1_met(Bool, Bool, Bool), Const, Public); - bool_.register_builtin_erg_impl(OP_OR, fn1_met(Bool, Bool, Bool), Const, Public); + bool_.register_builtin_erg_impl( + OP_AND, + fn1_met(Bool, Bool, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); + bool_.register_builtin_erg_impl( + OP_OR, + fn1_met(Bool, Bool, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); bool_.register_marker_trait(mono(NUM)); let mut bool_ord = Self::builtin_methods(Some(mono(ORD)), 2); bool_ord.register_builtin_erg_impl( OP_CMP, fn1_met(Bool, Bool, mono(ORDERING)), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); bool_.register_trait(Bool, bool_ord); let mut bool_eq = Self::builtin_methods(Some(mono(EQ)), 2); - bool_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Bool, Bool, Bool), Const, Public); + bool_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Bool, Bool, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); bool_.register_trait(Bool, bool_eq); let mut bool_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); bool_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUT_BOOL)), ); bool_.register_trait(Bool, bool_mutizable); let mut bool_show = Self::builtin_methods(Some(mono(SHOW)), 1); - bool_show.register_builtin_erg_impl(TO_STR, fn0_met(Bool, Str), Immutable, Public); + bool_show.register_builtin_erg_impl( + TO_STR, + fn0_met(Bool, Str), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); bool_.register_trait(Bool, bool_show); let t = fn0_met(Bool, Bool); bool_.register_py_builtin(FUNC_INVERT, t, Some(FUNC_INVERT), 9); @@ -406,7 +669,7 @@ impl Context { Str, ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); str_.register_builtin_erg_impl( FUNC_ENCODE, @@ -418,44 +681,44 @@ impl Context { mono(BYTES), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); str_.register_builtin_erg_impl( FUNC_FORMAT, fn_met(Str, vec![], Some(kw(KW_ARGS, Obj)), vec![], Str), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); str_.register_builtin_erg_impl( FUNC_LOWER, fn_met(Str, vec![], None, vec![], Str), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); str_.register_builtin_erg_impl( FUNC_UPPER, fn_met(Str, vec![], None, vec![], Str), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); str_.register_builtin_erg_impl( FUNC_TO_INT, fn_met(Str, vec![], None, vec![], or(Int, NoneType)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); str_.register_builtin_py_impl( FUNC_STARTSWITH, fn1_met(Str, Str, Bool), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_STARTSWITH), ); str_.register_builtin_py_impl( FUNC_ENDSWITH, fn1_met(Str, Str, Bool), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_ENDSWITH), ); str_.register_builtin_py_impl( @@ -468,7 +731,7 @@ impl Context { unknown_len_array_t(Str), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_SPLIT), ); str_.register_builtin_py_impl( @@ -481,14 +744,14 @@ impl Context { unknown_len_array_t(Str), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_SPLITLINES), ); str_.register_builtin_py_impl( FUNC_JOIN, fn1_met(unknown_len_array_t(Str), Str, Str), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_JOIN), ); str_.register_builtin_py_impl( @@ -501,7 +764,7 @@ impl Context { or(Nat, Never), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_INDEX), ); str_.register_builtin_py_impl( @@ -514,7 +777,7 @@ impl Context { or(Nat, Never), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_RINDEX), ); str_.register_builtin_py_impl( @@ -527,7 +790,7 @@ impl Context { or(Nat, v_enum(set! {(-1).into()})), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_FIND), ); str_.register_builtin_py_impl( @@ -540,7 +803,7 @@ impl Context { or(Nat, v_enum(set! {(-1).into()})), ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_RFIND), ); str_.register_builtin_py_impl( @@ -553,7 +816,7 @@ impl Context { Nat, ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_COUNT), ); str_.register_py_builtin( @@ -562,43 +825,95 @@ impl Context { Some(FUNC_CAPITALIZE), 13, ); - str_.register_builtin_erg_impl(FUNC_CONTAINS, fn1_met(Str, Str, Bool), Immutable, Public); + str_.register_builtin_erg_impl( + FUNC_CONTAINS, + fn1_met(Str, Str, Bool), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let str_getitem_t = fn1_kw_met(Str, kw(KW_IDX, Nat), Str); - str_.register_builtin_erg_impl(FUNDAMENTAL_GETITEM, str_getitem_t, Immutable, Public); + str_.register_builtin_erg_impl( + FUNDAMENTAL_GETITEM, + str_getitem_t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let mut str_eq = Self::builtin_methods(Some(mono(EQ)), 2); - str_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Str, Str, Bool), Const, Public); + str_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Str, Str, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); str_.register_trait(Str, str_eq); let mut str_seq = Self::builtin_methods(Some(poly(SEQ, vec![ty_tp(Str)])), 2); - str_seq.register_builtin_erg_impl(FUNC_LEN, fn0_met(Str, Nat), Const, Public); - str_seq.register_builtin_erg_impl(FUNC_GET, fn1_met(Str, Nat, Str), Const, Public); + str_seq.register_builtin_erg_impl( + FUNC_LEN, + fn0_met(Str, Nat), + Const, + Visibility::BUILTIN_PUBLIC, + ); + str_seq.register_builtin_erg_impl( + FUNC_GET, + fn1_met(Str, Nat, Str), + Const, + Visibility::BUILTIN_PUBLIC, + ); str_.register_trait(Str, str_seq); let mut str_add = Self::builtin_methods(Some(poly(ADD, vec![ty_tp(Str)])), 2); - str_add.register_builtin_erg_impl(OP_ADD, fn1_met(Str, Str, Str), Const, Public); - str_add.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Str)); + str_add.register_builtin_erg_impl( + OP_ADD, + fn1_met(Str, Str, Str), + Const, + Visibility::BUILTIN_PUBLIC, + ); + str_add.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Str), + ); str_.register_trait(Str, str_add); let mut str_mul = Self::builtin_methods(Some(poly(MUL, vec![ty_tp(Nat)])), 2); - str_mul.register_builtin_erg_impl(OP_MUL, fn1_met(Str, Nat, Str), Const, Public); - str_mul.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(Str)); + str_mul.register_builtin_erg_impl( + OP_MUL, + fn1_met(Str, Nat, Str), + Const, + Visibility::BUILTIN_PUBLIC, + ); + str_mul.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Str), + ); str_.register_trait(Str, str_mul); let mut str_mutizable = Self::builtin_methods(Some(mono(MUTIZABLE)), 2); str_mutizable.register_builtin_const( MUTABLE_MUT_TYPE, - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(mono(MUT_STR)), ); str_.register_trait(Str, str_mutizable); let mut str_show = Self::builtin_methods(Some(mono(SHOW)), 1); - str_show.register_builtin_erg_impl(TO_STR, fn0_met(Str, Str), Immutable, Public); + str_show.register_builtin_erg_impl( + TO_STR, + fn0_met(Str, Str), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); str_.register_trait(Str, str_show); let mut str_iterable = Self::builtin_methods(Some(poly(ITERABLE, vec![ty_tp(Str)])), 2); str_iterable.register_builtin_py_impl( FUNC_ITER, fn0_met(Str, mono(STR_ITERATOR)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_ITER), ); - str_iterable.register_builtin_const(ITERATOR, vis, ValueObj::builtin_t(mono(STR_ITERATOR))); + str_iterable.register_builtin_const( + ITERATOR, + vis.clone(), + ValueObj::builtin_t(mono(STR_ITERATOR)), + ); str_.register_trait(Str, str_iterable); /* NoneType */ let mut nonetype = Self::builtin_mono_class(NONE_TYPE, 10); @@ -608,11 +923,16 @@ impl Context { OP_EQ, fn1_met(NoneType, NoneType, Bool), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); nonetype.register_trait(NoneType, nonetype_eq); let mut nonetype_show = Self::builtin_methods(Some(mono(SHOW)), 1); - nonetype_show.register_builtin_erg_impl(TO_STR, fn0_met(NoneType, Str), Immutable, Public); + nonetype_show.register_builtin_erg_impl( + TO_STR, + fn0_met(NoneType, Str), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); nonetype.register_trait(NoneType, nonetype_show); /* Type */ let mut type_ = Self::builtin_mono_class(TYPE, 2); @@ -621,11 +941,16 @@ impl Context { FUNC_MRO, array_t(Type, TyParam::erased(Nat)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); type_.register_marker_trait(mono(NAMED)); let mut type_eq = Self::builtin_methods(Some(mono(EQ)), 2); - type_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Type, Type, Bool), Const, Public); + type_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Type, Type, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); type_.register_trait(Type, type_eq); let mut class_type = Self::builtin_mono_class(CLASS_TYPE, 2); class_type.register_superclass(Type, &type_); @@ -635,7 +960,7 @@ impl Context { OP_EQ, fn1_met(ClassType, ClassType, Bool), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); class_type.register_trait(ClassType, class_eq); let mut trait_type = Self::builtin_mono_class(TRAIT_TYPE, 2); @@ -646,54 +971,99 @@ impl Context { OP_EQ, fn1_met(TraitType, TraitType, Bool), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); trait_type.register_trait(TraitType, trait_eq); let mut code = Self::builtin_mono_class(CODE, 10); code.register_superclass(Obj, &obj); - code.register_builtin_erg_impl(FUNC_CO_ARGCOUNT, Nat, Immutable, Public); + code.register_builtin_erg_impl( + FUNC_CO_ARGCOUNT, + Nat, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); code.register_builtin_erg_impl( FUNC_CO_VARNAMES, array_t(Str, TyParam::erased(Nat)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); code.register_builtin_erg_impl( FUNC_CO_CONSTS, array_t(Obj, TyParam::erased(Nat)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); code.register_builtin_erg_impl( FUNC_CO_NAMES, array_t(Str, TyParam::erased(Nat)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); code.register_builtin_erg_impl( FUNC_CO_FREEVARS, array_t(Str, TyParam::erased(Nat)), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); code.register_builtin_erg_impl( FUNC_CO_CELLVARS, array_t(Str, TyParam::erased(Nat)), Immutable, - Public, - ); - code.register_builtin_erg_impl(FUNC_CO_FILENAME, Str, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_NAME, Str, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_FIRSTLINENO, Nat, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_STACKSIZE, Nat, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_FLAGS, Nat, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_CODE, mono(BYTES), Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_LNOTAB, mono(BYTES), Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_NLOCALS, Nat, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_KWONLYARGCOUNT, Nat, Immutable, Public); - code.register_builtin_erg_impl(FUNC_CO_POSONLYARGCOUNT, Nat, Immutable, Public); + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl( + FUNC_CO_FILENAME, + Str, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl(FUNC_CO_NAME, Str, Immutable, Visibility::BUILTIN_PUBLIC); + code.register_builtin_erg_impl( + FUNC_CO_FIRSTLINENO, + Nat, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl( + FUNC_CO_STACKSIZE, + Nat, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl(FUNC_CO_FLAGS, Nat, Immutable, Visibility::BUILTIN_PUBLIC); + code.register_builtin_erg_impl( + FUNC_CO_CODE, + mono(BYTES), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl( + FUNC_CO_LNOTAB, + mono(BYTES), + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl(FUNC_CO_NLOCALS, Nat, Immutable, Visibility::BUILTIN_PUBLIC); + code.register_builtin_erg_impl( + FUNC_CO_KWONLYARGCOUNT, + Nat, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); + code.register_builtin_erg_impl( + FUNC_CO_POSONLYARGCOUNT, + Nat, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let mut code_eq = Self::builtin_methods(Some(mono(EQ)), 2); - code_eq.register_builtin_erg_impl(OP_EQ, fn1_met(Code, Code, Bool), Const, Public); + code_eq.register_builtin_erg_impl( + OP_EQ, + fn1_met(Code, Code, Bool), + Const, + Visibility::BUILTIN_PUBLIC, + ); code.register_trait(Code, code_eq); let g_module_t = mono(GENERIC_MODULE); let mut generic_module = Self::builtin_mono_class(GENERIC_MODULE, 2); @@ -704,7 +1074,7 @@ impl Context { OP_EQ, fn1_met(g_module_t.clone(), g_module_t.clone(), Bool), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); generic_module.register_trait(g_module_t.clone(), generic_module_eq); let Path = mono_q_tp(PATH, instanceof(Str)); @@ -741,9 +1111,13 @@ impl Context { Some(poly(ADD, vec![ty_tp(array_t(T.clone(), M.clone()))])), 2, ); - array_add.register_builtin_erg_impl(OP_ADD, t, Immutable, Public); + array_add.register_builtin_erg_impl(OP_ADD, t, Immutable, Visibility::BUILTIN_PUBLIC); let out_t = array_t(T.clone(), N.clone() + M.clone()); - array_add.register_builtin_const(OUTPUT, Public, ValueObj::builtin_t(out_t)); + array_add.register_builtin_const( + OUTPUT, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(out_t), + ); array_.register_trait(arr_t.clone(), array_add); let t = fn_met( arr_t.clone(), @@ -753,13 +1127,13 @@ impl Context { array_t(T.clone(), N.clone() + value(1usize)), ) .quantify(); - array_.register_builtin_erg_impl(FUNC_PUSH, t, Immutable, Public); + array_.register_builtin_erg_impl(FUNC_PUSH, t, Immutable, Visibility::BUILTIN_PUBLIC); // [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!) let mut_type = ValueObj::builtin_t(poly( MUT_ARRAY, vec![TyParam::t(T.clone()), N.clone().mutate()], )); - array_.register_builtin_const(MUTABLE_MUT_TYPE, Public, mut_type); + array_.register_builtin_const(MUTABLE_MUT_TYPE, Visibility::BUILTIN_PUBLIC, mut_type); let var = StrStruct::from(fresh_varname()); let input = refinement( var.clone(), @@ -775,13 +1149,13 @@ impl Context { array_getitem_t, None, ))); - array_.register_builtin_const(FUNDAMENTAL_GETITEM, Public, get_item); + array_.register_builtin_const(FUNDAMENTAL_GETITEM, Visibility::BUILTIN_PUBLIC, get_item); let mut array_eq = Self::builtin_methods(Some(mono(EQ)), 2); array_eq.register_builtin_erg_impl( OP_EQ, fn1_met(arr_t.clone(), arr_t.clone(), Bool).quantify(), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); array_.register_trait(arr_t.clone(), array_eq); array_.register_marker_trait(mono(MUTIZABLE)); @@ -791,7 +1165,7 @@ impl Context { TO_STR, fn0_met(arr_t.clone(), Str).quantify(), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_STR), ); array_.register_trait(arr_t.clone(), array_show); @@ -803,10 +1177,14 @@ impl Context { FUNC_ITER, t, Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_ITER), ); - array_iterable.register_builtin_const(ITERATOR, vis, ValueObj::builtin_t(array_iter)); + array_iterable.register_builtin_const( + ITERATOR, + vis.clone(), + ValueObj::builtin_t(array_iter), + ); array_.register_trait(arr_t.clone(), array_iterable); let t = fn1_met( array_t(T.clone(), TyParam::erased(Nat)), @@ -842,18 +1220,18 @@ impl Context { array_t(T.clone(), N.clone() + M), ) .quantify(); - set_.register_builtin_erg_impl(FUNC_CONCAT, t, Immutable, Public); + set_.register_builtin_erg_impl(FUNC_CONCAT, t, Immutable, Visibility::BUILTIN_PUBLIC); let mut_type = ValueObj::builtin_t(poly( MUT_SET, vec![TyParam::t(T.clone()), N.clone().mutate()], )); - set_.register_builtin_const(MUTABLE_MUT_TYPE, Public, mut_type); + set_.register_builtin_const(MUTABLE_MUT_TYPE, Visibility::BUILTIN_PUBLIC, mut_type); let mut set_eq = Self::builtin_methods(Some(mono(EQ)), 2); set_eq.register_builtin_erg_impl( OP_EQ, fn1_met(set_t.clone(), set_t.clone(), Bool).quantify(), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); set_.register_trait(set_t.clone(), set_eq); set_.register_marker_trait(mono(MUTIZABLE)); @@ -863,7 +1241,7 @@ impl Context { TO_STR, fn0_met(set_t.clone(), Str).quantify(), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, ); set_.register_trait(set_t.clone(), set_show); let g_dict_t = mono(GENERIC_DICT); @@ -874,13 +1252,18 @@ impl Context { OP_EQ, fn1_met(g_dict_t.clone(), g_dict_t.clone(), Bool).quantify(), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); generic_dict.register_trait(g_dict_t.clone(), generic_dict_eq); let D = mono_q_tp(TY_D, instanceof(mono(GENERIC_DICT))); // .get: _: T -> T or None let dict_get_t = fn1_met(g_dict_t.clone(), T.clone(), or(T.clone(), NoneType)).quantify(); - generic_dict.register_builtin_erg_impl(FUNC_GET, dict_get_t, Immutable, Public); + generic_dict.register_builtin_erg_impl( + FUNC_GET, + dict_get_t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let dict_t = poly(DICT, vec![D.clone()]); let mut dict_ = // TODO: D <: GenericDict @@ -900,7 +1283,7 @@ impl Context { dict_getitem_t, None, ))); - dict_.register_builtin_const(FUNDAMENTAL_GETITEM, Public, get_item); + dict_.register_builtin_const(FUNDAMENTAL_GETITEM, Visibility::BUILTIN_PUBLIC, get_item); /* Bytes */ let mut bytes = Self::builtin_mono_class(BYTES, 2); bytes.register_superclass(Obj, &obj); @@ -920,7 +1303,7 @@ impl Context { OP_EQ, fn1_met(mono(GENERIC_TUPLE), mono(GENERIC_TUPLE), Bool), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); generic_tuple.register_trait(mono(GENERIC_TUPLE), tuple_eq); let Ts = mono_q_tp(TY_TS, instanceof(array_t(Type, N.clone()))); @@ -941,7 +1324,7 @@ impl Context { FUNDAMENTAL_TUPLE_GETITEM, tuple_getitem_t.clone(), Const, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_GETITEM), ); // `__Tuple_getitem__` and `__getitem__` are the same thing @@ -950,7 +1333,7 @@ impl Context { FUNDAMENTAL_GETITEM, tuple_getitem_t, Const, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_GETITEM), ); /* record */ @@ -1005,7 +1388,11 @@ impl Context { let mut obj_mut = Self::builtin_mono_class(MUTABLE_OBJ, 2); obj_mut.register_superclass(Obj, &obj); let mut obj_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - obj_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Obj)); + obj_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Obj), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Int)], None, vec![], Int)); let t = pr_met( ref_mut(mono(MUTABLE_OBJ), None), @@ -1014,13 +1401,22 @@ impl Context { vec![], NoneType, ); - obj_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + obj_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); obj_mut.register_trait(mono(MUTABLE_OBJ), obj_mut_mutable); /* Float! */ let mut float_mut = Self::builtin_mono_class(MUT_FLOAT, 2); float_mut.register_superclass(Float, &float); let mut float_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - float_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Float)); + float_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Float), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Float)], None, vec![], Float)); let t = pr_met( ref_mut(mono(MUT_FLOAT), None), @@ -1029,13 +1425,22 @@ impl Context { vec![], NoneType, ); - float_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + float_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); float_mut.register_trait(mono(MUT_FLOAT), float_mut_mutable); /* Ratio! */ let mut ratio_mut = Self::builtin_mono_class(MUT_RATIO, 2); ratio_mut.register_superclass(Ratio, &ratio); let mut ratio_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - ratio_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Ratio)); + ratio_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Ratio), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Ratio)], None, vec![], Ratio)); let t = pr_met( ref_mut(mono(MUT_RATIO), None), @@ -1044,17 +1449,38 @@ impl Context { vec![], NoneType, ); - ratio_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + ratio_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); ratio_mut.register_trait(mono(MUT_RATIO), ratio_mut_mutable); /* Int! */ let mut int_mut = Self::builtin_mono_class(MUT_INT, 2); int_mut.register_superclass(Int, &int); int_mut.register_superclass(mono(MUT_FLOAT), &float_mut); let t = pr_met(mono(MUT_INT), vec![], None, vec![kw("i", Int)], NoneType); - int_mut.register_builtin_py_impl(PROC_INC, t.clone(), Immutable, Public, Some(FUNC_INC)); - int_mut.register_builtin_py_impl(PROC_DEC, t, Immutable, Public, Some(FUNC_DEC)); + int_mut.register_builtin_py_impl( + PROC_INC, + t.clone(), + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_INC), + ); + int_mut.register_builtin_py_impl( + PROC_DEC, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_DEC), + ); let mut int_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - int_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Int)); + int_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Int), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Int)], None, vec![], Int)); let t = pr_met( ref_mut(mono(MUT_INT), None), @@ -1063,14 +1489,23 @@ impl Context { vec![], NoneType, ); - int_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + int_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); int_mut.register_trait(mono(MUT_INT), int_mut_mutable); let mut nat_mut = Self::builtin_mono_class(MUT_NAT, 2); nat_mut.register_superclass(Nat, &nat); nat_mut.register_superclass(mono(MUT_INT), &int_mut); /* Nat! */ let mut nat_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - nat_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Nat)); + nat_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Nat), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Nat)], None, vec![], Nat)); let t = pr_met( ref_mut(mono(MUT_NAT), None), @@ -1079,14 +1514,23 @@ impl Context { vec![], NoneType, ); - nat_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + nat_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); nat_mut.register_trait(mono(MUT_NAT), nat_mut_mutable); /* Bool! */ let mut bool_mut = Self::builtin_mono_class(MUT_BOOL, 2); bool_mut.register_superclass(Bool, &bool_); bool_mut.register_superclass(mono(MUT_NAT), &nat_mut); let mut bool_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - bool_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Bool)); + bool_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Bool), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Bool)], None, vec![], Bool)); let t = pr_met( ref_mut(mono(MUT_BOOL), None), @@ -1095,15 +1539,30 @@ impl Context { vec![], NoneType, ); - bool_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + bool_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); bool_mut.register_trait(mono(MUT_BOOL), bool_mut_mutable); let t = pr0_met(mono(MUT_BOOL), NoneType); - bool_mut.register_builtin_py_impl(PROC_INVERT, t, Immutable, Public, Some(FUNC_INVERT)); + bool_mut.register_builtin_py_impl( + PROC_INVERT, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_INVERT), + ); /* Str! */ let mut str_mut = Self::builtin_mono_class(MUT_STR, 2); str_mut.register_superclass(Str, &nonetype); let mut str_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - str_mut_mutable.register_builtin_const(IMMUT_TYPE, Public, ValueObj::builtin_t(Str)); + str_mut_mutable.register_builtin_const( + IMMUT_TYPE, + Visibility::BUILTIN_PUBLIC, + ValueObj::builtin_t(Str), + ); let f_t = kw(KW_FUNC, func(vec![kw(KW_OLD, Str)], None, vec![], Str)); let t = pr_met( ref_mut(mono(MUT_STR), None), @@ -1112,7 +1571,12 @@ impl Context { vec![], NoneType, ); - str_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + str_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); str_mut.register_trait(mono(MUT_STR), str_mut_mutable); let t = pr_met( ref_mut(mono(MUT_STR), None), @@ -1121,11 +1585,29 @@ impl Context { vec![], NoneType, ); - str_mut.register_builtin_py_impl(PROC_PUSH, t, Immutable, Public, Some(FUNC_PUSH)); + str_mut.register_builtin_py_impl( + PROC_PUSH, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_PUSH), + ); let t = pr0_met(ref_mut(mono(MUT_STR), None), Str); - str_mut.register_builtin_py_impl(PROC_POP, t, Immutable, Public, Some(FUNC_POP)); + str_mut.register_builtin_py_impl( + PROC_POP, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_POP), + ); let t = pr0_met(ref_mut(mono(MUT_STR), None), NoneType); - str_mut.register_builtin_py_impl(PROC_CLEAR, t, Immutable, Public, Some(FUNC_CLEAR)); + str_mut.register_builtin_py_impl( + PROC_CLEAR, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_CLEAR), + ); let t = pr_met( ref_mut(mono(MUT_STR), None), vec![kw("idx", Nat), kw("s", Str)], @@ -1133,7 +1615,13 @@ impl Context { vec![], NoneType, ); - str_mut.register_builtin_py_impl(PROC_INSERT, t, Immutable, Public, Some(FUNC_INSERT)); + str_mut.register_builtin_py_impl( + PROC_INSERT, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_INSERT), + ); let t = pr_met( ref_mut(mono(MUT_STR), None), vec![kw("idx", Nat)], @@ -1141,7 +1629,13 @@ impl Context { vec![], Str, ); - str_mut.register_builtin_py_impl(PROC_REMOVE, t, Immutable, Public, Some(FUNC_REMOVE)); + str_mut.register_builtin_py_impl( + PROC_REMOVE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_REMOVE), + ); /* File! */ let mut file_mut = Self::builtin_mono_class(MUT_FILE, 2); let mut file_mut_readable = Self::builtin_methods(Some(mono(MUT_READABLE)), 1); @@ -1155,7 +1649,7 @@ impl Context { Str, ), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_READ), ); file_mut.register_trait(mono(MUT_FILE), file_mut_readable); @@ -1164,7 +1658,7 @@ impl Context { PROC_WRITE, pr1_kw_met(ref_mut(mono(MUT_FILE), None), kw(KW_S, Str), Nat), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_WRITE), ); file_mut.register_trait(mono(MUT_FILE), file_mut_writable); @@ -1194,7 +1688,13 @@ impl Context { NoneType, ) .quantify(); - array_mut_.register_builtin_py_impl(PROC_PUSH, t, Immutable, Public, Some(FUNC_APPEND)); + array_mut_.register_builtin_py_impl( + PROC_PUSH, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_APPEND), + ); let t_extend = pr_met( ref_mut( array_mut_t.clone(), @@ -1213,7 +1713,7 @@ impl Context { PROC_EXTEND, t_extend, Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_EXTEND), ); let t_insert = pr_met( @@ -1234,7 +1734,7 @@ impl Context { PROC_INSERT, t_insert, Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_INSERT), ); let t_remove = pr_met( @@ -1255,7 +1755,7 @@ impl Context { PROC_REMOVE, t_remove, Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_REMOVE), ); let t_pop = pr_met( @@ -1272,7 +1772,13 @@ impl Context { T.clone(), ) .quantify(); - array_mut_.register_builtin_py_impl(PROC_POP, t_pop, Immutable, Public, Some(FUNC_POP)); + array_mut_.register_builtin_py_impl( + PROC_POP, + t_pop, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_POP), + ); let t_clear = pr0_met( ref_mut( array_mut_t.clone(), @@ -1285,7 +1791,7 @@ impl Context { PROC_CLEAR, t_clear, Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_CLEAR), ); let t_sort = pr_met( @@ -1299,13 +1805,19 @@ impl Context { NoneType, ) .quantify(); - array_mut_.register_builtin_py_impl(PROC_SORT, t_sort, Immutable, Public, Some(FUNC_SORT)); + array_mut_.register_builtin_py_impl( + PROC_SORT, + t_sort, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_SORT), + ); let t_reverse = pr0_met(ref_mut(array_mut_t.clone(), None), NoneType).quantify(); array_mut_.register_builtin_py_impl( PROC_REVERSE, t_reverse, Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNC_REVERSE), ); let t = pr_met( @@ -1316,7 +1828,12 @@ impl Context { NoneType, ) .quantify(); - array_mut_.register_builtin_erg_impl(PROC_STRICT_MAP, t, Immutable, Public); + array_mut_.register_builtin_erg_impl( + PROC_STRICT_MAP, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let f_t = kw( KW_FUNC, func(vec![kw(KW_OLD, arr_t.clone())], None, vec![], arr_t.clone()), @@ -1330,7 +1847,12 @@ impl Context { ) .quantify(); let mut array_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - array_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + array_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); array_mut_.register_trait(array_mut_t.clone(), array_mut_mutable); /* Set! */ let set_mut_t = poly(MUT_SET, vec![ty_tp(T.clone()), N_MUT]); @@ -1355,7 +1877,13 @@ impl Context { NoneType, ) .quantify(); - set_mut_.register_builtin_py_impl(PROC_ADD, t, Immutable, Public, Some(FUNC_ADD)); + set_mut_.register_builtin_py_impl( + PROC_ADD, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_ADD), + ); let t = pr_met( set_mut_t.clone(), vec![kw(KW_FUNC, nd_func(vec![anon(T.clone())], None, T.clone()))], @@ -1364,7 +1892,12 @@ impl Context { NoneType, ) .quantify(); - set_mut_.register_builtin_erg_impl(PROC_STRICT_MAP, t, Immutable, Public); + set_mut_.register_builtin_erg_impl( + PROC_STRICT_MAP, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let f_t = kw( KW_FUNC, func(vec![kw(KW_OLD, set_t.clone())], None, vec![], set_t.clone()), @@ -1378,7 +1911,12 @@ impl Context { ) .quantify(); let mut set_mut_mutable = Self::builtin_methods(Some(mono(MUTABLE)), 2); - set_mut_mutable.register_builtin_erg_impl(PROC_UPDATE, t, Immutable, Public); + set_mut_mutable.register_builtin_erg_impl( + PROC_UPDATE, + t, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); set_mut_.register_trait(set_mut_t.clone(), set_mut_mutable); /* Range */ let range_t = poly(RANGE, vec![TyParam::t(T.clone())]); @@ -1392,7 +1930,7 @@ impl Context { OP_EQ, fn1_met(range_t.clone(), range_t.clone(), Bool).quantify(), Const, - Public, + Visibility::BUILTIN_PUBLIC, ); range.register_trait(range_t.clone(), range_eq); let mut range_iterable = @@ -1402,10 +1940,14 @@ impl Context { FUNC_ITER, fn0_met(range_t.clone(), range_iter.clone()).quantify(), Immutable, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_ITER), ); - range_iterable.register_builtin_const(ITERATOR, vis, ValueObj::builtin_t(range_iter)); + range_iterable.register_builtin_const( + ITERATOR, + vis.clone(), + ValueObj::builtin_t(range_iter), + ); range.register_trait(range_t.clone(), range_iterable); let range_getitem_t = fn1_kw_met(range_t.clone(), anon(T.clone()), T.clone()).quantify(); let get_item = ValueObj::Subr(ConstSubr::Builtin(BuiltinConstSubr::new( @@ -1414,15 +1956,25 @@ impl Context { range_getitem_t, None, ))); - range.register_builtin_const(FUNDAMENTAL_GETITEM, Public, get_item); + range.register_builtin_const(FUNDAMENTAL_GETITEM, Visibility::BUILTIN_PUBLIC, get_item); let mut g_callable = Self::builtin_mono_class(GENERIC_CALLABLE, 2); g_callable.register_superclass(Obj, &obj); let t_return = fn1_met(mono(GENERIC_CALLABLE), Obj, Never).quantify(); - g_callable.register_builtin_erg_impl(FUNC_RETURN, t_return, Immutable, Public); + g_callable.register_builtin_erg_impl( + FUNC_RETURN, + t_return, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); let mut g_generator = Self::builtin_mono_class(GENERIC_GENERATOR, 2); g_generator.register_superclass(mono(GENERIC_CALLABLE), &g_callable); let t_yield = fn1_met(mono(GENERIC_GENERATOR), Obj, Never).quantify(); - g_generator.register_builtin_erg_impl(FUNC_YIELD, t_yield, Immutable, Public); + g_generator.register_builtin_erg_impl( + FUNC_YIELD, + t_yield, + Immutable, + Visibility::BUILTIN_PUBLIC, + ); /* Proc */ let mut proc = Self::builtin_mono_class(PROC, 2); proc.register_superclass(mono(GENERIC_CALLABLE), &g_callable); @@ -1439,167 +1991,191 @@ impl Context { quant.register_superclass(mono(PROC), &proc); let mut qfunc = Self::builtin_mono_class(QUANTIFIED_FUNC, 2); qfunc.register_superclass(mono(FUNC), &func); - self.register_builtin_type(Never, never, vis, Const, Some(NEVER)); - self.register_builtin_type(Obj, obj, vis, Const, Some(FUNC_OBJECT)); - // self.register_type(mono(RECORD), vec![], record, Private, Const); + self.register_builtin_type(Never, never, vis.clone(), Const, Some(NEVER)); + self.register_builtin_type(Obj, obj, vis.clone(), Const, Some(FUNC_OBJECT)); + // self.register_type(mono(RECORD), vec![], record, Visibility::BUILTIN_PRIVATE, Const); let name = if cfg!(feature = "py_compatible") { FUNC_INT } else { INT }; - self.register_builtin_type(Int, int, vis, Const, Some(name)); - self.register_builtin_type(Nat, nat, vis, Const, Some(NAT)); + self.register_builtin_type(Int, int, vis.clone(), Const, Some(name)); + self.register_builtin_type(Nat, nat, vis.clone(), Const, Some(NAT)); let name = if cfg!(feature = "py_compatible") { FUNC_FLOAT } else { FLOAT }; - self.register_builtin_type(Float, float, vis, Const, Some(name)); - self.register_builtin_type(Ratio, ratio, vis, Const, Some(RATIO)); + self.register_builtin_type(Float, float, vis.clone(), Const, Some(name)); + self.register_builtin_type(Ratio, ratio, vis.clone(), Const, Some(RATIO)); let name = if cfg!(feature = "py_compatible") { FUNC_BOOL } else { BOOL }; - self.register_builtin_type(Bool, bool_, vis, Const, Some(name)); + self.register_builtin_type(Bool, bool_, vis.clone(), Const, Some(name)); let name = if cfg!(feature = "py_compatible") { FUNC_STR } else { STR }; - self.register_builtin_type(Str, str_, vis, Const, Some(name)); - self.register_builtin_type(NoneType, nonetype, vis, Const, Some(NONE_TYPE)); - self.register_builtin_type(Type, type_, vis, Const, Some(FUNC_TYPE)); - self.register_builtin_type(ClassType, class_type, vis, Const, Some(CLASS_TYPE)); - self.register_builtin_type(TraitType, trait_type, vis, Const, Some(TRAIT_TYPE)); - self.register_builtin_type(Code, code, vis, Const, Some(CODE_TYPE)); + self.register_builtin_type(Str, str_, vis.clone(), Const, Some(name)); + self.register_builtin_type(NoneType, nonetype, vis.clone(), Const, Some(NONE_TYPE)); + self.register_builtin_type(Type, type_, vis.clone(), Const, Some(FUNC_TYPE)); + self.register_builtin_type(ClassType, class_type, vis.clone(), Const, Some(CLASS_TYPE)); + self.register_builtin_type(TraitType, trait_type, vis.clone(), Const, Some(TRAIT_TYPE)); + self.register_builtin_type(Code, code, vis.clone(), Const, Some(CODE_TYPE)); self.register_builtin_type( g_module_t, generic_module, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(MODULE_TYPE), ); - self.register_builtin_type(py_module_t, py_module, vis, Const, Some(MODULE_TYPE)); - self.register_builtin_type(arr_t, array_, vis, Const, Some(FUNC_LIST)); - self.register_builtin_type(set_t, set_, vis, Const, Some(FUNC_SET)); - self.register_builtin_type(g_dict_t, generic_dict, vis, Const, Some(FUNC_DICT)); - self.register_builtin_type(dict_t, dict_, vis, Const, Some(FUNC_DICT)); - self.register_builtin_type(mono(BYTES), bytes, vis, Const, Some(BYTES)); + self.register_builtin_type( + py_module_t, + py_module, + vis.clone(), + Const, + Some(MODULE_TYPE), + ); + self.register_builtin_type(arr_t, array_, vis.clone(), Const, Some(FUNC_LIST)); + self.register_builtin_type(set_t, set_, vis.clone(), Const, Some(FUNC_SET)); + self.register_builtin_type(g_dict_t, generic_dict, vis.clone(), Const, Some(FUNC_DICT)); + self.register_builtin_type(dict_t, dict_, vis.clone(), Const, Some(FUNC_DICT)); + self.register_builtin_type(mono(BYTES), bytes, vis.clone(), Const, Some(BYTES)); self.register_builtin_type( mono(GENERIC_TUPLE), generic_tuple, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_TUPLE), ); - self.register_builtin_type(_tuple_t, tuple_, vis, Const, Some(FUNC_TUPLE)); - self.register_builtin_type(mono(RECORD), record, vis, Const, Some(RECORD)); - self.register_builtin_type(or_t, or, vis, Const, Some(UNION)); + self.register_builtin_type(_tuple_t, tuple_, vis.clone(), Const, Some(FUNC_TUPLE)); + self.register_builtin_type(mono(RECORD), record, vis.clone(), Const, Some(RECORD)); + self.register_builtin_type(or_t, or, vis.clone(), Const, Some(UNION)); self.register_builtin_type( mono(STR_ITERATOR), str_iterator, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_STR_ITERATOR), ); self.register_builtin_type( poly(ARRAY_ITERATOR, vec![ty_tp(T.clone())]), array_iterator, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_ARRAY_ITERATOR), ); self.register_builtin_type( poly(RANGE_ITERATOR, vec![ty_tp(T.clone())]), range_iterator, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(RANGE_ITERATOR), ); self.register_builtin_type( poly(ENUMERATE, vec![ty_tp(T.clone())]), enumerate, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_ENUMERATE), ); self.register_builtin_type( poly(FILTER, vec![ty_tp(T.clone())]), filter, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_FILTER), ); self.register_builtin_type( poly(MAP, vec![ty_tp(T.clone())]), map, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_MAP), ); self.register_builtin_type( poly(REVERSED, vec![ty_tp(T.clone())]), reversed, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_REVERSED), ); self.register_builtin_type( poly(ZIP, vec![ty_tp(T), ty_tp(U)]), zip, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(FUNC_ZIP), ); - self.register_builtin_type(mono(MUT_FILE), file_mut, vis, Const, Some(FILE)); - self.register_builtin_type(array_mut_t, array_mut_, vis, Const, Some(FUNC_LIST)); - self.register_builtin_type(set_mut_t, set_mut_, vis, Const, Some(FUNC_SET)); + self.register_builtin_type(mono(MUT_FILE), file_mut, vis.clone(), Const, Some(FILE)); + self.register_builtin_type(array_mut_t, array_mut_, vis.clone(), Const, Some(FUNC_LIST)); + self.register_builtin_type(set_mut_t, set_mut_, vis.clone(), Const, Some(FUNC_SET)); self.register_builtin_type( mono(GENERIC_CALLABLE), g_callable, - vis, + vis.clone(), Const, Some(CALLABLE), ); self.register_builtin_type( mono(GENERIC_GENERATOR), g_generator, - vis, + vis.clone(), Const, Some(GENERATOR), ); - self.register_builtin_type(mono(PROC), proc, vis, Const, Some(PROC)); - self.register_builtin_type(mono(FUNC), func, vis, Const, Some(FUNC)); - self.register_builtin_type(range_t, range, vis, Const, Some(FUNC_RANGE)); + self.register_builtin_type(mono(PROC), proc, vis.clone(), Const, Some(PROC)); + self.register_builtin_type(mono(FUNC), func, vis.clone(), Const, Some(FUNC)); + self.register_builtin_type(range_t, range, vis.clone(), Const, Some(FUNC_RANGE)); if !cfg!(feature = "py_compatible") { - self.register_builtin_type(module_t, module, vis, Const, Some(MODULE_TYPE)); - self.register_builtin_type(mono(MUTABLE_OBJ), obj_mut, vis, Const, Some(FUNC_OBJECT)); - self.register_builtin_type(mono(MUT_INT), int_mut, vis, Const, Some(FUNC_INT)); - self.register_builtin_type(mono(MUT_NAT), nat_mut, vis, Const, Some(NAT)); - self.register_builtin_type(mono(MUT_FLOAT), float_mut, vis, Const, Some(FUNC_FLOAT)); - self.register_builtin_type(mono(MUT_RATIO), ratio_mut, vis, Const, Some(RATIO)); - self.register_builtin_type(mono(MUT_BOOL), bool_mut, vis, Const, Some(BOOL)); + self.register_builtin_type(module_t, module, vis.clone(), Const, Some(MODULE_TYPE)); + self.register_builtin_type( + mono(MUTABLE_OBJ), + obj_mut, + vis.clone(), + Const, + Some(FUNC_OBJECT), + ); + self.register_builtin_type(mono(MUT_INT), int_mut, vis.clone(), Const, Some(FUNC_INT)); + self.register_builtin_type(mono(MUT_NAT), nat_mut, vis.clone(), Const, Some(NAT)); + self.register_builtin_type( + mono(MUT_FLOAT), + float_mut, + vis.clone(), + Const, + Some(FUNC_FLOAT), + ); + self.register_builtin_type(mono(MUT_RATIO), ratio_mut, vis.clone(), Const, Some(RATIO)); + self.register_builtin_type(mono(MUT_BOOL), bool_mut, vis.clone(), Const, Some(BOOL)); self.register_builtin_type(mono(MUT_STR), str_mut, vis, Const, Some(STR)); self.register_builtin_type( mono(NAMED_PROC), named_proc, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(NAMED_PROC), ); self.register_builtin_type( mono(NAMED_FUNC), named_func, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(NAMED_FUNC), ); - self.register_builtin_type(mono(QUANTIFIED), quant, Private, Const, Some(QUANTIFIED)); + self.register_builtin_type( + mono(QUANTIFIED), + quant, + Visibility::BUILTIN_PRIVATE, + Const, + Some(QUANTIFIED), + ); self.register_builtin_type( mono(QUANTIFIED_FUNC), qfunc, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(QUANTIFIED_FUNC), ); diff --git a/crates/erg_compiler/context/initialize/funcs.rs b/crates/erg_compiler/context/initialize/funcs.rs index a541db668..86ebc8e82 100644 --- a/crates/erg_compiler/context/initialize/funcs.rs +++ b/crates/erg_compiler/context/initialize/funcs.rs @@ -1,25 +1,23 @@ #[allow(unused_imports)] use erg_common::log; -use erg_common::vis::{Field, Visibility}; use crate::ty::constructors::*; use crate::ty::typaram::TyParam; use crate::ty::value::ValueObj; -use crate::ty::Type; +use crate::ty::{Field, Type, Visibility}; use Type::*; use crate::context::initialize::*; use crate::context::Context; use crate::varinfo::Mutability; use Mutability::*; -use Visibility::*; impl Context { pub(super) fn init_builtin_funcs(&mut self) { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; let T = mono_q(TY_T, instanceof(Type)); let U = mono_q(TY_U, instanceof(Type)); @@ -222,96 +220,144 @@ impl Context { self.register_py_builtin(FUNC_ANY, t_any, Some(FUNC_ANY), 33); self.register_py_builtin(FUNC_ASCII, t_ascii, Some(FUNC_ASCII), 53); // Leave as `Const`, as it may negatively affect assert casting. - self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis); - self.register_builtin_py_impl(FUNC_BIN, t_bin, Immutable, vis, Some(FUNC_BIN)); - self.register_builtin_py_impl(FUNC_BYTES, t_bytes, Immutable, vis, Some(FUNC_BYTES)); - self.register_builtin_py_impl(FUNC_CHR, t_chr, Immutable, vis, Some(FUNC_CHR)); - self.register_builtin_py_impl(FUNC_CLASSOF, t_classof, Immutable, vis, Some(FUNC_TYPE)); - self.register_builtin_py_impl(FUNC_COMPILE, t_compile, Immutable, vis, Some(FUNC_COMPILE)); - self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis); + self.register_builtin_erg_impl(FUNC_ASSERT, t_assert, Const, vis.clone()); + self.register_builtin_py_impl(FUNC_BIN, t_bin, Immutable, vis.clone(), Some(FUNC_BIN)); + self.register_builtin_py_impl( + FUNC_BYTES, + t_bytes, + Immutable, + vis.clone(), + Some(FUNC_BYTES), + ); + self.register_builtin_py_impl(FUNC_CHR, t_chr, Immutable, vis.clone(), Some(FUNC_CHR)); + self.register_builtin_py_impl( + FUNC_CLASSOF, + t_classof, + Immutable, + vis.clone(), + Some(FUNC_TYPE), + ); + self.register_builtin_py_impl( + FUNC_COMPILE, + t_compile, + Immutable, + vis.clone(), + Some(FUNC_COMPILE), + ); + self.register_builtin_erg_impl(KW_COND, t_cond, Immutable, vis.clone()); self.register_builtin_py_impl( FUNC_ENUMERATE, t_enumerate, Immutable, - vis, + vis.clone(), Some(FUNC_ENUMERATE), ); - self.register_builtin_py_impl(FUNC_EXIT, t_exit, Immutable, vis, Some(FUNC_EXIT)); + self.register_builtin_py_impl(FUNC_EXIT, t_exit, Immutable, vis.clone(), Some(FUNC_EXIT)); self.register_builtin_py_impl( FUNC_ISINSTANCE, t_isinstance, Immutable, - vis, + vis.clone(), Some(FUNC_ISINSTANCE), ); self.register_builtin_py_impl( FUNC_ISSUBCLASS, t_issubclass, Immutable, - vis, + vis.clone(), Some(FUNC_ISSUBCLASS), ); - self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis, Some(FUNC_ITER)); - self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis, Some(FUNC_LEN)); - self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis, Some(FUNC_MAP)); - self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis, Some(FUNC_MAX)); - self.register_builtin_py_impl(FUNC_MIN, t_min, Immutable, vis, Some(FUNC_MIN)); - self.register_builtin_py_impl(FUNC_NOT, t_not, Immutable, vis, None); // `not` is not a function in Python - self.register_builtin_py_impl(FUNC_OCT, t_oct, Immutable, vis, Some(FUNC_OCT)); - self.register_builtin_py_impl(FUNC_ORD, t_ord, Immutable, vis, Some(FUNC_ORD)); - self.register_builtin_py_impl(FUNC_POW, t_pow, Immutable, vis, Some(FUNC_POW)); + self.register_builtin_py_impl(FUNC_ITER, t_iter, Immutable, vis.clone(), Some(FUNC_ITER)); + self.register_builtin_py_impl(FUNC_LEN, t_len, Immutable, vis.clone(), Some(FUNC_LEN)); + self.register_builtin_py_impl(FUNC_MAP, t_map, Immutable, vis.clone(), Some(FUNC_MAP)); + self.register_builtin_py_impl(FUNC_MAX, t_max, Immutable, vis.clone(), Some(FUNC_MAX)); + self.register_builtin_py_impl(FUNC_MIN, t_min, Immutable, vis.clone(), Some(FUNC_MIN)); + self.register_builtin_py_impl(FUNC_NOT, t_not, Immutable, vis.clone(), None); // `not` is not a function in Python + self.register_builtin_py_impl(FUNC_OCT, t_oct, Immutable, vis.clone(), Some(FUNC_OCT)); + self.register_builtin_py_impl(FUNC_ORD, t_ord, Immutable, vis.clone(), Some(FUNC_ORD)); + self.register_builtin_py_impl(FUNC_POW, t_pow, Immutable, vis.clone(), Some(FUNC_POW)); self.register_builtin_py_impl( PYIMPORT, t_pyimport.clone(), Immutable, - vis, + vis.clone(), Some(FUNDAMENTAL_IMPORT), ); - self.register_builtin_py_impl(FUNC_QUIT, t_quit, Immutable, vis, Some(FUNC_QUIT)); - self.register_builtin_py_impl(FUNC_REPR, t_repr, Immutable, vis, Some(FUNC_REPR)); + self.register_builtin_py_impl(FUNC_QUIT, t_quit, Immutable, vis.clone(), Some(FUNC_QUIT)); + self.register_builtin_py_impl(FUNC_REPR, t_repr, Immutable, vis.clone(), Some(FUNC_REPR)); self.register_builtin_py_impl( FUNC_REVERSED, t_reversed, Immutable, - vis, + vis.clone(), Some(FUNC_REVERSED), ); - self.register_builtin_py_impl(FUNC_ROUND, t_round, Immutable, vis, Some(FUNC_ROUND)); - self.register_builtin_py_impl(FUNC_SORTED, t_sorted, Immutable, vis, Some(FUNC_SORTED)); - self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis, Some(FUNC_STR__)); - self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis, Some(FUNC_SUM)); - self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis, Some(FUNC_ZIP)); + self.register_builtin_py_impl( + FUNC_ROUND, + t_round, + Immutable, + vis.clone(), + Some(FUNC_ROUND), + ); + self.register_builtin_py_impl( + FUNC_SORTED, + t_sorted, + Immutable, + vis.clone(), + Some(FUNC_SORTED), + ); + self.register_builtin_py_impl(FUNC_STR, t_str, Immutable, vis.clone(), Some(FUNC_STR__)); + self.register_builtin_py_impl(FUNC_SUM, t_sum, Immutable, vis.clone(), Some(FUNC_SUM)); + self.register_builtin_py_impl(FUNC_ZIP, t_zip, Immutable, vis.clone(), Some(FUNC_ZIP)); let name = if cfg!(feature = "py_compatible") { FUNC_INT } else { FUNC_INT__ }; - self.register_builtin_py_impl(FUNC_INT, t_int, Immutable, vis, Some(name)); + self.register_builtin_py_impl(FUNC_INT, t_int, Immutable, vis.clone(), Some(name)); if !cfg!(feature = "py_compatible") { - self.register_builtin_py_impl(FUNC_IF, t_if, Immutable, vis, Some(FUNC_IF__)); + self.register_builtin_py_impl(FUNC_IF, t_if, Immutable, vis.clone(), Some(FUNC_IF__)); self.register_builtin_py_impl( FUNC_DISCARD, t_discard, Immutable, - vis, + vis.clone(), Some(FUNC_DISCARD__), ); self.register_builtin_py_impl( FUNC_IMPORT, t_import, Immutable, - vis, + vis.clone(), Some(FUNDAMENTAL_IMPORT), ); - self.register_builtin_py_impl(FUNC_LOG, t_log, Immutable, vis, Some(FUNC_PRINT)); - self.register_builtin_py_impl(FUNC_NAT, t_nat, Immutable, vis, Some(FUNC_NAT__)); - self.register_builtin_py_impl(FUNC_PANIC, t_panic, Immutable, vis, Some(FUNC_QUIT)); + self.register_builtin_py_impl( + FUNC_LOG, + t_log, + Immutable, + vis.clone(), + Some(FUNC_PRINT), + ); + self.register_builtin_py_impl( + FUNC_NAT, + t_nat, + Immutable, + vis.clone(), + Some(FUNC_NAT__), + ); + self.register_builtin_py_impl( + FUNC_PANIC, + t_panic, + Immutable, + vis.clone(), + Some(FUNC_QUIT), + ); if cfg!(feature = "debug") { self.register_builtin_py_impl( PY, t_pyimport, Immutable, - vis, + vis.clone(), Some(FUNDAMENTAL_IMPORT), ); } @@ -319,7 +365,7 @@ impl Context { PYCOMPILE, t_pycompile, Immutable, - vis, + vis.clone(), Some(FUNC_COMPILE), ); // TODO: original implementation @@ -340,7 +386,13 @@ impl Context { ], poly(RANGE, vec![ty_tp(Int)]), ); - self.register_builtin_py_impl(FUNC_RANGE, t_range, Immutable, vis, Some(FUNC_RANGE)); + self.register_builtin_py_impl( + FUNC_RANGE, + t_range, + Immutable, + vis.clone(), + Some(FUNC_RANGE), + ); let t_list = func( vec![], None, @@ -348,7 +400,13 @@ impl Context { poly(ARRAY, vec![ty_tp(T.clone()), TyParam::erased(Nat)]), ) .quantify(); - self.register_builtin_py_impl(FUNC_LIST, t_list, Immutable, vis, Some(FUNC_LIST)); + self.register_builtin_py_impl( + FUNC_LIST, + t_list, + Immutable, + vis.clone(), + Some(FUNC_LIST), + ); let t_dict = func( vec![], None, @@ -365,9 +423,9 @@ impl Context { pub(super) fn init_builtin_const_funcs(&mut self) { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; let class_t = func( vec![], @@ -376,7 +434,7 @@ impl Context { ClassType, ); let class = ConstSubr::Builtin(BuiltinConstSubr::new(CLASS, class_func, class_t, None)); - self.register_builtin_const(CLASS, vis, ValueObj::Subr(class)); + self.register_builtin_const(CLASS, vis.clone(), ValueObj::Subr(class)); let inherit_t = func( vec![kw(KW_SUPER, ClassType)], None, @@ -389,7 +447,7 @@ impl Context { inherit_t, None, )); - self.register_builtin_const(INHERIT, vis, ValueObj::Subr(inherit)); + self.register_builtin_const(INHERIT, vis.clone(), ValueObj::Subr(inherit)); let trait_t = func( vec![kw(KW_REQUIREMENT, Type)], None, @@ -397,7 +455,7 @@ impl Context { TraitType, ); let trait_ = ConstSubr::Builtin(BuiltinConstSubr::new(TRAIT, trait_func, trait_t, None)); - self.register_builtin_const(TRAIT, vis, ValueObj::Subr(trait_)); + self.register_builtin_const(TRAIT, vis.clone(), ValueObj::Subr(trait_)); let subsume_t = func( vec![kw(KW_SUPER, TraitType)], None, @@ -410,14 +468,14 @@ impl Context { subsume_t, None, )); - self.register_builtin_const(SUBSUME, vis, ValueObj::Subr(subsume)); + self.register_builtin_const(SUBSUME, vis.clone(), ValueObj::Subr(subsume)); let structural = ConstSubr::Builtin(BuiltinConstSubr::new( STRUCTURAL, structural_func, func1(Type, Type), None, )); - self.register_builtin_const(STRUCTURAL, vis, ValueObj::Subr(structural)); + self.register_builtin_const(STRUCTURAL, vis.clone(), ValueObj::Subr(structural)); // decorators let inheritable_t = func1(ClassType, ClassType); let inheritable = ConstSubr::Builtin(BuiltinConstSubr::new( @@ -426,10 +484,10 @@ impl Context { inheritable_t, None, )); - self.register_builtin_const(INHERITABLE, vis, ValueObj::Subr(inheritable)); + self.register_builtin_const(INHERITABLE, vis.clone(), ValueObj::Subr(inheritable)); // TODO: register Del function object let t_del = nd_func(vec![kw(KW_OBJ, Obj)], None, NoneType); - self.register_builtin_erg_impl(DEL, t_del, Immutable, vis); + self.register_builtin_erg_impl(DEL, t_del, Immutable, vis.clone()); let patch_t = func( vec![kw(KW_REQUIREMENT, Type)], None, @@ -451,65 +509,65 @@ impl Context { proj(L, OUTPUT), ) .quantify(); - self.register_builtin_erg_impl(OP_ADD, op_t, Const, Private); + self.register_builtin_erg_impl(OP_ADD, op_t, Const, Visibility::BUILTIN_PRIVATE); let L = mono_q(TY_L, subtypeof(poly(SUB, params.clone()))); let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify(); - self.register_builtin_erg_impl(OP_SUB, op_t, Const, Private); + self.register_builtin_erg_impl(OP_SUB, op_t, Const, Visibility::BUILTIN_PRIVATE); let L = mono_q(TY_L, subtypeof(poly(MUL, params.clone()))); let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify(); - self.register_builtin_erg_impl(OP_MUL, op_t, Const, Private); + self.register_builtin_erg_impl(OP_MUL, op_t, Const, Visibility::BUILTIN_PRIVATE); let L = mono_q(TY_L, subtypeof(poly(DIV, params.clone()))); let op_t = bin_op(L.clone(), R.clone(), proj(L, OUTPUT)).quantify(); - self.register_builtin_erg_impl(OP_DIV, op_t, Const, Private); + self.register_builtin_erg_impl(OP_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE); let L = mono_q(TY_L, subtypeof(poly(FLOOR_DIV, params))); let op_t = bin_op(L.clone(), R, proj(L, OUTPUT)).quantify(); - self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Private); + self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE); let P = mono_q(TY_P, Constraint::Uninited); let P = mono_q(TY_P, subtypeof(poly(MUL, vec![ty_tp(P)]))); let op_t = bin_op(P.clone(), P.clone(), proj(P, POW_OUTPUT)).quantify(); // TODO: add bound: M == M.Output - self.register_builtin_erg_impl(OP_POW, op_t, Const, Private); + self.register_builtin_erg_impl(OP_POW, op_t, Const, Visibility::BUILTIN_PRIVATE); let M = mono_q(TY_M, Constraint::Uninited); let M = mono_q(TY_M, subtypeof(poly(DIV, vec![ty_tp(M)]))); let op_t = bin_op(M.clone(), M.clone(), proj(M, MOD_OUTPUT)).quantify(); - self.register_builtin_erg_impl(OP_MOD, op_t, Const, Private); + self.register_builtin_erg_impl(OP_MOD, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool); - self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Private); + self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Visibility::BUILTIN_PRIVATE); let E = mono_q(TY_E, subtypeof(mono(EQ))); let op_t = bin_op(E.clone(), E, Bool).quantify(); - self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_NE, op_t, Const, Private); + self.register_builtin_erg_impl(OP_EQ, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE); let O = mono_q(TY_O, subtypeof(mono(ORD))); let op_t = bin_op(O.clone(), O.clone(), Bool).quantify(); - self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_GT, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_GE, op_t, Const, Private); + self.register_builtin_erg_impl(OP_LT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_LE, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_GT, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_GE, op_t, Const, Visibility::BUILTIN_PRIVATE); let BT = mono_q(TY_BT, subtypeof(or(Bool, Type))); let op_t = bin_op(BT.clone(), BT.clone(), BT).quantify(); - self.register_builtin_erg_impl(OP_AND, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_OR, op_t, Const, Private); + self.register_builtin_erg_impl(OP_AND, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_OR, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = bin_op(O.clone(), O.clone(), range(O)).quantify(); - self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Private); - self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Private); - self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Private); - self.register_builtin_erg_decl(OP_ORNG, op_t, Private); + self.register_builtin_erg_decl(OP_RNG, op_t.clone(), Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_decl(OP_LORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_decl(OP_RORNG, op_t.clone(), Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_decl(OP_ORNG, op_t, Visibility::BUILTIN_PRIVATE); // TODO: use existential type: |T: Type| (T, In(T)) -> Bool let T = mono_q(TY_T, instanceof(Type)); let I = mono_q(KW_I, subtypeof(poly(IN, vec![ty_tp(T.clone())]))); let op_t = bin_op(I, T, Bool).quantify(); - self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Private); + self.register_builtin_erg_impl(OP_IN, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_NOT_IN, op_t, Const, Visibility::BUILTIN_PRIVATE); /* unary */ // TODO: +/- Bool would like to be warned let M = mono_q(TY_M, subtypeof(mono(MUTIZABLE))); let op_t = func1(M.clone(), proj(M, MUTABLE_MUT_TYPE)).quantify(); - self.register_builtin_erg_impl(OP_MUTATE, op_t, Const, Private); + self.register_builtin_erg_impl(OP_MUTATE, op_t, Const, Visibility::BUILTIN_PRIVATE); let N = mono_q(TY_N, subtypeof(mono(NUM))); let op_t = func1(N.clone(), N).quantify(); - self.register_builtin_erg_decl(OP_POS, op_t.clone(), Private); - self.register_builtin_erg_decl(OP_NEG, op_t, Private); + self.register_builtin_erg_decl(OP_POS, op_t.clone(), Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PRIVATE); } pub(super) fn init_py_builtin_operators(&mut self) { @@ -525,7 +583,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_ADD, op_t, Const, Private); + self.register_builtin_erg_impl(OP_ADD, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__sub__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -533,7 +591,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_SUB, op_t, Const, Private); + self.register_builtin_erg_impl(OP_SUB, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__mul__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -541,7 +599,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_MUL, op_t, Const, Private); + self.register_builtin_erg_impl(OP_MUL, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__div__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -549,7 +607,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_DIV, op_t, Const, Private); + self.register_builtin_erg_impl(OP_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__floordiv__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -557,7 +615,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Private); + self.register_builtin_erg_impl(OP_FLOOR_DIV, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__pow__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -565,7 +623,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_POW, op_t, Const, Private); + self.register_builtin_erg_impl(OP_POW, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__mod__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -573,10 +631,10 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_MOD, op_t, Const, Private); + self.register_builtin_erg_impl(OP_MOD, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = nd_proc(vec![kw(KW_LHS, Obj), kw(KW_RHS, Obj)], None, Bool); - self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Private); - self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Private); + self.register_builtin_erg_impl(OP_IS, op_t.clone(), Const, Visibility::BUILTIN_PRIVATE); + self.register_builtin_erg_impl(OP_IS_NOT, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__eq__".into()) => fn1_met(Never, R.clone(), Bool) }, @@ -584,7 +642,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), Bool).quantify() }; - self.register_builtin_erg_impl(OP_EQ, op_t, Const, Private); + self.register_builtin_erg_impl(OP_EQ, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__ne__".into()) => fn1_met(Never, R.clone(), Bool) }, @@ -592,7 +650,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), Bool).quantify() }; - self.register_builtin_erg_impl(OP_NE, op_t, Const, Private); + self.register_builtin_erg_impl(OP_NE, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__lt__".into()) => fn1_met(Never, R.clone(), Bool) }, @@ -600,7 +658,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), Bool).quantify() }; - self.register_builtin_erg_impl(OP_LT, op_t, Const, Private); + self.register_builtin_erg_impl(OP_LT, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__le__".into()) => fn1_met(Never, R.clone(), Bool) }, @@ -608,7 +666,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), Bool).quantify() }; - self.register_builtin_erg_impl(OP_LE, op_t, Const, Private); + self.register_builtin_erg_impl(OP_LE, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__gt__".into()) => fn1_met(Never, R.clone(), Bool) }, @@ -616,7 +674,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), Bool).quantify() }; - self.register_builtin_erg_impl(OP_GT, op_t, Const, Private); + self.register_builtin_erg_impl(OP_GT, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__ge__".into()) => fn1_met(Never, R.clone(), Bool) }, @@ -624,7 +682,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), Bool).quantify() }; - self.register_builtin_erg_impl(OP_GE, op_t, Const, Private); + self.register_builtin_erg_impl(OP_GE, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__and__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -632,7 +690,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O.clone()).quantify() }; - self.register_builtin_erg_impl(OP_AND, op_t, Const, Private); + self.register_builtin_erg_impl(OP_AND, op_t, Const, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from( dict! { Field::public("__or__".into()) => fn1_met(Never, R.clone(), O.clone()) }, @@ -640,7 +698,7 @@ impl Context { .structuralize(); bin_op(S, R.clone(), O).quantify() }; - self.register_builtin_erg_impl(OP_OR, op_t, Const, Private); + self.register_builtin_erg_impl(OP_OR, op_t, Const, Visibility::BUILTIN_PRIVATE); /* unary */ let op_t = { let S = @@ -648,13 +706,13 @@ impl Context { .structuralize(); func1(S, R.clone()).quantify() }; - self.register_builtin_erg_decl(OP_POS, op_t, Private); + self.register_builtin_erg_decl(OP_POS, op_t, Visibility::BUILTIN_PRIVATE); let op_t = { let S = Type::from(dict! { Field::public("__neg__".into()) => fn0_met(Never, R.clone()) }) .structuralize(); func1(S, R).quantify() }; - self.register_builtin_erg_decl(OP_NEG, op_t, Private); + self.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PRIVATE); } } diff --git a/crates/erg_compiler/context/initialize/mod.rs b/crates/erg_compiler/context/initialize/mod.rs index 9fa0597a0..a7110ad0c 100644 --- a/crates/erg_compiler/context/initialize/mod.rs +++ b/crates/erg_compiler/context/initialize/mod.rs @@ -18,28 +18,26 @@ use erg_common::error::Location; use erg_common::fresh::fresh_varname; #[allow(unused_imports)] use erg_common::log; -use erg_common::vis::Visibility; use erg_common::Str; use erg_common::{set, unique_in_place}; use erg_parser::ast::VarName; use crate::context::initialize::const_func::*; -use crate::context::instantiate::ConstTemplate; +use crate::context::instantiate_spec::ConstTemplate; use crate::context::{ ClassDefType, Context, ContextKind, MethodInfo, ModuleContext, ParamSpec, TraitImpl, }; use crate::module::SharedCompilerResource; use crate::ty::free::Constraint; use crate::ty::value::ValueObj; -use crate::ty::Type; use crate::ty::{constructors::*, BuiltinConstSubr, ConstSubr, Predicate}; +use crate::ty::{Type, Visibility}; use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use Mutability::*; use ParamSpec as PS; use Type::*; use VarKind::*; -use Visibility::*; const NUM: &str = "Num"; @@ -543,7 +541,7 @@ impl Context { ); if let Some(_vi) = self.locals.get(&name) { if _vi != &vi { - panic!("already registered: {} {name}", self.name); + unreachable!("already registered: {} {name}", self.name); } } else { self.locals.insert(name, vi); @@ -599,9 +597,9 @@ impl Context { VarName::from_static(name) }; let vis = if cfg!(feature = "py_compatible") || &self.name[..] != "" { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; let muty = Immutable; let loc = Location::range(lineno, 0, lineno, name.inspect().len() as u32); @@ -859,50 +857,56 @@ impl Context { fn init_builtin_consts(&mut self) { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; // TODO: this is not a const, but a special property self.register_builtin_py_impl( FUNDAMENTAL_NAME, Str, Immutable, - vis, + vis.clone(), Some(FUNDAMENTAL_NAME), ); self.register_builtin_py_impl( LICENSE, mono(SITEBUILTINS_PRINTER), Immutable, - vis, + vis.clone(), Some(LICENSE), ); self.register_builtin_py_impl( CREDITS, mono(SITEBUILTINS_PRINTER), Immutable, - vis, + vis.clone(), Some(CREDITS), ); self.register_builtin_py_impl( COPYRIGHT, mono(SITEBUILTINS_PRINTER), Immutable, - vis, + vis.clone(), Some(COPYRIGHT), ); self.register_builtin_py_impl( NOT_IMPLEMENTED, NotImplementedType, Const, - vis, + vis.clone(), Some(NOT_IMPLEMENTED), ); self.register_builtin_py_impl(ELLIPSIS, Ellipsis, Const, vis, Some(ELLIPSIS)); - self.register_builtin_py_impl(TRUE, Bool, Const, Private, Some(TRUE)); - self.register_builtin_py_impl(FALSE, Bool, Const, Private, Some(FALSE)); - self.register_builtin_py_impl(NONE, NoneType, Const, Private, Some(NONE)); + self.register_builtin_py_impl(TRUE, Bool, Const, Visibility::BUILTIN_PRIVATE, Some(TRUE)); + self.register_builtin_py_impl(FALSE, Bool, Const, Visibility::BUILTIN_PRIVATE, Some(FALSE)); + self.register_builtin_py_impl( + NONE, + NoneType, + Const, + Visibility::BUILTIN_PRIVATE, + Some(NONE), + ); } pub(crate) fn init_builtins(cfg: ErgConfig, shared: SharedCompilerResource) { diff --git a/crates/erg_compiler/context/initialize/patches.rs b/crates/erg_compiler/context/initialize/patches.rs index 3786ab095..892fea6a6 100644 --- a/crates/erg_compiler/context/initialize/patches.rs +++ b/crates/erg_compiler/context/initialize/patches.rs @@ -1,18 +1,16 @@ #[allow(unused_imports)] use erg_common::log; -use erg_common::vis::Visibility; use crate::ty::constructors::*; use crate::ty::typaram::TyParam; use crate::ty::value::ValueObj; -use crate::ty::Type; +use crate::ty::{Type, Visibility}; use Type::*; use crate::context::initialize::*; use crate::context::Context; use crate::varinfo::Mutability; use Mutability::*; -use Visibility::*; impl Context { pub(super) fn init_builtin_patches(&mut self) { @@ -38,10 +36,10 @@ impl Context { ) .quantify(); let mut interval_add = Self::builtin_methods(Some(impls), 2); - interval_add.register_builtin_erg_impl("__add__", op_t, Const, Public); + interval_add.register_builtin_erg_impl("__add__", op_t, Const, Visibility::BUILTIN_PUBLIC); interval_add.register_builtin_const( "Output", - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(Type::from(m.clone() + o.clone()..=n.clone() + p.clone())), ); interval.register_trait(class.clone(), interval_add); @@ -53,18 +51,18 @@ impl Context { Type::from(m.clone() - p.clone()..=n.clone() - o.clone()), ) .quantify(); - interval_sub.register_builtin_erg_impl("__sub__", op_t, Const, Public); + interval_sub.register_builtin_erg_impl("__sub__", op_t, Const, Visibility::BUILTIN_PUBLIC); interval_sub.register_builtin_const( "Output", - Public, + Visibility::BUILTIN_PUBLIC, ValueObj::builtin_t(Type::from(m - p..=n - o)), ); interval.register_trait(class, interval_sub); - self.register_builtin_patch("Interval", interval, Private, Const); - // eq.register_impl("__ne__", op_t, Const, Public); - // ord.register_impl("__le__", op_t.clone(), Const, Public); - // ord.register_impl("__gt__", op_t.clone(), Const, Public); - // ord.register_impl("__ge__", op_t, Const, Public); + self.register_builtin_patch("Interval", interval, Visibility::BUILTIN_PRIVATE, Const); + // eq.register_impl("__ne__", op_t, Const, Visibility::BUILTIN_PUBLIC); + // ord.register_impl("__le__", op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + // ord.register_impl("__gt__", op_t.clone(), Const, Visibility::BUILTIN_PUBLIC); + // ord.register_impl("__ge__", op_t, Const, Visibility::BUILTIN_PUBLIC); let E = mono_q("E", subtypeof(mono("Eq"))); let base = or(E, NoneType); let impls = mono("Eq"); @@ -73,8 +71,8 @@ impl Context { Self::builtin_poly_glue_patch("OptionEq", base.clone(), impls.clone(), params, 1); let mut option_eq_impl = Self::builtin_methods(Some(impls), 1); let op_t = fn1_met(base.clone(), base.clone(), Bool).quantify(); - option_eq_impl.register_builtin_erg_impl("__eq__", op_t, Const, Public); + option_eq_impl.register_builtin_erg_impl("__eq__", op_t, Const, Visibility::BUILTIN_PUBLIC); option_eq.register_trait(base, option_eq_impl); - self.register_builtin_patch("OptionEq", option_eq, Private, Const); + self.register_builtin_patch("OptionEq", option_eq, Visibility::BUILTIN_PRIVATE, Const); } } diff --git a/crates/erg_compiler/context/initialize/procs.rs b/crates/erg_compiler/context/initialize/procs.rs index 324cebcfb..0e51c9553 100644 --- a/crates/erg_compiler/context/initialize/procs.rs +++ b/crates/erg_compiler/context/initialize/procs.rs @@ -1,24 +1,22 @@ #[allow(unused_imports)] use erg_common::log; -use erg_common::vis::Visibility; use crate::ty::constructors::*; use crate::ty::typaram::TyParam; -use crate::ty::Type; +use crate::ty::{Type, Visibility}; use Type::*; use crate::context::initialize::*; use crate::context::Context; use crate::varinfo::Mutability; use Mutability::*; -use Visibility::*; impl Context { pub(super) fn init_builtin_procs(&mut self) { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; let T = mono_q("T", instanceof(Type)); let U = mono_q("U", instanceof(Type)); @@ -119,32 +117,38 @@ impl Context { U, ) .quantify(); - self.register_builtin_py_impl("dir!", t_dir, Immutable, vis, Some("dir")); + self.register_builtin_py_impl("dir!", t_dir, Immutable, vis.clone(), Some("dir")); self.register_py_builtin("print!", t_print, Some("print"), 81); - self.register_builtin_py_impl("id!", t_id, Immutable, vis, Some("id")); - self.register_builtin_py_impl("input!", t_input, Immutable, vis, Some("input")); - self.register_builtin_py_impl("globals!", t_globals, Immutable, vis, Some("globals")); - self.register_builtin_py_impl("locals!", t_locals, Immutable, vis, Some("locals")); - self.register_builtin_py_impl("next!", t_next, Immutable, vis, Some("next")); + self.register_builtin_py_impl("id!", t_id, Immutable, vis.clone(), Some("id")); + self.register_builtin_py_impl("input!", t_input, Immutable, vis.clone(), Some("input")); + self.register_builtin_py_impl( + "globals!", + t_globals, + Immutable, + vis.clone(), + Some("globals"), + ); + self.register_builtin_py_impl("locals!", t_locals, Immutable, vis.clone(), Some("locals")); + self.register_builtin_py_impl("next!", t_next, Immutable, vis.clone(), Some("next")); self.register_py_builtin("open!", t_open, Some("open"), 198); let name = if cfg!(feature = "py_compatible") { "if" } else { "if__" }; - self.register_builtin_py_impl("if!", t_if, Immutable, vis, Some(name)); + self.register_builtin_py_impl("if!", t_if, Immutable, vis.clone(), Some(name)); let name = if cfg!(feature = "py_compatible") { "for" } else { "for__" }; - self.register_builtin_py_impl("for!", t_for, Immutable, vis, Some(name)); + self.register_builtin_py_impl("for!", t_for, Immutable, vis.clone(), Some(name)); let name = if cfg!(feature = "py_compatible") { "while" } else { "while__" }; - self.register_builtin_py_impl("while!", t_while, Immutable, vis, Some(name)); + self.register_builtin_py_impl("while!", t_while, Immutable, vis.clone(), Some(name)); let name = if cfg!(feature = "py_compatible") { "with" } else { diff --git a/crates/erg_compiler/context/initialize/traits.rs b/crates/erg_compiler/context/initialize/traits.rs index a15f6e204..4acfb6b2e 100644 --- a/crates/erg_compiler/context/initialize/traits.rs +++ b/crates/erg_compiler/context/initialize/traits.rs @@ -1,11 +1,10 @@ #[allow(unused_imports)] use erg_common::log; -use erg_common::vis::Visibility; use crate::ty::constructors::*; use crate::ty::typaram::TyParam; use crate::ty::value::ValueObj; -use crate::ty::Type; +use crate::ty::{Type, Visibility}; use ParamSpec as PS; use Type::*; @@ -14,7 +13,6 @@ use crate::context::{ConstTemplate, Context, DefaultInfo, ParamSpec}; use crate::varinfo::Mutability; use DefaultInfo::*; use Mutability::*; -use Visibility::*; impl Context { /// see std/prelude.er @@ -24,9 +22,9 @@ impl Context { // push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する pub(super) fn init_builtin_traits(&mut self) { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::BUILTIN_PRIVATE }; let unpack = Self::builtin_mono_trait(UNPACK, 2); let inheritable_type = Self::builtin_mono_trait(INHERITABLE_TYPE, 2); @@ -36,25 +34,35 @@ impl Context { let immut_t = proj(Slf.clone(), IMMUT_TYPE); let f_t = func(vec![kw(KW_OLD, immut_t.clone())], None, vec![], immut_t); let t = pr1_met(ref_mut(Slf, None), f_t, NoneType).quantify(); - mutable.register_builtin_erg_decl(PROC_UPDATE, t, Public); + mutable.register_builtin_erg_decl(PROC_UPDATE, t, Visibility::BUILTIN_PUBLIC); // REVIEW: Immutatable? let mut immutizable = Self::builtin_mono_trait(IMMUTIZABLE, 2); immutizable.register_superclass(mono(MUTABLE), &mutable); - immutizable.register_builtin_erg_decl(IMMUT_TYPE, Type, Public); + immutizable.register_builtin_erg_decl(IMMUT_TYPE, Type, Visibility::BUILTIN_PUBLIC); // REVIEW: Mutatable? let mut mutizable = Self::builtin_mono_trait(MUTIZABLE, 2); - mutizable.register_builtin_erg_decl(MUTABLE_MUT_TYPE, Type, Public); + mutizable.register_builtin_erg_decl(MUTABLE_MUT_TYPE, Type, Visibility::BUILTIN_PUBLIC); let pathlike = Self::builtin_mono_trait(PATH_LIKE, 2); /* Readable */ let mut readable = Self::builtin_mono_trait(MUTABLE_READABLE, 2); let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_READABLE))); let t_read = pr_met(ref_mut(Slf, None), vec![], None, vec![kw(KW_N, Int)], Str).quantify(); - readable.register_builtin_py_decl(PROC_READ, t_read, Public, Some(FUNC_READ)); + readable.register_builtin_py_decl( + PROC_READ, + t_read, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_READ), + ); /* Writable */ let mut writable = Self::builtin_mono_trait(MUTABLE_WRITABLE, 2); let Slf = mono_q(SELF, subtypeof(mono(MUTABLE_WRITABLE))); let t_write = pr1_kw_met(ref_mut(Slf, None), kw("s", Str), Nat).quantify(); - writable.register_builtin_py_decl(PROC_WRITE, t_write, Public, Some(FUNC_WRITE)); + writable.register_builtin_py_decl( + PROC_WRITE, + t_write, + Visibility::BUILTIN_PUBLIC, + Some(FUNC_WRITE), + ); // TODO: Add required methods let mut filelike = Self::builtin_mono_trait(FILE_LIKE, 2); filelike.register_superclass(mono(READABLE), &readable); @@ -65,7 +73,12 @@ impl Context { let mut show = Self::builtin_mono_trait(SHOW, 2); let Slf = mono_q(SELF, subtypeof(mono(SHOW))); let t_show = fn0_met(ref_(Slf), Str).quantify(); - show.register_builtin_py_decl(TO_STR, t_show, Public, Some(FUNDAMENTAL_STR)); + show.register_builtin_py_decl( + TO_STR, + t_show, + Visibility::BUILTIN_PUBLIC, + Some(FUNDAMENTAL_STR), + ); /* In */ let mut in_ = Self::builtin_poly_trait(IN, vec![PS::t_nd(TY_T)], 2); let params = vec![PS::t_nd(TY_T)]; @@ -75,7 +88,7 @@ impl Context { let I = mono_q(TY_I, subtypeof(poly(IN, vec![ty_tp(T.clone())]))); in_.register_superclass(poly(INPUT, vec![ty_tp(T.clone())]), &input); let op_t = fn1_met(T.clone(), I, Bool).quantify(); - in_.register_builtin_erg_decl(OP_IN, op_t, Public); + in_.register_builtin_erg_decl(OP_IN, op_t, Visibility::BUILTIN_PUBLIC); /* Eq */ // Erg does not have a trait equivalent to `PartialEq` in Rust // This means, Erg's `Float` cannot be compared with other `Float` @@ -84,13 +97,13 @@ impl Context { let Slf = mono_q(SELF, subtypeof(mono(EQ))); // __eq__: |Self <: Eq| (self: Self, other: Self) -> Bool let op_t = fn1_met(Slf.clone(), Slf, Bool).quantify(); - eq.register_builtin_erg_decl(OP_EQ, op_t, Public); + eq.register_builtin_erg_decl(OP_EQ, op_t, Visibility::BUILTIN_PUBLIC); /* Ord */ let mut ord = Self::builtin_mono_trait(ORD, 2); ord.register_superclass(mono(EQ), &eq); let Slf = mono_q(SELF, subtypeof(mono(ORD))); let op_t = fn1_met(Slf.clone(), Slf, or(mono(ORDERING), NoneType)).quantify(); - ord.register_builtin_erg_decl(OP_CMP, op_t, Public); + ord.register_builtin_erg_decl(OP_CMP, op_t, Visibility::BUILTIN_PUBLIC); // FIXME: poly trait /* Num */ let num = Self::builtin_mono_trait(NUM, 2); @@ -104,24 +117,29 @@ impl Context { seq.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(SEQ, vec![TyParam::erased(Type)]))); let t = fn0_met(Slf.clone(), Nat).quantify(); - seq.register_builtin_erg_decl(FUNC_LEN, t, Public); + seq.register_builtin_erg_decl(FUNC_LEN, t, Visibility::BUILTIN_PUBLIC); let t = fn1_met(Slf, Nat, T.clone()).quantify(); // Seq.get: |Self <: Seq(T)| Self.(Nat) -> T - seq.register_builtin_erg_decl(FUNC_GET, t, Public); + seq.register_builtin_erg_decl(FUNC_GET, t, Visibility::BUILTIN_PUBLIC); /* Iterable */ let mut iterable = Self::builtin_poly_trait(ITERABLE, vec![PS::t_nd(TY_T)], 2); iterable.register_superclass(poly(OUTPUT, vec![ty_tp(T.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(ITERABLE, vec![ty_tp(T.clone())]))); let t = fn0_met(Slf.clone(), proj(Slf, ITER)).quantify(); - iterable.register_builtin_py_decl(FUNC_ITER, t, Public, Some(FUNDAMENTAL_ITER)); - iterable.register_builtin_erg_decl(ITER, Type, Public); + iterable.register_builtin_py_decl( + FUNC_ITER, + t, + Visibility::BUILTIN_PUBLIC, + Some(FUNDAMENTAL_ITER), + ); + iterable.register_builtin_erg_decl(ITER, Type, Visibility::BUILTIN_PUBLIC); let mut context_manager = Self::builtin_mono_trait(CONTEXT_MANAGER, 2); let Slf = mono_q(SELF, subtypeof(mono(CONTEXT_MANAGER))); let t = fn0_met(Slf.clone(), NoneType).quantify(); context_manager.register_builtin_py_decl( FUNDAMENTAL_ENTER, t, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_ENTER), ); let t = fn_met( @@ -139,7 +157,7 @@ impl Context { context_manager.register_builtin_py_decl( FUNDAMENTAL_EXIT, t, - Public, + Visibility::BUILTIN_PUBLIC, Some(FUNDAMENTAL_EXIT), ); let R = mono_q(TY_R, instanceof(Type)); @@ -152,111 +170,141 @@ impl Context { add.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(ADD, ty_params.clone()))); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); - add.register_builtin_erg_decl(OP_ADD, op_t, Public); - add.register_builtin_erg_decl(OUTPUT, Type, Public); + add.register_builtin_erg_decl(OP_ADD, op_t, Visibility::BUILTIN_PUBLIC); + add.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); /* Sub */ let mut sub = Self::builtin_poly_trait(SUB, params.clone(), 2); sub.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(SUB, ty_params.clone()))); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); - sub.register_builtin_erg_decl(OP_SUB, op_t, Public); - sub.register_builtin_erg_decl(OUTPUT, Type, Public); + sub.register_builtin_erg_decl(OP_SUB, op_t, Visibility::BUILTIN_PUBLIC); + sub.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); /* Mul */ let mut mul = Self::builtin_poly_trait(MUL, params.clone(), 2); mul.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(MUL, ty_params.clone()))); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); - mul.register_builtin_erg_decl(OP_MUL, op_t, Public); - mul.register_builtin_erg_decl(OUTPUT, Type, Public); + mul.register_builtin_erg_decl(OP_MUL, op_t, Visibility::BUILTIN_PUBLIC); + mul.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); /* Div */ let mut div = Self::builtin_poly_trait(DIV, params.clone(), 2); div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(DIV, ty_params.clone()))); let op_t = fn1_met(Slf.clone(), R.clone(), proj(Slf, OUTPUT)).quantify(); - div.register_builtin_erg_decl(OP_DIV, op_t, Public); - div.register_builtin_erg_decl(OUTPUT, Type, Public); + div.register_builtin_erg_decl(OP_DIV, op_t, Visibility::BUILTIN_PUBLIC); + div.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); /* FloorDiv */ let mut floor_div = Self::builtin_poly_trait(FLOOR_DIV, params, 2); floor_div.register_superclass(poly(OUTPUT, vec![ty_tp(R.clone())]), &output); let Slf = mono_q(SELF, subtypeof(poly(FLOOR_DIV, ty_params.clone()))); let op_t = fn1_met(Slf.clone(), R, proj(Slf.clone(), OUTPUT)).quantify(); - floor_div.register_builtin_erg_decl(OP_FLOOR_DIV, op_t, Public); - floor_div.register_builtin_erg_decl(OUTPUT, Type, Public); + floor_div.register_builtin_erg_decl(OP_FLOOR_DIV, op_t, Visibility::BUILTIN_PUBLIC); + floor_div.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); /* Pos */ let mut pos = Self::builtin_mono_trait(POS, 2); let _Slf = mono_q(SELF, subtypeof(mono(POS))); let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify(); - pos.register_builtin_erg_decl(OP_POS, op_t, Public); - pos.register_builtin_erg_decl(OUTPUT, Type, Public); + pos.register_builtin_erg_decl(OP_POS, op_t, Visibility::BUILTIN_PUBLIC); + pos.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); /* Neg */ let mut neg = Self::builtin_mono_trait(NEG, 2); let _Slf = mono_q(SELF, subtypeof(mono(NEG))); let op_t = fn0_met(_Slf.clone(), proj(_Slf, OUTPUT)).quantify(); - neg.register_builtin_erg_decl(OP_NEG, op_t, Public); - neg.register_builtin_erg_decl(OUTPUT, Type, Public); - self.register_builtin_type(mono(UNPACK), unpack, vis, Const, None); + neg.register_builtin_erg_decl(OP_NEG, op_t, Visibility::BUILTIN_PUBLIC); + neg.register_builtin_erg_decl(OUTPUT, Type, Visibility::BUILTIN_PUBLIC); + self.register_builtin_type(mono(UNPACK), unpack, vis.clone(), Const, None); self.register_builtin_type( mono(INHERITABLE_TYPE), inheritable_type, - Private, + Visibility::BUILTIN_PRIVATE, Const, None, ); - self.register_builtin_type(mono(NAMED), named, vis, Const, None); - self.register_builtin_type(mono(MUTABLE), mutable, vis, Const, None); - self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis, Const, None); - self.register_builtin_type(mono(MUTIZABLE), mutizable, vis, Const, None); - self.register_builtin_type(mono(PATH_LIKE), pathlike, vis, Const, None); + self.register_builtin_type(mono(NAMED), named, vis.clone(), Const, None); + self.register_builtin_type(mono(MUTABLE), mutable, vis.clone(), Const, None); + self.register_builtin_type(mono(IMMUTIZABLE), immutizable, vis.clone(), Const, None); + self.register_builtin_type(mono(MUTIZABLE), mutizable, vis.clone(), Const, None); + self.register_builtin_type(mono(PATH_LIKE), pathlike, vis.clone(), Const, None); self.register_builtin_type( mono(MUTABLE_READABLE), readable, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(READABLE), ); self.register_builtin_type( mono(MUTABLE_WRITABLE), writable, - Private, + Visibility::BUILTIN_PRIVATE, Const, Some(WRITABLE), ); - self.register_builtin_type(mono(FILE_LIKE), filelike, vis, Const, None); - self.register_builtin_type(mono(MUTABLE_FILE_LIKE), filelike_mut, vis, Const, None); - self.register_builtin_type(mono(SHOW), show, vis, Const, None); + self.register_builtin_type(mono(FILE_LIKE), filelike, vis.clone(), Const, None); + self.register_builtin_type( + mono(MUTABLE_FILE_LIKE), + filelike_mut, + vis.clone(), + Const, + None, + ); + self.register_builtin_type(mono(SHOW), show, vis.clone(), Const, None); self.register_builtin_type( poly(INPUT, vec![ty_tp(T.clone())]), input, - Private, + Visibility::BUILTIN_PRIVATE, Const, None, ); self.register_builtin_type( poly(OUTPUT, vec![ty_tp(T.clone())]), output, - Private, + Visibility::BUILTIN_PRIVATE, + Const, + None, + ); + self.register_builtin_type( + poly(IN, vec![ty_tp(T.clone())]), + in_, + Visibility::BUILTIN_PRIVATE, + Const, + None, + ); + self.register_builtin_type(mono(EQ), eq, vis.clone(), Const, None); + self.register_builtin_type(mono(ORD), ord, vis.clone(), Const, None); + self.register_builtin_type(mono(NUM), num, vis.clone(), Const, None); + self.register_builtin_type( + poly(SEQ, vec![ty_tp(T.clone())]), + seq, + Visibility::BUILTIN_PRIVATE, Const, None, ); - self.register_builtin_type(poly(IN, vec![ty_tp(T.clone())]), in_, Private, Const, None); - self.register_builtin_type(mono(EQ), eq, vis, Const, None); - self.register_builtin_type(mono(ORD), ord, vis, Const, None); - self.register_builtin_type(mono(NUM), num, vis, Const, None); - self.register_builtin_type(poly(SEQ, vec![ty_tp(T.clone())]), seq, Private, Const, None); self.register_builtin_type( poly(ITERABLE, vec![ty_tp(T)]), iterable, - Private, + Visibility::BUILTIN_PRIVATE, + Const, + None, + ); + self.register_builtin_type( + mono(CONTEXT_MANAGER), + context_manager, + Visibility::BUILTIN_PRIVATE, + Const, + None, + ); + self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis.clone(), Const, None); + self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis.clone(), Const, None); + self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis.clone(), Const, None); + self.register_builtin_type(poly(DIV, ty_params.clone()), div, vis.clone(), Const, None); + self.register_builtin_type( + poly(FLOOR_DIV, ty_params), + floor_div, + vis.clone(), Const, None, ); - self.register_builtin_type(mono(CONTEXT_MANAGER), context_manager, Private, Const, None); - self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis, Const, None); - self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis, Const, None); - self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis, Const, None); - self.register_builtin_type(poly(DIV, ty_params.clone()), div, vis, Const, None); - self.register_builtin_type(poly(FLOOR_DIV, ty_params), floor_div, vis, Const, None); - self.register_builtin_type(mono(POS), pos, vis, Const, None); + self.register_builtin_type(mono(POS), pos, vis.clone(), Const, None); self.register_builtin_type(mono(NEG), neg, vis, Const, None); self.register_const_param_defaults( ADD, diff --git a/crates/erg_compiler/context/inquire.rs b/crates/erg_compiler/context/inquire.rs index af0f80d5b..86ea16971 100644 --- a/crates/erg_compiler/context/inquire.rs +++ b/crates/erg_compiler/context/inquire.rs @@ -5,28 +5,27 @@ use std::path::{Path, PathBuf}; use erg_common::config::{ErgConfig, Input}; use erg_common::env::{erg_py_external_lib_path, erg_pystd_path, erg_std_path}; use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage}; -use erg_common::levenshtein::get_similar_name; +use erg_common::levenshtein; use erg_common::pathutil::add_postfix_foreach; use erg_common::set::Set; use erg_common::traits::{Locational, NoTypeDisplay, Stream}; -use erg_common::vis::Visibility; +use erg_common::triple::Triple; use erg_common::Str; use erg_common::{ fmt_option, fmt_slice, log, normalize_path, option_enum_unwrap, set, switch_lang, }; -use Type::*; -use ast::VarName; -use erg_parser::ast::{self, Identifier}; +use erg_parser::ast::{self, Identifier, VarName}; use erg_parser::token::Token; use crate::ty::constructors::{anon, free_var, func, mono, poly, proc, proj, ref_, subr_t}; use crate::ty::free::Constraint; use crate::ty::typaram::TyParam; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; -use crate::ty::{HasType, ParamTy, SubrKind, SubrType, Type}; +use crate::ty::{HasType, ParamTy, SubrKind, SubrType, Type, Visibility}; +use Type::*; -use crate::context::instantiate::ConstTemplate; +use crate::context::instantiate_spec::ConstTemplate; use crate::context::{Context, RegistrationMode, TraitImpl, TyVarCache, Variance}; use crate::error::{ binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError, @@ -36,9 +35,8 @@ use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use crate::{feature_error, hir}; use crate::{unreachable_error, AccessKind}; use RegistrationMode::*; -use Visibility::*; -use super::instantiate::ParamKind; +use super::instantiate_spec::ParamKind; use super::{ContextKind, MethodInfo}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -105,7 +103,7 @@ impl Context { pub fn get_singular_ctx_by_hir_expr( &self, obj: &hir::Expr, - namespace: &Str, + namespace: &Context, ) -> SingleTyCheckResult<&Context> { match obj { hir::Expr::Accessor(hir::Accessor::Ident(ident)) => { @@ -132,19 +130,22 @@ impl Context { pub(crate) fn get_singular_ctx_by_ident( &self, ident: &ast::Identifier, - namespace: &Str, + namespace: &Context, ) -> SingleTyCheckResult<&Context> { self.get_mod(ident.inspect()) .or_else(|| self.rec_local_get_type(ident.inspect()).map(|(_, ctx)| ctx)) .or_else(|| self.rec_get_patch(ident.inspect())) .ok_or_else(|| { - TyCheckError::no_var_error( + let (similar_info, similar_name) = + self.get_similar_name_and_info(ident.inspect()).unzip(); + TyCheckError::detailed_no_var_error( self.cfg.input.clone(), line!() as usize, ident.loc(), - namespace.into(), + namespace.name.to_string(), ident.inspect(), - self.get_similar_name(ident.inspect()), + similar_name, + similar_info, ) }) } @@ -170,7 +171,7 @@ impl Context { pub(crate) fn get_singular_ctx( &self, obj: &ast::Expr, - namespace: &Str, + namespace: &Context, ) -> SingleTyCheckResult<&Context> { match obj { ast::Expr::Accessor(ast::Accessor::Ident(ident)) => { @@ -342,16 +343,16 @@ impl Context { ident: &Identifier, acc_kind: AccessKind, input: &Input, - namespace: &Str, - ) -> SingleTyCheckResult { + namespace: &Context, + ) -> Triple { if let Some(vi) = self.get_current_scope_var(&ident.name) { match self.validate_visibility(ident, vi, input, namespace) { Ok(()) => { - return Ok(vi.clone()); + return Triple::Ok(vi.clone()); } Err(err) => { if !acc_kind.is_local() { - return Err(err); + return Triple::Err(err); } } } @@ -359,21 +360,21 @@ impl Context { .future_defined_locals .get_key_value(&ident.inspect()[..]) { - return Err(TyCheckError::access_before_def_error( + return Triple::Err(TyCheckError::access_before_def_error( input.clone(), line!() as usize, ident.loc(), - namespace.into(), + namespace.name.to_string(), ident.inspect(), name.ln_begin().unwrap_or(0), self.get_similar_name(ident.inspect()), )); } else if let Some((name, _vi)) = self.deleted_locals.get_key_value(&ident.inspect()[..]) { - return Err(TyCheckError::access_deleted_var_error( + return Triple::Err(TyCheckError::access_deleted_var_error( input.clone(), line!() as usize, ident.loc(), - namespace.into(), + namespace.name.to_string(), ident.inspect(), name.ln_begin().unwrap_or(0), self.get_similar_name(ident.inspect()), @@ -381,20 +382,22 @@ impl Context { } if acc_kind.is_local() { if let Some(parent) = self.get_outer().or_else(|| self.get_builtins()) { - return match parent.rec_get_var_info(ident, acc_kind, input, namespace) { - Ok(vi) => Ok(vi), - Err(err) => Err(err), - }; + return parent.rec_get_var_info(ident, acc_kind, input, namespace); } } - Err(TyCheckError::no_var_error( + /* + let (similar_info, similar_name) = self.get_similar_name_and_info(ident.inspect()).unzip(); + Err(TyCheckError::detailed_no_var_error( input.clone(), line!() as usize, ident.loc(), namespace.into(), ident.inspect(), - self.get_similar_name(ident.inspect()), + similar_name, + similar_info, )) + */ + Triple::None } pub(crate) fn rec_get_decl_info( @@ -402,8 +405,8 @@ impl Context { ident: &Identifier, acc_kind: AccessKind, input: &Input, - namespace: &Str, - ) -> SingleTyCheckResult { + namespace: &Context, + ) -> Triple { if let Some(vi) = self .decls .get(&ident.inspect()[..]) @@ -411,11 +414,11 @@ impl Context { { match self.validate_visibility(ident, vi, input, namespace) { Ok(()) => { - return Ok(vi.clone()); + return Triple::Ok(vi.clone()); } Err(err) => { if !acc_kind.is_local() { - return Err(err); + return Triple::Err(err); } } } @@ -425,14 +428,15 @@ impl Context { return parent.rec_get_decl_info(ident, acc_kind, input, namespace); } } - Err(TyCheckError::no_var_error( + /*Err(TyCheckError::no_var_error( input.clone(), line!() as usize, ident.loc(), namespace.into(), ident.inspect(), self.get_similar_name(ident.inspect()), - )) + ))*/ + Triple::None } pub(crate) fn get_attr_info( @@ -440,42 +444,48 @@ impl Context { obj: &hir::Expr, ident: &Identifier, input: &Input, - namespace: &Str, - ) -> SingleTyCheckResult { + namespace: &Context, + ) -> Triple { let self_t = obj.t(); - let name = ident.name.token(); - match self.get_attr_info_from_attributive(&self_t, ident, namespace) { - Ok(vi) => { - return Ok(vi); + match self.get_attr_info_from_attributive(&self_t, ident) { + Triple::Ok(vi) => { + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::AttributeError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + _ => {} } if let Ok(singular_ctx) = self.get_singular_ctx_by_hir_expr(obj, namespace) { match singular_ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { - Ok(vi) => { - return Ok(vi); + Triple::Ok(vi) => { + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::NameError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + Triple::None => {} } } match self.get_attr_from_nominal_t(obj, ident, input, namespace) { - Ok(vi) => { + Triple::Ok(vi) => { if let Some(self_t) = vi.t.self_t() { - self.sub_unify(obj.ref_t(), self_t, obj, Some(&"self".into())) - .map_err(|mut e| e.remove(0))?; + match self + .sub_unify(obj.ref_t(), self_t, obj, Some(&"self".into())) + .map_err(|mut e| e.remove(0)) + { + Ok(_) => {} + Err(e) => { + return Triple::Err(e); + } + } } - return Ok(vi); + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::AttributeError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + _ => {} } for patch in self.find_patches_of(obj.ref_t()) { if let Some(vi) = patch @@ -483,8 +493,10 @@ impl Context { .get(ident.inspect()) .or_else(|| patch.decls.get(ident.inspect())) { - self.validate_visibility(ident, vi, input, namespace)?; - return Ok(vi.clone()); + return match self.validate_visibility(ident, vi, input, namespace) { + Ok(_) => Triple::Ok(vi.clone()), + Err(e) => Triple::Err(e), + }; } for (_, methods_ctx) in patch.methods_list.iter() { if let Some(vi) = methods_ctx @@ -492,12 +504,15 @@ impl Context { .get(ident.inspect()) .or_else(|| methods_ctx.decls.get(ident.inspect())) { - self.validate_visibility(ident, vi, input, namespace)?; - return Ok(vi.clone()); + return match self.validate_visibility(ident, vi, input, namespace) { + Ok(_) => Triple::Ok(vi.clone()), + Err(e) => Triple::Err(e), + }; } } } - Err(TyCheckError::no_attr_error( + Triple::None + /*Err(TyCheckError::no_attr_error( input.clone(), line!() as usize, name.loc(), @@ -505,7 +520,7 @@ impl Context { &self_t, name.inspect(), self.get_similar_attr(&self_t, name.inspect()), - )) + ))*/ } fn get_attr_from_nominal_t( @@ -513,39 +528,45 @@ impl Context { obj: &hir::Expr, ident: &Identifier, input: &Input, - namespace: &Str, - ) -> SingleTyCheckResult { + namespace: &Context, + ) -> Triple { let self_t = obj.t(); if let Some(sups) = self.get_nominal_super_type_ctxs(&self_t) { for ctx in sups { match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { - Ok(vi) => { - return Ok(vi); + Triple::Ok(vi) => { + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::NameError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + _ => {} } // if self is a methods context if let Some(ctx) = self.get_same_name_context(&ctx.name) { match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) { - Ok(vi) => { - return Ok(vi); + Triple::Ok(vi) => { + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::NameError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + _ => {} } } } } - let coerced = self + let coerced = match self .deref_tyvar(obj.t(), Variance::Covariant, &set! {}, &()) - .map_err(|mut es| es.remove(0))?; + .map_err(|mut es| es.remove(0)) + { + Ok(t) => t, + Err(e) => { + return Triple::Err(e); + } + }; if obj.ref_t() != &coerced { - for ctx in self.get_nominal_super_type_ctxs(&coerced).ok_or_else(|| { + let ctxs = match self.get_nominal_super_type_ctxs(&coerced).ok_or_else(|| { TyCheckError::type_not_found( self.cfg.input.clone(), line!() as usize, @@ -553,31 +574,37 @@ impl Context { self.caused_by(), &coerced, ) - })? { + }) { + Ok(ctxs) => ctxs, + Err(e) => { + return Triple::Err(e); + } + }; + for ctx in ctxs { match ctx.rec_get_var_info(ident, AccessKind::Attr, input, namespace) { - Ok(vi) => { + Triple::Ok(vi) => { obj.ref_t().coerce(); - return Ok(vi); + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::NameError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + _ => {} } if let Some(ctx) = self.get_same_name_context(&ctx.name) { match ctx.rec_get_var_info(ident, AccessKind::Method, input, namespace) { - Ok(vi) => { - return Ok(vi); + Triple::Ok(vi) => { + return Triple::Ok(vi); } - Err(e) if e.core.kind == ErrorKind::NameError => {} - Err(e) => { - return Err(e); + Triple::Err(e) => { + return Triple::Err(e); } + _ => {} } } } } - Err(TyCheckError::no_attr_error( + /*Err(TyCheckError::no_attr_error( self.cfg.input.clone(), line!() as usize, ident.loc(), @@ -585,7 +612,8 @@ impl Context { &self_t, ident.inspect(), self.get_similar_attr(&self_t, ident.inspect()), - )) + ))*/ + Triple::None } /// get type from given attributive type (Record). @@ -594,105 +622,43 @@ impl Context { &self, t: &Type, ident: &Identifier, - namespace: &Str, - ) -> SingleTyCheckResult { + ) -> Triple { match t { // (obj: Never).foo: Never - Type::Never => Ok(VarInfo::ILLEGAL.clone()), + Type::Never => Triple::Ok(VarInfo::ILLEGAL.clone()), Type::FreeVar(fv) if fv.is_linked() => { - self.get_attr_info_from_attributive(&fv.crack(), ident, namespace) + self.get_attr_info_from_attributive(&fv.crack(), ident) } Type::FreeVar(fv) /* if fv.is_unbound() */ => { let sup = fv.get_super().unwrap(); - self.get_attr_info_from_attributive(&sup, ident, namespace) + self.get_attr_info_from_attributive(&sup, ident) } - Type::Ref(t) => self.get_attr_info_from_attributive(t, ident, namespace), + Type::Ref(t) => self.get_attr_info_from_attributive(t, ident), Type::RefMut { before, .. } => { - self.get_attr_info_from_attributive(before, ident, namespace) + self.get_attr_info_from_attributive(before, ident) } Type::Refinement(refine) => { - self.get_attr_info_from_attributive(&refine.t, ident, namespace) + self.get_attr_info_from_attributive(&refine.t, ident) } Type::Record(record) => { - if let Some(attr_t) = record.get(ident.inspect()) { + if let Some((field, attr_t)) = record.get_key_value(ident.inspect()) { let muty = Mutability::from(&ident.inspect()[..]); let vi = VarInfo::new( attr_t.clone(), muty, - Public, + Visibility::new(field.vis.clone(), Str::ever("")), VarKind::Builtin, None, None, None, AbsLocation::unknown(), ); - Ok(vi) - } else { - Err(TyCheckError::no_attr_error( - self.cfg.input.clone(), - line!() as usize, - ident.loc(), - namespace.into(), - t, - ident.inspect(), - self.get_similar_attr(t, ident.inspect()), - )) - } - } - Type::Structural(t) => self.get_attr_info_from_attributive(t, ident, namespace), - other => { - if let Some(v) = self.rec_get_const_obj(&other.local_name()) { - match v { - ValueObj::Type(TypeObj::Generated(gen)) => self - .get_gen_t_require_attr_t(gen, &ident.inspect()[..]) - .map(|attr_t| { - let muty = Mutability::from(&ident.inspect()[..]); - VarInfo::new( - attr_t.clone(), - muty, - Public, - VarKind::Builtin, - None, - None, - None, - AbsLocation::unknown(), - ) - }) - .ok_or_else(|| { - TyCheckError::no_attr_error( - self.cfg.input.clone(), - line!() as usize, - ident.loc(), - namespace.into(), - t, - ident.inspect(), - self.get_similar_attr(t, ident.inspect()), - ) - }), - ValueObj::Type(TypeObj::Builtin(_t)) => { - // FIXME: - Err(TyCheckError::no_attr_error( - self.cfg.input.clone(), - line!() as usize, - ident.loc(), - namespace.into(), - _t, - ident.inspect(), - self.get_similar_attr(_t, ident.inspect()), - )) - } - _other => Err(TyCheckError::no_attr_error( - self.cfg.input.clone(), - line!() as usize, - ident.loc(), - namespace.into(), - t, - ident.inspect(), - self.get_similar_attr(t, ident.inspect()), - )), + if let Err(err) = self.validate_visibility(ident, &vi, &self.cfg.input, self) { + return Triple::Err(err); } + Triple::Ok(vi) } else { - Err(TyCheckError::no_attr_error( + /*Err(TyCheckError::no_attr_error( self.cfg.input.clone(), line!() as usize, ident.loc(), @@ -700,9 +666,12 @@ impl Context { t, ident.inspect(), self.get_similar_attr(t, ident.inspect()), - )) + ))*/ + Triple::None } } + Type::Structural(t) => self.get_attr_info_from_attributive(t, ident), + _other => Triple::None, } } @@ -712,7 +681,7 @@ impl Context { obj: &hir::Expr, attr_name: &Option, input: &Input, - namespace: &Str, + namespace: &Context, ) -> SingleTyCheckResult { if obj.ref_t() == Type::FAILURE { // (...Obj) -> Failure @@ -750,10 +719,16 @@ impl Context { obj: &hir::Expr, attr_name: &Identifier, input: &Input, - namespace: &Str, + namespace: &Context, ) -> SingleTyCheckResult { - if let Ok(vi) = self.get_attr_info_from_attributive(obj.ref_t(), attr_name, namespace) { - return Ok(vi); + match self.get_attr_info_from_attributive(obj.ref_t(), attr_name) { + Triple::Ok(vi) => { + return Ok(vi); + } + Triple::Err(e) => { + return Err(e); + } + _ => {} } for ctx in self .get_nominal_super_type_ctxs(obj.ref_t()) @@ -787,13 +762,13 @@ impl Context { } if let Some(ctx) = self.get_same_name_context(&ctx.name) { match ctx.rec_get_var_info(attr_name, AccessKind::Method, input, namespace) { - Ok(t) => { + Triple::Ok(t) => { return Ok(t); } - Err(e) if e.core.kind == ErrorKind::NameError => {} - Err(e) => { + Triple::Err(e) => { return Err(e); } + Triple::None => {} } } } @@ -820,7 +795,7 @@ impl Context { self.cfg.input.clone(), line!() as usize, attr_name.loc(), - namespace.into(), + namespace.name.to_string(), obj.qual_name().unwrap_or("?"), obj.ref_t(), attr_name.inspect(), @@ -863,7 +838,7 @@ impl Context { self.cfg.input.clone(), line!() as usize, attr_name.loc(), - namespace.into(), + namespace.name.to_string(), obj.ref_t(), attr_name.inspect(), self.get_similar_attr(obj.ref_t(), attr_name.inspect()), @@ -875,34 +850,19 @@ impl Context { ident: &Identifier, vi: &VarInfo, input: &Input, - namespace: &str, + namespace: &Context, ) -> SingleTyCheckResult<()> { - if ident.vis() != vi.vis { - Err(TyCheckError::visibility_error( - input.clone(), - line!() as usize, - ident.loc(), - self.caused_by(), - ident.inspect(), - vi.vis, - )) - // check if the private variable is loaded from the other scope - } else if vi.vis.is_private() - && &self.name[..] != "" - && &self.name[..] != namespace - && !namespace.contains(&self.name[..]) - { - log!(err "{namespace}/{}", self.name); + if vi.vis.compatible(&ident.acc_kind(), namespace) { + Ok(()) + } else { Err(TyCheckError::visibility_error( input.clone(), line!() as usize, ident.loc(), self.caused_by(), ident.inspect(), - Private, + vi.vis.clone(), )) - } else { - Ok(()) } } @@ -931,18 +891,20 @@ impl Context { op: &Token, args: &[hir::PosArg], input: &Input, - namespace: &Str, + namespace: &Context, ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 2); let cont = binop_to_dname(op.inspect()); // not a `Token::from_str(op.kind, cont)` because ops are defined as symbols let symbol = Token::symbol(cont); - let t = self.rec_get_var_info( - &Identifier::new(None, VarName::new(symbol.clone())), - AccessKind::Name, - input, - namespace, - )?; + let t = self + .rec_get_var_info( + &Identifier::private_from_token(symbol.clone()), + AccessKind::Name, + input, + namespace, + ) + .unwrap_to_result()?; let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); self.get_call_t(&op, &None, args, &[], input, namespace) .map_err(|(_, errs)| { @@ -952,7 +914,7 @@ impl Context { let vi = op_ident.vi.clone(); let lhs = args[0].expr.clone(); let rhs = args[1].expr.clone(); - let bin = hir::BinOp::new(op_ident.name.into_token(), lhs, rhs, vi); + let bin = hir::BinOp::new(op_ident.raw.name.into_token(), lhs, rhs, vi); let errs = errs .into_iter() .map(|e| self.append_loc_info(e, bin.loc())) @@ -966,17 +928,19 @@ impl Context { op: &Token, args: &[hir::PosArg], input: &Input, - namespace: &Str, + namespace: &Context, ) -> TyCheckResult { erg_common::debug_power_assert!(args.len() == 1); let cont = unaryop_to_dname(op.inspect()); let symbol = Token::symbol(cont); - let vi = self.rec_get_var_info( - &Identifier::new(None, VarName::new(symbol.clone())), - AccessKind::Name, - input, - namespace, - )?; + let vi = self + .rec_get_var_info( + &Identifier::private_from_token(symbol.clone()), + AccessKind::Name, + input, + namespace, + ) + .unwrap_to_result()?; let op = hir::Expr::Accessor(hir::Accessor::private(symbol, vi)); self.get_call_t(&op, &None, args, &[], input, namespace) .map_err(|(_, errs)| { @@ -985,7 +949,7 @@ impl Context { }; let vi = op_ident.vi.clone(); let expr = args[0].expr.clone(); - let unary = hir::UnaryOp::new(op_ident.name.into_token(), expr, vi); + let unary = hir::UnaryOp::new(op_ident.raw.name.into_token(), expr, vi); let errs = errs .into_iter() .map(|e| self.append_loc_info(e, unary.loc())) @@ -1118,10 +1082,8 @@ impl Context { if is_method { obj.clone() } else { - let attr = hir::Attribute::new( - obj.clone(), - hir::Identifier::bare(ident.dot.clone(), ident.name.clone()), - ); + let attr = + hir::Attribute::new(obj.clone(), hir::Identifier::bare(ident.clone())); hir::Expr::Accessor(hir::Accessor::Attr(attr)) } } else { @@ -1272,10 +1234,10 @@ impl Context { } } other => { - let one = self.get_singular_ctx_by_hir_expr(obj, &self.name).ok(); + let one = self.get_singular_ctx_by_hir_expr(obj, self).ok(); let one = one .zip(attr_name.as_ref()) - .and_then(|(ctx, attr)| ctx.get_singular_ctx_by_ident(attr, &self.name).ok()) + .and_then(|(ctx, attr)| ctx.get_singular_ctx_by_ident(attr, self).ok()) .or(one); let two = obj .qual_name() @@ -1354,7 +1316,8 @@ impl Context { )) } else { let unknown_arg_errors = unknown_args.into_iter().map(|arg| { - let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect()); + let similar = + levenshtein::get_similar_name(subr_ty.param_names(), arg.keyword.inspect()); TyCheckError::unexpected_kw_arg_error( self.cfg.input.clone(), line!() as usize, @@ -1550,7 +1513,8 @@ impl Context { ) })?; } else { - let similar = get_similar_name(subr_ty.param_names(), arg.keyword.inspect()); + let similar = + levenshtein::get_similar_name(subr_ty.param_names(), arg.keyword.inspect()); return Err(TyCheckErrors::from(TyCheckError::unexpected_kw_arg_error( self.cfg.input.clone(), line!() as usize, @@ -1571,7 +1535,7 @@ impl Context { pos_args: &[hir::PosArg], kw_args: &[hir::KwArg], input: &Input, - namespace: &Str, + namespace: &Context, ) -> Result, TyCheckErrors)> { if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj { if local.vis().is_private() { @@ -1692,18 +1656,27 @@ impl Context { } pub(crate) fn get_similar_name(&self, name: &str) -> Option<&str> { - get_similar_name( + levenshtein::get_similar_name( self.dir().into_iter().map(|(vn, _)| &vn.inspect()[..]), name, ) } + pub(crate) fn get_similar_name_and_info(&self, name: &str) -> Option<(&VarInfo, &str)> { + levenshtein::get_similar_name_and_some( + self.dir() + .into_iter() + .map(|(vn, vi)| (vi, &vn.inspect()[..])), + name, + ) + } + pub(crate) fn get_similar_attr_from_singular<'a>( &'a self, obj: &hir::Expr, name: &str, ) -> Option<&'a str> { - if let Ok(ctx) = self.get_singular_ctx_by_hir_expr(obj, &self.name) { + if let Ok(ctx) = self.get_singular_ctx_by_hir_expr(obj, self) { if let Some(name) = ctx.get_similar_name(name) { return Some(name); } @@ -1720,6 +1693,19 @@ impl Context { None } + pub(crate) fn get_similar_attr_and_info<'a>( + &'a self, + self_t: &'a Type, + name: &str, + ) -> Option<(&'a VarInfo, &'a str)> { + for ctx in self.get_nominal_super_type_ctxs(self_t)? { + if let Some((vi, name)) = ctx.get_similar_name_and_info(name) { + return Some((vi, name)); + } + } + None + } + // Returns what kind of variance the type has for each parameter Type. // Invariant for types not specified // selfが示す型が、各パラメータTypeに対してどのような変性Varianceを持つかを返す @@ -2166,7 +2152,7 @@ impl Context { { normalize_path(path) } else { - todo!("{} {}", path.display(), add.display()) + todo!("{} // {}", path.display(), add.display()) } } @@ -2423,7 +2409,11 @@ impl Context { } } - fn get_gen_t_require_attr_t<'a>(&'a self, gen: &'a GenTypeObj, attr: &str) -> Option<&'a Type> { + fn _get_gen_t_require_attr_t<'a>( + &'a self, + gen: &'a GenTypeObj, + attr: &str, + ) -> Option<&'a Type> { match gen.base_or_sup().map(|req_sup| req_sup.typ()) { Some(Type::Record(rec)) => { if let Some(t) = rec.get(attr) { @@ -2433,7 +2423,7 @@ impl Context { Some(other) => { let obj = self.rec_get_const_obj(&other.local_name()); let obj = option_enum_unwrap!(obj, Some:(ValueObj::Type:(TypeObj::Generated:(_))))?; - if let Some(t) = self.get_gen_t_require_attr_t(obj, attr) { + if let Some(t) = self._get_gen_t_require_attr_t(obj, attr) { return Some(t); } } diff --git a/crates/erg_compiler/context/instantiate.rs b/crates/erg_compiler/context/instantiate.rs index 602319f25..50b9ac1ed 100644 --- a/crates/erg_compiler/context/instantiate.rs +++ b/crates/erg_compiler/context/instantiate.rs @@ -3,96 +3,24 @@ use std::mem; use std::option::Option; // conflicting to Type::Option use erg_common::dict::Dict; +use erg_common::enum_unwrap; #[allow(unused)] use erg_common::log; use erg_common::set::Set; -use erg_common::traits::{Locational, Stream}; -use erg_common::vis::Field; +use erg_common::traits::Locational; use erg_common::Str; -use erg_common::{assume_unreachable, dict, enum_unwrap, set, try_map_mut}; - -use ast::{ - NonDefaultParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec, - TypeBoundSpecs, TypeSpec, -}; -use erg_parser::ast; -use erg_parser::token::TokenKind; -use erg_parser::Parser; use crate::feature_error; use crate::ty::constructors::*; -use crate::ty::free::CanbeFree; use crate::ty::free::{Constraint, HasLevel}; -use crate::ty::typaram::TyParamLambda; -use crate::ty::typaram::{IntervalOp, OpKind, TyParam, TyParamOrdering}; -use crate::ty::value::ValueObj; -use crate::ty::SubrType; -use crate::ty::{HasType, ParamTy, Predicate, SubrKind, Type}; -use crate::type_feature_error; -use crate::unreachable_error; -use TyParamOrdering::*; +use crate::ty::typaram::{TyParam, TyParamLambda}; +use crate::ty::{HasType, Predicate, Type}; +use crate::{type_feature_error, unreachable_error}; use Type::*; -use crate::context::{Context, DefaultInfo, RegistrationMode}; +use crate::context::Context; use crate::error::{TyCheckError, TyCheckErrors, TyCheckResult}; use crate::hir; -use crate::AccessKind; -use RegistrationMode::*; - -pub fn token_kind_to_op_kind(kind: TokenKind) -> Option { - match kind { - TokenKind::Plus => Some(OpKind::Add), - TokenKind::Minus => Some(OpKind::Sub), - TokenKind::Star => Some(OpKind::Mul), - TokenKind::Slash => Some(OpKind::Div), - TokenKind::FloorDiv => Some(OpKind::FloorDiv), - TokenKind::Mod => Some(OpKind::Mod), - TokenKind::Pow => Some(OpKind::Pow), - TokenKind::PrePlus => Some(OpKind::Pos), - TokenKind::PreMinus => Some(OpKind::Neg), - TokenKind::PreBitNot => Some(OpKind::Invert), - TokenKind::Equal => Some(OpKind::Eq), - TokenKind::NotEq => Some(OpKind::Ne), - TokenKind::Less => Some(OpKind::Lt), - TokenKind::LessEq => Some(OpKind::Le), - TokenKind::Gre => Some(OpKind::Gt), - TokenKind::GreEq => Some(OpKind::Ge), - TokenKind::AndOp => Some(OpKind::And), - TokenKind::OrOp => Some(OpKind::Or), - TokenKind::BitAnd => Some(OpKind::BitAnd), - TokenKind::BitOr => Some(OpKind::BitOr), - TokenKind::BitXor => Some(OpKind::BitXor), - TokenKind::Shl => Some(OpKind::Shl), - TokenKind::Shr => Some(OpKind::Shr), - _ => None, - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ParamKind { - NonDefault, - Default(Type), - VarParams, - KwParams, -} - -impl ParamKind { - pub const fn is_var_params(&self) -> bool { - matches!(self, ParamKind::VarParams) - } - pub const fn is_kw_params(&self) -> bool { - matches!(self, ParamKind::KwParams) - } - pub const fn is_default(&self) -> bool { - matches!(self, ParamKind::Default(_)) - } - pub const fn default_info(&self) -> DefaultInfo { - match self { - ParamKind::Default(_) => DefaultInfo::WithDefault, - _ => DefaultInfo::NonDefault, - } - } -} /// Context for instantiating a quantified type /// For example, cloning each type variable of quantified type `?T -> ?T` would result in `?1 -> ?2`. @@ -244,1072 +172,7 @@ impl TyVarCache { } } -/// TODO: this struct will be removed when const functions are implemented. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum ConstTemplate { - Obj(ValueObj), - App { - name: Str, - non_default_args: Vec, - default_args: Vec, - }, -} - -impl ConstTemplate { - pub const fn app( - name: &'static str, - non_default_args: Vec, - default_args: Vec, - ) -> Self { - ConstTemplate::App { - name: Str::ever(name), - non_default_args, - default_args, - } - } -} - impl Context { - pub(crate) fn instantiate_var_sig_t( - &self, - t_spec: Option<&TypeSpec>, - mode: RegistrationMode, - ) -> TyCheckResult { - let mut tmp_tv_cache = TyVarCache::new(self.level, self); - let spec_t = if let Some(t_spec) = t_spec { - self.instantiate_typespec(t_spec, None, &mut tmp_tv_cache, mode, false)? - } else { - free_var(self.level, Constraint::new_type_of(Type)) - }; - Ok(spec_t) - } - - pub(crate) fn instantiate_sub_sig_t( - &self, - sig: &ast::SubrSignature, - default_ts: Vec, - mode: RegistrationMode, - ) -> Result { - let mut errs = TyCheckErrors::empty(); - // -> Result { - let opt_decl_sig_t = match self - .rec_get_decl_info(&sig.ident, AccessKind::Name, &self.cfg.input, &self.name) - .ok() - .map(|vi| vi.t) - { - Some(Type::Subr(subr)) => Some(subr), - Some(Type::FreeVar(fv)) if fv.is_unbound() => return Ok(Type::FreeVar(fv)), - Some(other) => { - let err = TyCheckError::unreachable( - self.cfg.input.clone(), - "instantiate_sub_sig_t", - line!(), - ); - return Err((TyCheckErrors::from(err), other)); - } - None => None, - }; - let mut tmp_tv_cache = self - .instantiate_ty_bounds(&sig.bounds, PreRegister) - .map_err(|errs| (errs, Type::Failure))?; - let mut non_defaults = vec![]; - for (n, param) in sig.params.non_defaults.iter().enumerate() { - let opt_decl_t = opt_decl_sig_t - .as_ref() - .and_then(|subr| subr.non_default_params.get(n)); - match self.instantiate_param_ty( - param, - opt_decl_t, - &mut tmp_tv_cache, - mode, - ParamKind::NonDefault, - ) { - Ok(pt) => non_defaults.push(pt), - Err(es) => { - errs.extend(es); - non_defaults.push(ParamTy::pos(param.inspect().cloned(), Type::Failure)); - } - } - } - let var_args = if let Some(var_args) = sig.params.var_params.as_ref() { - let opt_decl_t = opt_decl_sig_t - .as_ref() - .and_then(|subr| subr.var_params.as_ref().map(|v| v.as_ref())); - let pt = match self.instantiate_param_ty( - var_args, - opt_decl_t, - &mut tmp_tv_cache, - mode, - ParamKind::VarParams, - ) { - Ok(pt) => pt, - Err(es) => { - errs.extend(es); - ParamTy::pos(var_args.inspect().cloned(), Type::Failure) - } - }; - Some(pt) - } else { - None - }; - let mut defaults = vec![]; - for ((n, p), default_t) in sig.params.defaults.iter().enumerate().zip(default_ts) { - let opt_decl_t = opt_decl_sig_t - .as_ref() - .and_then(|subr| subr.default_params.get(n)); - match self.instantiate_param_ty( - &p.sig, - opt_decl_t, - &mut tmp_tv_cache, - mode, - ParamKind::Default(default_t), - ) { - Ok(pt) => defaults.push(pt), - Err(es) => { - errs.extend(es); - defaults.push(ParamTy::pos(p.sig.inspect().cloned(), Type::Failure)); - } - } - } - let spec_return_t = if let Some(t_spec) = sig.return_t_spec.as_ref() { - let opt_decl_t = opt_decl_sig_t - .as_ref() - .map(|subr| ParamTy::anonymous(subr.return_t.as_ref().clone())); - match self.instantiate_typespec( - t_spec, - opt_decl_t.as_ref(), - &mut tmp_tv_cache, - mode, - false, - ) { - Ok(ty) => ty, - Err(es) => { - errs.extend(es); - Type::Failure - } - } - } else { - // preregisterならouter scopeで型宣言(see inference.md) - let level = if mode == PreRegister { - self.level - } else { - self.level + 1 - }; - free_var(level, Constraint::new_type_of(Type)) - }; - let typ = if sig.ident.is_procedural() { - proc(non_defaults, var_args, defaults, spec_return_t) - } else { - func(non_defaults, var_args, defaults, spec_return_t) - }; - if errs.is_empty() { - Ok(typ) - } else { - Err((errs, typ)) - } - } - - /// spec_t == Noneかつリテラル推論が不可能なら型変数を発行する - pub(crate) fn instantiate_param_sig_t( - &self, - sig: &NonDefaultParamSignature, - opt_decl_t: Option<&ParamTy>, - tmp_tv_cache: &mut TyVarCache, - mode: RegistrationMode, - kind: ParamKind, - ) -> TyCheckResult { - let gen_free_t = || { - let level = if mode == PreRegister { - self.level - } else { - self.level + 1 - }; - free_var(level, Constraint::new_type_of(Type)) - }; - let spec_t = if let Some(spec_with_op) = &sig.t_spec { - self.instantiate_typespec(&spec_with_op.t_spec, opt_decl_t, tmp_tv_cache, mode, false)? - } else { - match &sig.pat { - ast::ParamPattern::Lit(lit) => v_enum(set![self.eval_lit(lit)?]), - ast::ParamPattern::Discard(_) => Type::Obj, - ast::ParamPattern::Ref(_) => ref_(gen_free_t()), - ast::ParamPattern::RefMut(_) => ref_mut(gen_free_t(), None), - // ast::ParamPattern::VarName(name) if &name.inspect()[..] == "_" => Type::Obj, - // TODO: Array - _ => gen_free_t(), - } - }; - if let Some(decl_pt) = opt_decl_t { - if kind.is_var_params() { - let spec_t = unknown_len_array_t(spec_t.clone()); - self.sub_unify( - decl_pt.typ(), - &spec_t, - &sig.t_spec.as_ref().ok_or(sig), - None, - )?; - } else { - self.sub_unify( - decl_pt.typ(), - &spec_t, - &sig.t_spec.as_ref().ok_or(sig), - None, - )?; - } - } - Ok(spec_t) - } - - pub(crate) fn instantiate_param_ty( - &self, - sig: &NonDefaultParamSignature, - opt_decl_t: Option<&ParamTy>, - tmp_tv_cache: &mut TyVarCache, - mode: RegistrationMode, - kind: ParamKind, - ) -> TyCheckResult { - let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_cache, mode, kind.clone())?; - match (sig.inspect(), kind) { - (Some(name), ParamKind::Default(default_t)) => { - Ok(ParamTy::kw_default(name.clone(), t, default_t)) - } - (Some(name), _) => Ok(ParamTy::kw(name.clone(), t)), - (None, _) => Ok(ParamTy::anonymous(t)), - } - } - - pub(crate) fn instantiate_predecl_t( - &self, - predecl: &PreDeclTypeSpec, - opt_decl_t: Option<&ParamTy>, - tmp_tv_cache: &mut TyVarCache, - not_found_is_qvar: bool, - ) -> TyCheckResult { - match predecl { - ast::PreDeclTypeSpec::Simple(simple) => { - self.instantiate_simple_t(simple, opt_decl_t, tmp_tv_cache, not_found_is_qvar) - } - ast::PreDeclTypeSpec::Attr { namespace, t } => { - if let Ok(receiver) = Parser::validate_const_expr(namespace.as_ref().clone()) { - if let Ok(receiver_t) = - self.instantiate_const_expr_as_type(&receiver, None, tmp_tv_cache) - { - let rhs = t.ident.inspect(); - return Ok(proj(receiver_t, rhs)); - } - } - let ctx = self.get_singular_ctx(namespace.as_ref(), &self.name)?; - if let Some((typ, _)) = ctx.rec_local_get_type(t.ident.inspect()) { - let vi = ctx - .rec_get_var_info(&t.ident, AccessKind::Name, &self.cfg.input, &self.name) - .unwrap(); - self.inc_ref(&vi, &t.ident.name); - // TODO: visibility check - Ok(typ.clone()) - } else { - Err(TyCheckErrors::from(TyCheckError::no_var_error( - self.cfg.input.clone(), - line!() as usize, - t.loc(), - self.caused_by(), - t.ident.inspect(), - self.get_similar_name(t.ident.inspect()), - ))) - } - } - other => type_feature_error!(self, other.loc(), &format!("instantiating type {other}")), - } - } - - pub(crate) fn instantiate_simple_t( - &self, - simple: &SimpleTypeSpec, - opt_decl_t: Option<&ParamTy>, - tmp_tv_cache: &mut TyVarCache, - not_found_is_qvar: bool, - ) -> TyCheckResult { - self.inc_ref_simple_typespec(simple); - match &simple.ident.inspect()[..] { - "_" | "Obj" => Ok(Type::Obj), - "Nat" => Ok(Type::Nat), - "Int" => Ok(Type::Int), - "Ratio" => Ok(Type::Ratio), - "Float" => Ok(Type::Float), - "Str" => Ok(Type::Str), - "Bool" => Ok(Type::Bool), - "NoneType" => Ok(Type::NoneType), - "Ellipsis" => Ok(Type::Ellipsis), - "NotImplemented" => Ok(Type::NotImplementedType), - "Inf" => Ok(Type::Inf), - "NegInf" => Ok(Type::NegInf), - "Never" => Ok(Type::Never), - "ClassType" => Ok(Type::ClassType), - "TraitType" => Ok(Type::TraitType), - "Type" => Ok(Type::Type), - "Array" => { - // TODO: kw - let mut args = simple.args.pos_args(); - if let Some(first) = args.next() { - let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; - let len = if let Some(len) = args.next() { - self.instantiate_const_expr(&len.expr, None, tmp_tv_cache)? - } else { - TyParam::erased(Nat) - }; - Ok(array_t(t, len)) - } else { - Ok(mono("GenericArray")) - } - } - "Ref" => { - let mut args = simple.args.pos_args(); - let Some(first) = args.next() else { - return Err(TyCheckErrors::from(TyCheckError::args_missing_error( - self.cfg.input.clone(), - line!() as usize, - simple.args.loc(), - "Ref", - self.caused_by(), - vec![Str::from("T")], - ))); - }; - let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; - Ok(ref_(t)) - } - "RefMut" => { - // TODO after - let mut args = simple.args.pos_args(); - let Some(first) = args.next() else { - return Err(TyCheckErrors::from(TyCheckError::args_missing_error( - self.cfg.input.clone(), - line!() as usize, - simple.args.loc(), - "RefMut", - self.caused_by(), - vec![Str::from("T")], - ))); - }; - let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; - Ok(ref_mut(t, None)) - } - "Structural" => { - let mut args = simple.args.pos_args(); - let Some(first) = args.next() else { - return Err(TyCheckErrors::from(TyCheckError::args_missing_error( - self.cfg.input.clone(), - line!() as usize, - simple.args.loc(), - "Structural", - self.caused_by(), - vec![Str::from("Type")], - ))); - }; - let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; - Ok(t.structuralize()) - } - "Self" => self.rec_get_self_t().ok_or_else(|| { - TyCheckErrors::from(TyCheckError::unreachable( - self.cfg.input.clone(), - erg_common::fn_name_full!(), - line!(), - )) - }), - other if simple.args.is_empty() => { - if let Some(t) = tmp_tv_cache.get_tyvar(other) { - return Ok(t.clone()); - } else if let Some(tp) = tmp_tv_cache.get_typaram(other) { - let t = enum_unwrap!(tp, TyParam::Type); - return Ok(t.as_ref().clone()); - } - if let Some(tv_cache) = &self.tv_cache { - if let Some(t) = tv_cache.get_tyvar(other) { - return Ok(t.clone()); - } else if let Some(tp) = tv_cache.get_typaram(other) { - let t = enum_unwrap!(tp, TyParam::Type); - return Ok(t.as_ref().clone()); - } - } - if let Some(outer) = &self.outer { - if let Ok(t) = outer.instantiate_simple_t( - simple, - opt_decl_t, - tmp_tv_cache, - not_found_is_qvar, - ) { - return Ok(t); - } - } - if let Some(decl_t) = opt_decl_t { - return Ok(decl_t.typ().clone()); - } - if let Some((typ, _)) = self.get_type(simple.ident.inspect()) { - Ok(typ.clone()) - } else if not_found_is_qvar { - let tyvar = named_free_var(Str::rc(other), self.level, Constraint::Uninited); - tmp_tv_cache.push_or_init_tyvar(simple.ident.inspect(), &tyvar); - Ok(tyvar) - } else { - Err(TyCheckErrors::from(TyCheckError::no_type_error( - self.cfg.input.clone(), - line!() as usize, - simple.loc(), - self.caused_by(), - other, - self.get_similar_name(other), - ))) - } - } - other => { - let ctx = if let Some((_, ctx)) = self.get_type(&Str::rc(other)) { - ctx - } else { - return Err(TyCheckErrors::from(TyCheckError::no_type_error( - self.cfg.input.clone(), - line!() as usize, - simple.ident.loc(), - self.caused_by(), - other, - self.get_similar_name(other), - ))); - }; - // FIXME: kw args - let mut new_params = vec![]; - for (i, arg) in simple.args.pos_args().enumerate() { - let params = - self.instantiate_const_expr(&arg.expr, Some((ctx, i)), tmp_tv_cache); - let params = params.or_else(|e| { - if not_found_is_qvar { - let name = arg.expr.to_string(); - // FIXME: handle `::` as a right way - let name = Str::rc(name.trim_start_matches("::")); - let tp = TyParam::named_free_var( - name.clone(), - self.level, - Constraint::Uninited, - ); - tmp_tv_cache.push_or_init_typaram(&name, &tp); - Ok(tp) - } else { - Err(e) - } - })?; - new_params.push(params); - } - // FIXME: non-builtin - Ok(poly(Str::rc(other), new_params)) - } - } - } - - fn instantiate_local( - &self, - name: &Str, - erased_idx: Option<(&Context, usize)>, - tmp_tv_cache: &mut TyVarCache, - loc: &impl Locational, - ) -> TyCheckResult { - if &name[..] == "_" { - let t = if let Some((ctx, i)) = erased_idx { - ctx.params[i].1.t.clone() - } else { - Type::Uninited - }; - return Ok(TyParam::erased(t)); - } - if let Some(tp) = tmp_tv_cache.get_typaram(name) { - return Ok(tp.clone()); - } else if let Some(t) = tmp_tv_cache.get_tyvar(name) { - return Ok(TyParam::t(t.clone())); - } - if let Some(tv_ctx) = &self.tv_cache { - if let Some(t) = tv_ctx.get_tyvar(name) { - return Ok(TyParam::t(t.clone())); - } else if let Some(tp) = tv_ctx.get_typaram(name) { - return Ok(tp.clone()); - } - } - if let Some(value) = self.rec_get_const_obj(name) { - return Ok(TyParam::Value(value.clone())); - } - Err(TyCheckErrors::from(TyCheckError::no_var_error( - self.cfg.input.clone(), - line!() as usize, - loc.loc(), - self.caused_by(), - name, - self.get_similar_name(name), - ))) - } - - pub(crate) fn instantiate_const_expr( - &self, - expr: &ast::ConstExpr, - erased_idx: Option<(&Context, usize)>, - tmp_tv_cache: &mut TyVarCache, - ) -> TyCheckResult { - match expr { - ast::ConstExpr::Lit(lit) => Ok(TyParam::Value(self.eval_lit(lit)?)), - ast::ConstExpr::Accessor(ast::ConstAccessor::Attr(attr)) => { - let obj = self.instantiate_const_expr(&attr.obj, erased_idx, tmp_tv_cache)?; - Ok(obj.proj(attr.name.inspect())) - } - ast::ConstExpr::Accessor(ast::ConstAccessor::Local(local)) => { - self.inc_ref_const_local(local); - self.instantiate_local(local.inspect(), erased_idx, tmp_tv_cache, local) - } - ast::ConstExpr::Array(array) => { - let mut tp_arr = vec![]; - for (i, elem) in array.elems.pos_args().enumerate() { - let el = - self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?; - tp_arr.push(el); - } - Ok(TyParam::Array(tp_arr)) - } - ast::ConstExpr::Set(set) => { - let mut tp_set = set! {}; - for (i, elem) in set.elems.pos_args().enumerate() { - let el = - self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?; - tp_set.insert(el); - } - Ok(TyParam::Set(tp_set)) - } - ast::ConstExpr::Dict(dict) => { - let mut tp_dict = dict! {}; - for (i, elem) in dict.kvs.iter().enumerate() { - let key = - self.instantiate_const_expr(&elem.key, Some((self, i)), tmp_tv_cache)?; - let val = - self.instantiate_const_expr(&elem.value, Some((self, i)), tmp_tv_cache)?; - tp_dict.insert(key, val); - } - Ok(TyParam::Dict(tp_dict)) - } - ast::ConstExpr::Tuple(tuple) => { - let mut tp_tuple = vec![]; - for (i, elem) in tuple.elems.pos_args().enumerate() { - let el = - self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?; - tp_tuple.push(el); - } - Ok(TyParam::Tuple(tp_tuple)) - } - ast::ConstExpr::Record(rec) => { - let mut tp_rec = dict! {}; - for attr in rec.attrs.iter() { - let field = Field::new(attr.ident.vis(), attr.ident.inspect().clone()); - let val = self.instantiate_const_expr( - attr.body.block.get(0).unwrap(), - None, - tmp_tv_cache, - )?; - tp_rec.insert(field, val); - } - Ok(TyParam::Record(tp_rec)) - } - ast::ConstExpr::Lambda(lambda) => { - let mut _tmp_tv_cache = - self.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?; - let tmp_tv_cache = if tmp_tv_cache.is_empty() { - &mut _tmp_tv_cache - } else { - // TODO: prohibit double quantification - tmp_tv_cache - }; - let mut nd_params = Vec::with_capacity(lambda.sig.params.non_defaults.len()); - for sig in lambda.sig.params.non_defaults.iter() { - let pt = self.instantiate_param_ty( - sig, - None, - tmp_tv_cache, - RegistrationMode::Normal, - ParamKind::NonDefault, - )?; - nd_params.push(pt); - } - let var_params = if let Some(p) = lambda.sig.params.var_params.as_ref() { - let pt = self.instantiate_param_ty( - p, - None, - tmp_tv_cache, - RegistrationMode::Normal, - ParamKind::VarParams, - )?; - Some(pt) - } else { - None - }; - let mut d_params = Vec::with_capacity(lambda.sig.params.defaults.len()); - for sig in lambda.sig.params.defaults.iter() { - let expr = self.eval_const_expr(&sig.default_val)?; - let pt = self.instantiate_param_ty( - &sig.sig, - None, - tmp_tv_cache, - RegistrationMode::Normal, - ParamKind::Default(expr.t()), - )?; - d_params.push(pt); - } - let mut body = vec![]; - for expr in lambda.body.iter() { - let param = self.instantiate_const_expr(expr, None, tmp_tv_cache)?; - body.push(param); - } - Ok(TyParam::Lambda(TyParamLambda::new( - lambda.clone(), - nd_params, - var_params, - d_params, - body, - ))) - } - ast::ConstExpr::BinOp(bin) => { - let Some(op) = token_kind_to_op_kind(bin.op.kind) else { - return type_feature_error!( - self, - bin.loc(), - &format!("instantiating const expression {bin}") - ) - }; - let lhs = self.instantiate_const_expr(&bin.lhs, erased_idx, tmp_tv_cache)?; - let rhs = self.instantiate_const_expr(&bin.rhs, erased_idx, tmp_tv_cache)?; - Ok(TyParam::bin(op, lhs, rhs)) - } - ast::ConstExpr::UnaryOp(unary) => { - let Some(op) = token_kind_to_op_kind(unary.op.kind) else { - return type_feature_error!( - self, - unary.loc(), - &format!("instantiating const expression {unary}") - ) - }; - let val = self.instantiate_const_expr(&unary.expr, erased_idx, tmp_tv_cache)?; - Ok(TyParam::unary(op, val)) - } - ast::ConstExpr::TypeAsc(tasc) => { - let tp = self.instantiate_const_expr(&tasc.expr, erased_idx, tmp_tv_cache)?; - let spec_t = self.instantiate_typespec( - &tasc.t_spec.t_spec, - None, - tmp_tv_cache, - RegistrationMode::Normal, - false, - )?; - if self.subtype_of(&self.get_tp_t(&tp)?, &spec_t) { - Ok(tp) - } else { - Err(TyCheckErrors::from(TyCheckError::subtyping_error( - self.cfg.input.clone(), - line!() as usize, - &self.get_tp_t(&tp)?, - &spec_t, - tasc.loc(), - self.caused_by(), - ))) - } - } - other => type_feature_error!( - self, - other.loc(), - &format!("instantiating const expression {other}") - ), - } - } - - pub(crate) fn instantiate_const_expr_as_type( - &self, - expr: &ast::ConstExpr, - erased_idx: Option<(&Context, usize)>, - tmp_tv_cache: &mut TyVarCache, - ) -> TyCheckResult { - let tp = self.instantiate_const_expr(expr, erased_idx, tmp_tv_cache)?; - self.instantiate_tp_as_type(tp, expr) - } - - fn instantiate_tp_as_type(&self, tp: TyParam, loc: &impl Locational) -> TyCheckResult { - match tp { - TyParam::FreeVar(fv) if fv.is_linked() => { - self.instantiate_tp_as_type(fv.crack().clone(), loc) - } - TyParam::Type(t) => Ok(*t), - TyParam::Value(ValueObj::Type(t)) => Ok(t.into_typ()), - TyParam::Set(set) => { - let t = set - .iter() - .next() - .and_then(|tp| self.get_tp_t(tp).ok()) - .unwrap_or(Type::Never); - Ok(tp_enum(t, set)) - } - TyParam::Tuple(ts) => { - let mut tps = vec![]; - for tp in ts { - let t = self.instantiate_tp_as_type(tp, loc)?; - tps.push(t); - } - Ok(tuple_t(tps)) - } - TyParam::Record(rec) => { - let mut rec_t = dict! {}; - for (field, tp) in rec { - let t = self.instantiate_tp_as_type(tp, loc)?; - rec_t.insert(field, t); - } - Ok(Type::Record(rec_t)) - } - TyParam::Lambda(lambda) => { - let return_t = self - .instantiate_tp_as_type(lambda.body.last().unwrap().clone(), &lambda.const_)?; - let subr = SubrType::new( - SubrKind::from(lambda.const_.op.kind), - lambda.nd_params, - lambda.var_params, - lambda.d_params, - return_t, - ); - Ok(Type::Subr(subr)) - } - other => { - type_feature_error!(self, loc.loc(), &format!("instantiate `{other}` as type")) - } - } - } - - fn instantiate_func_param_spec( - &self, - p: &ParamTySpec, - opt_decl_t: Option<&ParamTy>, - default_t: Option<&TypeSpec>, - tmp_tv_cache: &mut TyVarCache, - mode: RegistrationMode, - ) -> TyCheckResult { - let t = self.instantiate_typespec(&p.ty, opt_decl_t, tmp_tv_cache, mode, false)?; - if let Some(default_t) = default_t { - Ok(ParamTy::kw_default( - p.name.as_ref().unwrap().inspect().to_owned(), - t, - self.instantiate_typespec(default_t, opt_decl_t, tmp_tv_cache, mode, false)?, - )) - } else { - Ok(ParamTy::pos( - p.name.as_ref().map(|t| t.inspect().to_owned()), - t, - )) - } - } - - pub(crate) fn instantiate_typespec( - &self, - t_spec: &TypeSpec, - opt_decl_t: Option<&ParamTy>, - tmp_tv_cache: &mut TyVarCache, - mode: RegistrationMode, - not_found_is_qvar: bool, - ) -> TyCheckResult { - match t_spec { - TypeSpec::Infer(_) => Ok(free_var(self.level, Constraint::new_type_of(Type))), - TypeSpec::PreDeclTy(predecl) => Ok(self.instantiate_predecl_t( - predecl, - opt_decl_t, - tmp_tv_cache, - not_found_is_qvar, - )?), - TypeSpec::And(lhs, rhs) => Ok(self.intersection( - &self.instantiate_typespec( - lhs, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - &self.instantiate_typespec( - rhs, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - )), - TypeSpec::Or(lhs, rhs) => Ok(self.union( - &self.instantiate_typespec( - lhs, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - &self.instantiate_typespec( - rhs, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - )), - TypeSpec::Not(ty) => Ok(self.complement(&self.instantiate_typespec( - ty, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?)), - TypeSpec::Array(arr) => { - let elem_t = self.instantiate_typespec( - &arr.ty, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?; - let mut len = self.instantiate_const_expr(&arr.len, None, tmp_tv_cache)?; - if let TyParam::Erased(t) = &mut len { - *t.as_mut() = Type::Nat; - } - Ok(array_t(elem_t, len)) - } - TypeSpec::SetWithLen(set) => { - let elem_t = self.instantiate_typespec( - &set.ty, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?; - let mut len = self.instantiate_const_expr(&set.len, None, tmp_tv_cache)?; - if let TyParam::Erased(t) = &mut len { - *t.as_mut() = Type::Nat; - } - Ok(set_t(elem_t, len)) - } - TypeSpec::Tuple(tup) => { - let mut inst_tys = vec![]; - for spec in tup.tys.iter() { - inst_tys.push(self.instantiate_typespec( - spec, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?); - } - Ok(tuple_t(inst_tys)) - } - TypeSpec::Dict(dict) => { - let mut inst_tys = dict! {}; - for (k, v) in dict { - inst_tys.insert( - self.instantiate_typespec( - k, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - self.instantiate_typespec( - v, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - ); - } - Ok(dict_t(inst_tys.into())) - } - TypeSpec::Record(rec) => { - let mut inst_tys = dict! {}; - for (k, v) in rec { - inst_tys.insert( - k.into(), - self.instantiate_typespec( - v, - opt_decl_t, - tmp_tv_cache, - mode, - not_found_is_qvar, - )?, - ); - } - Ok(Type::Record(inst_tys)) - } - // TODO: エラー処理(リテラルでない)はパーサーにやらせる - TypeSpec::Enum(set) => { - let mut new_set = set! {}; - for arg in set.pos_args() { - new_set.insert(self.instantiate_const_expr(&arg.expr, None, tmp_tv_cache)?); - } - let ty = new_set.iter().fold(Type::Never, |t, tp| { - self.union(&t, &self.get_tp_t(tp).unwrap()) - }); - Ok(tp_enum(ty, new_set)) - } - TypeSpec::Interval { op, lhs, rhs } => { - let op = match op.kind { - TokenKind::Closed => IntervalOp::Closed, - TokenKind::LeftOpen => IntervalOp::LeftOpen, - TokenKind::RightOpen => IntervalOp::RightOpen, - TokenKind::Open => IntervalOp::Open, - _ => assume_unreachable!(), - }; - let l = self.instantiate_const_expr(lhs, None, tmp_tv_cache)?; - let l = self.eval_tp(l)?; - let r = self.instantiate_const_expr(rhs, None, tmp_tv_cache)?; - let r = self.eval_tp(r)?; - if let Some(Greater) = self.try_cmp(&l, &r) { - panic!("{l}..{r} is not a valid interval type (should be lhs <= rhs)") - } - Ok(int_interval(op, l, r)) - } - TypeSpec::Subr(subr) => { - let mut inner_tv_ctx = if !subr.bounds.is_empty() { - let tv_cache = self.instantiate_ty_bounds(&subr.bounds, mode)?; - Some(tv_cache) - } else { - None - }; - if let Some(inner) = &mut inner_tv_ctx { - inner.merge(tmp_tv_cache); - } - let tmp_tv_ctx = if let Some(inner) = &mut inner_tv_ctx { - inner - } else { - tmp_tv_cache - }; - let non_defaults = try_map_mut(subr.non_defaults.iter(), |p| { - self.instantiate_func_param_spec(p, opt_decl_t, None, tmp_tv_ctx, mode) - })?; - let var_params = subr - .var_params - .as_ref() - .map(|p| { - self.instantiate_func_param_spec(p, opt_decl_t, None, tmp_tv_ctx, mode) - }) - .transpose()?; - let defaults = try_map_mut(subr.defaults.iter(), |p| { - self.instantiate_func_param_spec( - &p.param, - opt_decl_t, - Some(&p.default), - tmp_tv_ctx, - mode, - ) - })? - .into_iter() - .collect(); - let return_t = self.instantiate_typespec( - &subr.return_t, - opt_decl_t, - tmp_tv_ctx, - mode, - not_found_is_qvar, - )?; - Ok(subr_t( - SubrKind::from(subr.arrow.kind), - non_defaults, - var_params, - defaults, - return_t, - )) - } - TypeSpec::TypeApp { spec, args } => { - type_feature_error!( - self, - t_spec.loc(), - &format!("instantiating type spec {spec}{args}") - ) - } - } - } - - pub(crate) fn instantiate_ty_bound( - &self, - bound: &TypeBoundSpec, - tv_cache: &mut TyVarCache, - mode: RegistrationMode, - ) -> TyCheckResult<()> { - // REVIEW: 型境界の左辺に来れるのは型変数だけか? - // TODO: 高階型変数 - match bound { - TypeBoundSpec::Omitted(name) => { - // TODO: other than type `Type` - let constr = Constraint::new_type_of(Type); - let tv = named_free_var(name.inspect().clone(), self.level, constr); - tv_cache.push_or_init_tyvar(name.inspect(), &tv); - Ok(()) - } - TypeBoundSpec::NonDefault { lhs, spec } => { - let constr = - match spec.op.kind { - TokenKind::SubtypeOf => Constraint::new_subtype_of( - self.instantiate_typespec(&spec.t_spec, None, tv_cache, mode, true)?, - ), - TokenKind::SupertypeOf => Constraint::new_supertype_of( - self.instantiate_typespec(&spec.t_spec, None, tv_cache, mode, true)?, - ), - TokenKind::Colon => Constraint::new_type_of(self.instantiate_typespec( - &spec.t_spec, - None, - tv_cache, - mode, - true, - )?), - _ => unreachable!(), - }; - if constr.get_sub_sup().is_none() { - let tp = TyParam::named_free_var(lhs.inspect().clone(), self.level, constr); - tv_cache.push_or_init_typaram(lhs.inspect(), &tp); - } else { - let tv = named_free_var(lhs.inspect().clone(), self.level, constr); - tv_cache.push_or_init_tyvar(lhs.inspect(), &tv); - } - Ok(()) - } - TypeBoundSpec::WithDefault { .. } => type_feature_error!( - self, - bound.loc(), - "type boundary specification with default" - ), - } - } - - pub(crate) fn instantiate_ty_bounds( - &self, - bounds: &TypeBoundSpecs, - mode: RegistrationMode, - ) -> TyCheckResult { - let mut tv_cache = TyVarCache::new(self.level, self); - for bound in bounds.iter() { - self.instantiate_ty_bound(bound, &mut tv_cache, mode)?; - } - for tv in tv_cache.tyvar_instances.values() { - if tv.constraint().map(|c| c.is_uninited()).unwrap_or(false) { - return Err(TyCheckErrors::from(TyCheckError::no_var_error( - self.cfg.input.clone(), - line!() as usize, - bounds.loc(), - self.caused_by(), - &tv.local_name(), - self.get_similar_name(&tv.local_name()), - ))); - } - } - for tp in tv_cache.typaram_instances.values() { - if tp.constraint().map(|c| c.is_uninited()).unwrap_or(false) { - return Err(TyCheckErrors::from(TyCheckError::no_var_error( - self.cfg.input.clone(), - line!() as usize, - bounds.loc(), - self.caused_by(), - &tp.to_string(), - self.get_similar_name(&tp.to_string()), - ))); - } - } - Ok(tv_cache) - } - fn instantiate_tp( &self, quantified: TyParam, diff --git a/crates/erg_compiler/context/instantiate_spec.rs b/crates/erg_compiler/context/instantiate_spec.rs new file mode 100644 index 000000000..9195e3e72 --- /dev/null +++ b/crates/erg_compiler/context/instantiate_spec.rs @@ -0,0 +1,1212 @@ +use std::option::Option; // conflicting to Type::Option + +#[allow(unused)] +use erg_common::log; +use erg_common::traits::{Locational, Stream}; +use erg_common::Str; +use erg_common::{assume_unreachable, dict, enum_unwrap, set, try_map_mut}; + +use ast::{ + NonDefaultParamSignature, ParamTySpec, PreDeclTypeSpec, SimpleTypeSpec, TypeBoundSpec, + TypeBoundSpecs, TypeSpec, +}; +use erg_parser::ast::{self, Identifier, VisModifierSpec, VisRestriction}; +use erg_parser::token::TokenKind; +use erg_parser::Parser; + +use crate::feature_error; +use crate::ty::free::{CanbeFree, Constraint}; +use crate::ty::typaram::{IntervalOp, OpKind, TyParam, TyParamLambda, TyParamOrdering}; +use crate::ty::value::ValueObj; +use crate::ty::{constructors::*, VisibilityModifier}; +use crate::ty::{Field, HasType, ParamTy, SubrKind, SubrType, Type}; +use crate::type_feature_error; +use TyParamOrdering::*; +use Type::*; + +use crate::context::instantiate::TyVarCache; +use crate::context::{Context, DefaultInfo, RegistrationMode}; +use crate::error::{TyCheckError, TyCheckErrors, TyCheckResult}; +use crate::AccessKind; +use RegistrationMode::*; + +pub fn token_kind_to_op_kind(kind: TokenKind) -> Option { + match kind { + TokenKind::Plus => Some(OpKind::Add), + TokenKind::Minus => Some(OpKind::Sub), + TokenKind::Star => Some(OpKind::Mul), + TokenKind::Slash => Some(OpKind::Div), + TokenKind::FloorDiv => Some(OpKind::FloorDiv), + TokenKind::Mod => Some(OpKind::Mod), + TokenKind::Pow => Some(OpKind::Pow), + TokenKind::PrePlus => Some(OpKind::Pos), + TokenKind::PreMinus => Some(OpKind::Neg), + TokenKind::PreBitNot => Some(OpKind::Invert), + TokenKind::Equal => Some(OpKind::Eq), + TokenKind::NotEq => Some(OpKind::Ne), + TokenKind::Less => Some(OpKind::Lt), + TokenKind::LessEq => Some(OpKind::Le), + TokenKind::Gre => Some(OpKind::Gt), + TokenKind::GreEq => Some(OpKind::Ge), + TokenKind::AndOp => Some(OpKind::And), + TokenKind::OrOp => Some(OpKind::Or), + TokenKind::BitAnd => Some(OpKind::BitAnd), + TokenKind::BitOr => Some(OpKind::BitOr), + TokenKind::BitXor => Some(OpKind::BitXor), + TokenKind::Shl => Some(OpKind::Shl), + TokenKind::Shr => Some(OpKind::Shr), + _ => None, + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ParamKind { + NonDefault, + Default(Type), + VarParams, + KwParams, +} + +impl ParamKind { + pub const fn is_var_params(&self) -> bool { + matches!(self, ParamKind::VarParams) + } + pub const fn is_kw_params(&self) -> bool { + matches!(self, ParamKind::KwParams) + } + pub const fn is_default(&self) -> bool { + matches!(self, ParamKind::Default(_)) + } + pub const fn default_info(&self) -> DefaultInfo { + match self { + ParamKind::Default(_) => DefaultInfo::WithDefault, + _ => DefaultInfo::NonDefault, + } + } +} + +/// TODO: this struct will be removed when const functions are implemented. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum ConstTemplate { + Obj(ValueObj), + App { + name: Str, + non_default_args: Vec, + default_args: Vec, + }, +} + +impl ConstTemplate { + pub const fn app( + name: &'static str, + non_default_args: Vec, + default_args: Vec, + ) -> Self { + ConstTemplate::App { + name: Str::ever(name), + non_default_args, + default_args, + } + } +} + +impl Context { + pub(crate) fn instantiate_ty_bound( + &self, + bound: &TypeBoundSpec, + tv_cache: &mut TyVarCache, + mode: RegistrationMode, + ) -> TyCheckResult<()> { + // REVIEW: 型境界の左辺に来れるのは型変数だけか? + // TODO: 高階型変数 + match bound { + TypeBoundSpec::Omitted(name) => { + // TODO: other than type `Type` + let constr = Constraint::new_type_of(Type); + let tv = named_free_var(name.inspect().clone(), self.level, constr); + tv_cache.push_or_init_tyvar(name.inspect(), &tv); + Ok(()) + } + TypeBoundSpec::NonDefault { lhs, spec } => { + let constr = + match spec.op.kind { + TokenKind::SubtypeOf => Constraint::new_subtype_of( + self.instantiate_typespec(&spec.t_spec, None, tv_cache, mode, true)?, + ), + TokenKind::SupertypeOf => Constraint::new_supertype_of( + self.instantiate_typespec(&spec.t_spec, None, tv_cache, mode, true)?, + ), + TokenKind::Colon => Constraint::new_type_of(self.instantiate_typespec( + &spec.t_spec, + None, + tv_cache, + mode, + true, + )?), + _ => unreachable!(), + }; + if constr.get_sub_sup().is_none() { + let tp = TyParam::named_free_var(lhs.inspect().clone(), self.level, constr); + tv_cache.push_or_init_typaram(lhs.inspect(), &tp); + } else { + let tv = named_free_var(lhs.inspect().clone(), self.level, constr); + tv_cache.push_or_init_tyvar(lhs.inspect(), &tv); + } + Ok(()) + } + TypeBoundSpec::WithDefault { .. } => type_feature_error!( + self, + bound.loc(), + "type boundary specification with default" + ), + } + } + + pub(crate) fn instantiate_ty_bounds( + &self, + bounds: &TypeBoundSpecs, + mode: RegistrationMode, + ) -> TyCheckResult { + let mut tv_cache = TyVarCache::new(self.level, self); + for bound in bounds.iter() { + self.instantiate_ty_bound(bound, &mut tv_cache, mode)?; + } + for tv in tv_cache.tyvar_instances.values() { + if tv.constraint().map(|c| c.is_uninited()).unwrap_or(false) { + return Err(TyCheckErrors::from(TyCheckError::no_var_error( + self.cfg.input.clone(), + line!() as usize, + bounds.loc(), + self.caused_by(), + &tv.local_name(), + self.get_similar_name(&tv.local_name()), + ))); + } + } + for tp in tv_cache.typaram_instances.values() { + if tp.constraint().map(|c| c.is_uninited()).unwrap_or(false) { + return Err(TyCheckErrors::from(TyCheckError::no_var_error( + self.cfg.input.clone(), + line!() as usize, + bounds.loc(), + self.caused_by(), + &tp.to_string(), + self.get_similar_name(&tp.to_string()), + ))); + } + } + Ok(tv_cache) + } + + pub(crate) fn instantiate_var_sig_t( + &self, + t_spec: Option<&TypeSpec>, + mode: RegistrationMode, + ) -> TyCheckResult { + let mut tmp_tv_cache = TyVarCache::new(self.level, self); + let spec_t = if let Some(t_spec) = t_spec { + self.instantiate_typespec(t_spec, None, &mut tmp_tv_cache, mode, false)? + } else { + free_var(self.level, Constraint::new_type_of(Type)) + }; + Ok(spec_t) + } + + pub(crate) fn instantiate_sub_sig_t( + &self, + sig: &ast::SubrSignature, + default_ts: Vec, + mode: RegistrationMode, + ) -> Result { + let mut errs = TyCheckErrors::empty(); + // -> Result { + let opt_decl_sig_t = match self + .rec_get_decl_info(&sig.ident, AccessKind::Name, &self.cfg.input, self) + .ok() + .map(|vi| vi.t) + { + Some(Type::Subr(subr)) => Some(subr), + Some(Type::FreeVar(fv)) if fv.is_unbound() => return Ok(Type::FreeVar(fv)), + Some(other) => { + let err = TyCheckError::unreachable( + self.cfg.input.clone(), + "instantiate_sub_sig_t", + line!(), + ); + return Err((TyCheckErrors::from(err), other)); + } + None => None, + }; + let mut tmp_tv_cache = self + .instantiate_ty_bounds(&sig.bounds, PreRegister) + .map_err(|errs| (errs, Type::Failure))?; + let mut non_defaults = vec![]; + for (n, param) in sig.params.non_defaults.iter().enumerate() { + let opt_decl_t = opt_decl_sig_t + .as_ref() + .and_then(|subr| subr.non_default_params.get(n)); + match self.instantiate_param_ty( + param, + opt_decl_t, + &mut tmp_tv_cache, + mode, + ParamKind::NonDefault, + ) { + Ok(pt) => non_defaults.push(pt), + Err(es) => { + errs.extend(es); + non_defaults.push(ParamTy::pos(param.inspect().cloned(), Type::Failure)); + } + } + } + let var_args = if let Some(var_args) = sig.params.var_params.as_ref() { + let opt_decl_t = opt_decl_sig_t + .as_ref() + .and_then(|subr| subr.var_params.as_ref().map(|v| v.as_ref())); + let pt = match self.instantiate_param_ty( + var_args, + opt_decl_t, + &mut tmp_tv_cache, + mode, + ParamKind::VarParams, + ) { + Ok(pt) => pt, + Err(es) => { + errs.extend(es); + ParamTy::pos(var_args.inspect().cloned(), Type::Failure) + } + }; + Some(pt) + } else { + None + }; + let mut defaults = vec![]; + for ((n, p), default_t) in sig.params.defaults.iter().enumerate().zip(default_ts) { + let opt_decl_t = opt_decl_sig_t + .as_ref() + .and_then(|subr| subr.default_params.get(n)); + match self.instantiate_param_ty( + &p.sig, + opt_decl_t, + &mut tmp_tv_cache, + mode, + ParamKind::Default(default_t), + ) { + Ok(pt) => defaults.push(pt), + Err(es) => { + errs.extend(es); + defaults.push(ParamTy::pos(p.sig.inspect().cloned(), Type::Failure)); + } + } + } + let spec_return_t = if let Some(t_spec) = sig.return_t_spec.as_ref() { + let opt_decl_t = opt_decl_sig_t + .as_ref() + .map(|subr| ParamTy::anonymous(subr.return_t.as_ref().clone())); + match self.instantiate_typespec( + t_spec, + opt_decl_t.as_ref(), + &mut tmp_tv_cache, + mode, + false, + ) { + Ok(ty) => ty, + Err(es) => { + errs.extend(es); + Type::Failure + } + } + } else { + // preregisterならouter scopeで型宣言(see inference.md) + let level = if mode == PreRegister { + self.level + } else { + self.level + 1 + }; + free_var(level, Constraint::new_type_of(Type)) + }; + let typ = if sig.ident.is_procedural() { + proc(non_defaults, var_args, defaults, spec_return_t) + } else { + func(non_defaults, var_args, defaults, spec_return_t) + }; + if errs.is_empty() { + Ok(typ) + } else { + Err((errs, typ)) + } + } + + /// spec_t == Noneかつリテラル推論が不可能なら型変数を発行する + pub(crate) fn instantiate_param_sig_t( + &self, + sig: &NonDefaultParamSignature, + opt_decl_t: Option<&ParamTy>, + tmp_tv_cache: &mut TyVarCache, + mode: RegistrationMode, + kind: ParamKind, + ) -> TyCheckResult { + let gen_free_t = || { + let level = if mode == PreRegister { + self.level + } else { + self.level + 1 + }; + free_var(level, Constraint::new_type_of(Type)) + }; + let spec_t = if let Some(spec_with_op) = &sig.t_spec { + self.instantiate_typespec(&spec_with_op.t_spec, opt_decl_t, tmp_tv_cache, mode, false)? + } else { + match &sig.pat { + ast::ParamPattern::Lit(lit) => v_enum(set![self.eval_lit(lit)?]), + ast::ParamPattern::Discard(_) => Type::Obj, + ast::ParamPattern::Ref(_) => ref_(gen_free_t()), + ast::ParamPattern::RefMut(_) => ref_mut(gen_free_t(), None), + // ast::ParamPattern::VarName(name) if &name.inspect()[..] == "_" => Type::Obj, + // TODO: Array + _ => gen_free_t(), + } + }; + if let Some(decl_pt) = opt_decl_t { + if kind.is_var_params() { + let spec_t = unknown_len_array_t(spec_t.clone()); + self.sub_unify( + decl_pt.typ(), + &spec_t, + &sig.t_spec.as_ref().ok_or(sig), + None, + )?; + } else { + self.sub_unify( + decl_pt.typ(), + &spec_t, + &sig.t_spec.as_ref().ok_or(sig), + None, + )?; + } + } + Ok(spec_t) + } + + pub(crate) fn instantiate_param_ty( + &self, + sig: &NonDefaultParamSignature, + opt_decl_t: Option<&ParamTy>, + tmp_tv_cache: &mut TyVarCache, + mode: RegistrationMode, + kind: ParamKind, + ) -> TyCheckResult { + let t = self.instantiate_param_sig_t(sig, opt_decl_t, tmp_tv_cache, mode, kind.clone())?; + match (sig.inspect(), kind) { + (Some(name), ParamKind::Default(default_t)) => { + Ok(ParamTy::kw_default(name.clone(), t, default_t)) + } + (Some(name), _) => Ok(ParamTy::kw(name.clone(), t)), + (None, _) => Ok(ParamTy::anonymous(t)), + } + } + + pub(crate) fn instantiate_predecl_t( + &self, + predecl: &PreDeclTypeSpec, + opt_decl_t: Option<&ParamTy>, + tmp_tv_cache: &mut TyVarCache, + not_found_is_qvar: bool, + ) -> TyCheckResult { + match predecl { + ast::PreDeclTypeSpec::Simple(simple) => { + self.instantiate_simple_t(simple, opt_decl_t, tmp_tv_cache, not_found_is_qvar) + } + ast::PreDeclTypeSpec::Attr { namespace, t } => { + if let Ok(receiver) = Parser::validate_const_expr(namespace.as_ref().clone()) { + if let Ok(receiver_t) = + self.instantiate_const_expr_as_type(&receiver, None, tmp_tv_cache) + { + let rhs = t.ident.inspect(); + return Ok(proj(receiver_t, rhs)); + } + } + let ctx = self.get_singular_ctx(namespace.as_ref(), self)?; + if let Some((typ, _)) = ctx.rec_local_get_type(t.ident.inspect()) { + let vi = ctx + .rec_get_var_info(&t.ident, AccessKind::Name, &self.cfg.input, self) + .unwrap(); + self.inc_ref(&vi, &t.ident.name); + // TODO: visibility check + Ok(typ.clone()) + } else { + Err(TyCheckErrors::from(TyCheckError::no_var_error( + self.cfg.input.clone(), + line!() as usize, + t.loc(), + self.caused_by(), + t.ident.inspect(), + self.get_similar_name(t.ident.inspect()), + ))) + } + } + other => type_feature_error!(self, other.loc(), &format!("instantiating type {other}")), + } + } + + pub(crate) fn instantiate_simple_t( + &self, + simple: &SimpleTypeSpec, + opt_decl_t: Option<&ParamTy>, + tmp_tv_cache: &mut TyVarCache, + not_found_is_qvar: bool, + ) -> TyCheckResult { + self.inc_ref_simple_typespec(simple); + match &simple.ident.inspect()[..] { + "_" | "Obj" => Ok(Type::Obj), + "Nat" => Ok(Type::Nat), + "Int" => Ok(Type::Int), + "Ratio" => Ok(Type::Ratio), + "Float" => Ok(Type::Float), + "Str" => Ok(Type::Str), + "Bool" => Ok(Type::Bool), + "NoneType" => Ok(Type::NoneType), + "Ellipsis" => Ok(Type::Ellipsis), + "NotImplemented" => Ok(Type::NotImplementedType), + "Inf" => Ok(Type::Inf), + "NegInf" => Ok(Type::NegInf), + "Never" => Ok(Type::Never), + "ClassType" => Ok(Type::ClassType), + "TraitType" => Ok(Type::TraitType), + "Type" => Ok(Type::Type), + "Array" => { + // TODO: kw + let mut args = simple.args.pos_args(); + if let Some(first) = args.next() { + let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; + let len = if let Some(len) = args.next() { + self.instantiate_const_expr(&len.expr, None, tmp_tv_cache)? + } else { + TyParam::erased(Nat) + }; + Ok(array_t(t, len)) + } else { + Ok(mono("GenericArray")) + } + } + "Ref" => { + let mut args = simple.args.pos_args(); + let Some(first) = args.next() else { + return Err(TyCheckErrors::from(TyCheckError::args_missing_error( + self.cfg.input.clone(), + line!() as usize, + simple.args.loc(), + "Ref", + self.caused_by(), + vec![Str::from("T")], + ))); + }; + let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; + Ok(ref_(t)) + } + "RefMut" => { + // TODO after + let mut args = simple.args.pos_args(); + let Some(first) = args.next() else { + return Err(TyCheckErrors::from(TyCheckError::args_missing_error( + self.cfg.input.clone(), + line!() as usize, + simple.args.loc(), + "RefMut", + self.caused_by(), + vec![Str::from("T")], + ))); + }; + let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; + Ok(ref_mut(t, None)) + } + "Structural" => { + let mut args = simple.args.pos_args(); + let Some(first) = args.next() else { + return Err(TyCheckErrors::from(TyCheckError::args_missing_error( + self.cfg.input.clone(), + line!() as usize, + simple.args.loc(), + "Structural", + self.caused_by(), + vec![Str::from("Type")], + ))); + }; + let t = self.instantiate_const_expr_as_type(&first.expr, None, tmp_tv_cache)?; + Ok(t.structuralize()) + } + "Self" => self.rec_get_self_t().ok_or_else(|| { + TyCheckErrors::from(TyCheckError::unreachable( + self.cfg.input.clone(), + erg_common::fn_name_full!(), + line!(), + )) + }), + other if simple.args.is_empty() => { + if let Some(t) = tmp_tv_cache.get_tyvar(other) { + return Ok(t.clone()); + } else if let Some(tp) = tmp_tv_cache.get_typaram(other) { + let t = enum_unwrap!(tp, TyParam::Type); + return Ok(t.as_ref().clone()); + } + if let Some(tv_cache) = &self.tv_cache { + if let Some(t) = tv_cache.get_tyvar(other) { + return Ok(t.clone()); + } else if let Some(tp) = tv_cache.get_typaram(other) { + let t = enum_unwrap!(tp, TyParam::Type); + return Ok(t.as_ref().clone()); + } + } + if let Some(outer) = &self.outer { + if let Ok(t) = outer.instantiate_simple_t( + simple, + opt_decl_t, + tmp_tv_cache, + not_found_is_qvar, + ) { + return Ok(t); + } + } + if let Some(decl_t) = opt_decl_t { + return Ok(decl_t.typ().clone()); + } + if let Some((typ, _)) = self.get_type(simple.ident.inspect()) { + Ok(typ.clone()) + } else if not_found_is_qvar { + let tyvar = named_free_var(Str::rc(other), self.level, Constraint::Uninited); + tmp_tv_cache.push_or_init_tyvar(simple.ident.inspect(), &tyvar); + Ok(tyvar) + } else { + Err(TyCheckErrors::from(TyCheckError::no_type_error( + self.cfg.input.clone(), + line!() as usize, + simple.loc(), + self.caused_by(), + other, + self.get_similar_name(other), + ))) + } + } + other => { + let ctx = if let Some((_, ctx)) = self.get_type(&Str::rc(other)) { + ctx + } else { + return Err(TyCheckErrors::from(TyCheckError::no_type_error( + self.cfg.input.clone(), + line!() as usize, + simple.ident.loc(), + self.caused_by(), + other, + self.get_similar_name(other), + ))); + }; + // FIXME: kw args + let mut new_params = vec![]; + for (i, arg) in simple.args.pos_args().enumerate() { + let params = + self.instantiate_const_expr(&arg.expr, Some((ctx, i)), tmp_tv_cache); + let params = params.or_else(|e| { + if not_found_is_qvar { + let name = arg.expr.to_string(); + // FIXME: handle `::` as a right way + let name = Str::rc(name.trim_start_matches("::")); + let tp = TyParam::named_free_var( + name.clone(), + self.level, + Constraint::Uninited, + ); + tmp_tv_cache.push_or_init_typaram(&name, &tp); + Ok(tp) + } else { + Err(e) + } + })?; + new_params.push(params); + } + // FIXME: non-builtin + Ok(poly(Str::rc(other), new_params)) + } + } + } + + fn instantiate_local( + &self, + name: &Str, + erased_idx: Option<(&Context, usize)>, + tmp_tv_cache: &mut TyVarCache, + loc: &impl Locational, + ) -> TyCheckResult { + if &name[..] == "_" { + let t = if let Some((ctx, i)) = erased_idx { + ctx.params[i].1.t.clone() + } else { + Type::Uninited + }; + return Ok(TyParam::erased(t)); + } + if let Some(tp) = tmp_tv_cache.get_typaram(name) { + return Ok(tp.clone()); + } else if let Some(t) = tmp_tv_cache.get_tyvar(name) { + return Ok(TyParam::t(t.clone())); + } + if let Some(tv_ctx) = &self.tv_cache { + if let Some(t) = tv_ctx.get_tyvar(name) { + return Ok(TyParam::t(t.clone())); + } else if let Some(tp) = tv_ctx.get_typaram(name) { + return Ok(tp.clone()); + } + } + if let Some(value) = self.rec_get_const_obj(name) { + return Ok(TyParam::Value(value.clone())); + } + Err(TyCheckErrors::from(TyCheckError::no_var_error( + self.cfg.input.clone(), + line!() as usize, + loc.loc(), + self.caused_by(), + name, + self.get_similar_name(name), + ))) + } + + pub(crate) fn instantiate_const_expr( + &self, + expr: &ast::ConstExpr, + erased_idx: Option<(&Context, usize)>, + tmp_tv_cache: &mut TyVarCache, + ) -> TyCheckResult { + match expr { + ast::ConstExpr::Lit(lit) => Ok(TyParam::Value(self.eval_lit(lit)?)), + ast::ConstExpr::Accessor(ast::ConstAccessor::Attr(attr)) => { + let obj = self.instantiate_const_expr(&attr.obj, erased_idx, tmp_tv_cache)?; + Ok(obj.proj(attr.name.inspect())) + } + ast::ConstExpr::Accessor(ast::ConstAccessor::Local(local)) => { + self.inc_ref_const_local(local); + self.instantiate_local(local.inspect(), erased_idx, tmp_tv_cache, local) + } + ast::ConstExpr::Array(array) => { + let mut tp_arr = vec![]; + for (i, elem) in array.elems.pos_args().enumerate() { + let el = + self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?; + tp_arr.push(el); + } + Ok(TyParam::Array(tp_arr)) + } + ast::ConstExpr::Set(set) => { + let mut tp_set = set! {}; + for (i, elem) in set.elems.pos_args().enumerate() { + let el = + self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?; + tp_set.insert(el); + } + Ok(TyParam::Set(tp_set)) + } + ast::ConstExpr::Dict(dict) => { + let mut tp_dict = dict! {}; + for (i, elem) in dict.kvs.iter().enumerate() { + let key = + self.instantiate_const_expr(&elem.key, Some((self, i)), tmp_tv_cache)?; + let val = + self.instantiate_const_expr(&elem.value, Some((self, i)), tmp_tv_cache)?; + tp_dict.insert(key, val); + } + Ok(TyParam::Dict(tp_dict)) + } + ast::ConstExpr::Tuple(tuple) => { + let mut tp_tuple = vec![]; + for (i, elem) in tuple.elems.pos_args().enumerate() { + let el = + self.instantiate_const_expr(&elem.expr, Some((self, i)), tmp_tv_cache)?; + tp_tuple.push(el); + } + Ok(TyParam::Tuple(tp_tuple)) + } + ast::ConstExpr::Record(rec) => { + let mut tp_rec = dict! {}; + for attr in rec.attrs.iter() { + let field = self.instantiate_field(&attr.ident)?; + let val = self.instantiate_const_expr( + attr.body.block.get(0).unwrap(), + None, + tmp_tv_cache, + )?; + tp_rec.insert(field, val); + } + Ok(TyParam::Record(tp_rec)) + } + ast::ConstExpr::Lambda(lambda) => { + let mut _tmp_tv_cache = + self.instantiate_ty_bounds(&lambda.sig.bounds, RegistrationMode::Normal)?; + let tmp_tv_cache = if tmp_tv_cache.is_empty() { + &mut _tmp_tv_cache + } else { + // TODO: prohibit double quantification + tmp_tv_cache + }; + let mut nd_params = Vec::with_capacity(lambda.sig.params.non_defaults.len()); + for sig in lambda.sig.params.non_defaults.iter() { + let pt = self.instantiate_param_ty( + sig, + None, + tmp_tv_cache, + RegistrationMode::Normal, + ParamKind::NonDefault, + )?; + nd_params.push(pt); + } + let var_params = if let Some(p) = lambda.sig.params.var_params.as_ref() { + let pt = self.instantiate_param_ty( + p, + None, + tmp_tv_cache, + RegistrationMode::Normal, + ParamKind::VarParams, + )?; + Some(pt) + } else { + None + }; + let mut d_params = Vec::with_capacity(lambda.sig.params.defaults.len()); + for sig in lambda.sig.params.defaults.iter() { + let expr = self.eval_const_expr(&sig.default_val)?; + let pt = self.instantiate_param_ty( + &sig.sig, + None, + tmp_tv_cache, + RegistrationMode::Normal, + ParamKind::Default(expr.t()), + )?; + d_params.push(pt); + } + let mut body = vec![]; + for expr in lambda.body.iter() { + let param = self.instantiate_const_expr(expr, None, tmp_tv_cache)?; + body.push(param); + } + Ok(TyParam::Lambda(TyParamLambda::new( + lambda.clone(), + nd_params, + var_params, + d_params, + body, + ))) + } + ast::ConstExpr::BinOp(bin) => { + let Some(op) = token_kind_to_op_kind(bin.op.kind) else { + return type_feature_error!( + self, + bin.loc(), + &format!("instantiating const expression {bin}") + ) + }; + let lhs = self.instantiate_const_expr(&bin.lhs, erased_idx, tmp_tv_cache)?; + let rhs = self.instantiate_const_expr(&bin.rhs, erased_idx, tmp_tv_cache)?; + Ok(TyParam::bin(op, lhs, rhs)) + } + ast::ConstExpr::UnaryOp(unary) => { + let Some(op) = token_kind_to_op_kind(unary.op.kind) else { + return type_feature_error!( + self, + unary.loc(), + &format!("instantiating const expression {unary}") + ) + }; + let val = self.instantiate_const_expr(&unary.expr, erased_idx, tmp_tv_cache)?; + Ok(TyParam::unary(op, val)) + } + ast::ConstExpr::TypeAsc(tasc) => { + let tp = self.instantiate_const_expr(&tasc.expr, erased_idx, tmp_tv_cache)?; + let spec_t = self.instantiate_typespec( + &tasc.t_spec.t_spec, + None, + tmp_tv_cache, + RegistrationMode::Normal, + false, + )?; + if self.subtype_of(&self.get_tp_t(&tp)?, &spec_t) { + Ok(tp) + } else { + Err(TyCheckErrors::from(TyCheckError::subtyping_error( + self.cfg.input.clone(), + line!() as usize, + &self.get_tp_t(&tp)?, + &spec_t, + tasc.loc(), + self.caused_by(), + ))) + } + } + other => type_feature_error!( + self, + other.loc(), + &format!("instantiating const expression {other}") + ), + } + } + + pub(crate) fn instantiate_const_expr_as_type( + &self, + expr: &ast::ConstExpr, + erased_idx: Option<(&Context, usize)>, + tmp_tv_cache: &mut TyVarCache, + ) -> TyCheckResult { + let tp = self.instantiate_const_expr(expr, erased_idx, tmp_tv_cache)?; + self.instantiate_tp_as_type(tp, expr) + } + + fn instantiate_tp_as_type(&self, tp: TyParam, loc: &impl Locational) -> TyCheckResult { + match tp { + TyParam::FreeVar(fv) if fv.is_linked() => { + self.instantiate_tp_as_type(fv.crack().clone(), loc) + } + TyParam::Type(t) => Ok(*t), + TyParam::Value(ValueObj::Type(t)) => Ok(t.into_typ()), + TyParam::Set(set) => { + let t = set + .iter() + .next() + .and_then(|tp| self.get_tp_t(tp).ok()) + .unwrap_or(Type::Never); + Ok(tp_enum(t, set)) + } + TyParam::Tuple(ts) => { + let mut tps = vec![]; + for tp in ts { + let t = self.instantiate_tp_as_type(tp, loc)?; + tps.push(t); + } + Ok(tuple_t(tps)) + } + TyParam::Record(rec) => { + let mut rec_t = dict! {}; + for (field, tp) in rec { + let t = self.instantiate_tp_as_type(tp, loc)?; + rec_t.insert(field, t); + } + Ok(Type::Record(rec_t)) + } + TyParam::Lambda(lambda) => { + let return_t = self + .instantiate_tp_as_type(lambda.body.last().unwrap().clone(), &lambda.const_)?; + let subr = SubrType::new( + SubrKind::from(lambda.const_.op.kind), + lambda.nd_params, + lambda.var_params, + lambda.d_params, + return_t, + ); + Ok(Type::Subr(subr)) + } + other => { + type_feature_error!(self, loc.loc(), &format!("instantiate `{other}` as type")) + } + } + } + + fn instantiate_func_param_spec( + &self, + p: &ParamTySpec, + opt_decl_t: Option<&ParamTy>, + default_t: Option<&TypeSpec>, + tmp_tv_cache: &mut TyVarCache, + mode: RegistrationMode, + ) -> TyCheckResult { + let t = self.instantiate_typespec(&p.ty, opt_decl_t, tmp_tv_cache, mode, false)?; + if let Some(default_t) = default_t { + Ok(ParamTy::kw_default( + p.name.as_ref().unwrap().inspect().to_owned(), + t, + self.instantiate_typespec(default_t, opt_decl_t, tmp_tv_cache, mode, false)?, + )) + } else { + Ok(ParamTy::pos( + p.name.as_ref().map(|t| t.inspect().to_owned()), + t, + )) + } + } + + pub(crate) fn instantiate_typespec( + &self, + t_spec: &TypeSpec, + opt_decl_t: Option<&ParamTy>, + tmp_tv_cache: &mut TyVarCache, + mode: RegistrationMode, + not_found_is_qvar: bool, + ) -> TyCheckResult { + match t_spec { + TypeSpec::Infer(_) => Ok(free_var(self.level, Constraint::new_type_of(Type))), + TypeSpec::PreDeclTy(predecl) => Ok(self.instantiate_predecl_t( + predecl, + opt_decl_t, + tmp_tv_cache, + not_found_is_qvar, + )?), + TypeSpec::And(lhs, rhs) => Ok(self.intersection( + &self.instantiate_typespec( + lhs, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + &self.instantiate_typespec( + rhs, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + )), + TypeSpec::Or(lhs, rhs) => Ok(self.union( + &self.instantiate_typespec( + lhs, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + &self.instantiate_typespec( + rhs, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + )), + TypeSpec::Not(ty) => Ok(self.complement(&self.instantiate_typespec( + ty, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?)), + TypeSpec::Array(arr) => { + let elem_t = self.instantiate_typespec( + &arr.ty, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?; + let mut len = self.instantiate_const_expr(&arr.len, None, tmp_tv_cache)?; + if let TyParam::Erased(t) = &mut len { + *t.as_mut() = Type::Nat; + } + Ok(array_t(elem_t, len)) + } + TypeSpec::SetWithLen(set) => { + let elem_t = self.instantiate_typespec( + &set.ty, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?; + let mut len = self.instantiate_const_expr(&set.len, None, tmp_tv_cache)?; + if let TyParam::Erased(t) = &mut len { + *t.as_mut() = Type::Nat; + } + Ok(set_t(elem_t, len)) + } + TypeSpec::Tuple(tup) => { + let mut inst_tys = vec![]; + for spec in tup.tys.iter() { + inst_tys.push(self.instantiate_typespec( + spec, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?); + } + Ok(tuple_t(inst_tys)) + } + TypeSpec::Dict(dict) => { + let mut inst_tys = dict! {}; + for (k, v) in dict { + inst_tys.insert( + self.instantiate_typespec( + k, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + self.instantiate_typespec( + v, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + ); + } + Ok(dict_t(inst_tys.into())) + } + TypeSpec::Record(rec) => { + let mut inst_tys = dict! {}; + for (k, v) in rec { + inst_tys.insert( + self.instantiate_field(k)?, + self.instantiate_typespec( + v, + opt_decl_t, + tmp_tv_cache, + mode, + not_found_is_qvar, + )?, + ); + } + Ok(Type::Record(inst_tys)) + } + // TODO: エラー処理(リテラルでない)はパーサーにやらせる + TypeSpec::Enum(set) => { + let mut new_set = set! {}; + for arg in set.pos_args() { + new_set.insert(self.instantiate_const_expr(&arg.expr, None, tmp_tv_cache)?); + } + let ty = new_set.iter().fold(Type::Never, |t, tp| { + self.union(&t, &self.get_tp_t(tp).unwrap()) + }); + Ok(tp_enum(ty, new_set)) + } + TypeSpec::Interval { op, lhs, rhs } => { + let op = match op.kind { + TokenKind::Closed => IntervalOp::Closed, + TokenKind::LeftOpen => IntervalOp::LeftOpen, + TokenKind::RightOpen => IntervalOp::RightOpen, + TokenKind::Open => IntervalOp::Open, + _ => assume_unreachable!(), + }; + let l = self.instantiate_const_expr(lhs, None, tmp_tv_cache)?; + let l = self.eval_tp(l)?; + let r = self.instantiate_const_expr(rhs, None, tmp_tv_cache)?; + let r = self.eval_tp(r)?; + if let Some(Greater) = self.try_cmp(&l, &r) { + panic!("{l}..{r} is not a valid interval type (should be lhs <= rhs)") + } + Ok(int_interval(op, l, r)) + } + TypeSpec::Subr(subr) => { + let mut inner_tv_ctx = if !subr.bounds.is_empty() { + let tv_cache = self.instantiate_ty_bounds(&subr.bounds, mode)?; + Some(tv_cache) + } else { + None + }; + if let Some(inner) = &mut inner_tv_ctx { + inner.merge(tmp_tv_cache); + } + let tmp_tv_ctx = if let Some(inner) = &mut inner_tv_ctx { + inner + } else { + tmp_tv_cache + }; + let non_defaults = try_map_mut(subr.non_defaults.iter(), |p| { + self.instantiate_func_param_spec(p, opt_decl_t, None, tmp_tv_ctx, mode) + })?; + let var_params = subr + .var_params + .as_ref() + .map(|p| { + self.instantiate_func_param_spec(p, opt_decl_t, None, tmp_tv_ctx, mode) + }) + .transpose()?; + let defaults = try_map_mut(subr.defaults.iter(), |p| { + self.instantiate_func_param_spec( + &p.param, + opt_decl_t, + Some(&p.default), + tmp_tv_ctx, + mode, + ) + })? + .into_iter() + .collect(); + let return_t = self.instantiate_typespec( + &subr.return_t, + opt_decl_t, + tmp_tv_ctx, + mode, + not_found_is_qvar, + )?; + Ok(subr_t( + SubrKind::from(subr.arrow.kind), + non_defaults, + var_params, + defaults, + return_t, + )) + } + TypeSpec::TypeApp { spec, args } => { + type_feature_error!( + self, + t_spec.loc(), + &format!("instantiating type spec {spec}{args}") + ) + } + } + } + + pub fn instantiate_field(&self, ident: &Identifier) -> TyCheckResult { + let vis = self.instantiate_vis_modifier(&ident.vis)?; + Ok(Field::new(vis, ident.inspect().clone())) + } + + pub fn instantiate_vis_modifier( + &self, + spec: &VisModifierSpec, + ) -> TyCheckResult { + match spec { + VisModifierSpec::Auto => unreachable!(), + VisModifierSpec::Private | VisModifierSpec::ExplicitPrivate(_) => { + Ok(VisibilityModifier::Private) + } + VisModifierSpec::Public(_) => Ok(VisibilityModifier::Public), + VisModifierSpec::Restricted(rest) => match &rest { + VisRestriction::Namespaces(namespace) => { + let mut namespaces = set! {}; + for ns in namespace.iter() { + let ast::Accessor::Ident(ident) = ns else { + return feature_error!(TyCheckErrors, TyCheckError, self, ns.loc(), "namespace accessors"); + }; + let vi = self + .rec_get_var_info(ident, AccessKind::Name, &self.cfg.input, self) + .none_or_result(|| { + TyCheckError::no_var_error( + self.cfg.input.clone(), + line!() as usize, + ident.loc(), + self.caused_by(), + ident.inspect(), + None, + ) + })?; + let name = Str::from(format!( + "{}{}{}", + vi.vis.def_namespace, + vi.vis.modifier.display_as_accessor(), + ident.inspect() + )); + namespaces.insert(name); + } + Ok(VisibilityModifier::Restricted(namespaces)) + } + VisRestriction::SubtypeOf(typ) => { + let mut dummy_tv_cache = TyVarCache::new(self.level, self); + let t = self.instantiate_typespec( + typ, + None, + &mut dummy_tv_cache, + RegistrationMode::Normal, + false, + )?; + Ok(VisibilityModifier::SubtypeRestricted(t)) + } + }, + } + } +} diff --git a/crates/erg_compiler/context/mod.rs b/crates/erg_compiler/context/mod.rs index 505956f9a..c3d049fcd 100644 --- a/crates/erg_compiler/context/mod.rs +++ b/crates/erg_compiler/context/mod.rs @@ -10,6 +10,7 @@ pub mod hint; pub mod initialize; pub mod inquire; pub mod instantiate; +pub mod instantiate_spec; pub mod register; pub mod test; pub mod unify; @@ -20,12 +21,10 @@ use std::option::Option; // conflicting to Type::Option use std::path::{Path, PathBuf}; use erg_common::config::ErgConfig; -use erg_common::config::Input; 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; use erg_common::Str; use erg_common::{fmt_option, fn_name, get_hash, log}; @@ -33,14 +32,14 @@ use ast::{DefId, DefKind, VarName}; use erg_parser::ast; use erg_parser::token::Token; -use crate::context::instantiate::{ConstTemplate, TyVarCache}; +use crate::context::instantiate::TyVarCache; +use crate::context::instantiate_spec::ConstTemplate; use crate::error::{TyCheckError, TyCheckErrors}; use crate::module::{SharedCompilerResource, SharedModuleCache}; use crate::ty::value::ValueObj; -use crate::ty::{Predicate, Type}; +use crate::ty::{Predicate, Type, Visibility, VisibilityModifier}; use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use Type::*; -use Visibility::*; /// For implementing LSP or other IDE features pub trait ContextProvider { @@ -511,12 +510,30 @@ impl Context { if let Some(name) = param.name { let kind = VarKind::parameter(id, param.is_var_params, param.default_info); let muty = Mutability::from(name); - let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None, param.loc); + let vi = VarInfo::new( + param.t, + muty, + Visibility::private(name), + kind, + None, + None, + None, + param.loc, + ); params_.push((Some(VarName::new(Token::static_symbol(name))), vi)); } else { let kind = VarKind::parameter(id, param.is_var_params, param.default_info); let muty = Mutability::Immutable; - let vi = VarInfo::new(param.t, muty, Private, kind, None, None, None, param.loc); + let vi = VarInfo::new( + param.t, + muty, + Visibility::private(name.clone()), + kind, + None, + None, + None, + param.loc, + ); params_.push((None, vi)); } } @@ -846,16 +863,12 @@ impl Context { ) } - pub(crate) fn module_path(&self) -> Option<&PathBuf> { - if let Input::File(path) = &self.cfg.input { - Some(path) - } else { - None - } + pub(crate) fn module_path(&self) -> Option<&Path> { + self.cfg.input.path() } pub(crate) fn absolutize(&self, loc: Location) -> AbsLocation { - AbsLocation::new(self.module_path().cloned(), loc) + AbsLocation::new(self.module_path().map(PathBuf::from), loc) } #[inline] @@ -925,7 +938,7 @@ impl Context { &mut self, name: &str, kind: ContextKind, - vis: Visibility, + vis: VisibilityModifier, tv_cache: Option, ) { let name = if vis.is_public() { @@ -999,6 +1012,7 @@ impl Context { } } + /// enumerates all the variables/methods in the current context & super contexts. fn type_dir(&self) -> Vec<(&VarName, &VarInfo)> { let mut vars: Vec<_> = self .locals diff --git a/crates/erg_compiler/context/register.rs b/crates/erg_compiler/context/register.rs index e13c0af0b..b578a9639 100644 --- a/crates/erg_compiler/context/register.rs +++ b/crates/erg_compiler/context/register.rs @@ -11,7 +11,7 @@ use erg_common::levenshtein::get_similar_name; use erg_common::python_util::BUILTIN_PYTHON_MODS; use erg_common::set::Set; use erg_common::traits::{Locational, Stream}; -use erg_common::vis::Visibility; +use erg_common::triple::Triple; use erg_common::Str; use erg_common::{enum_unwrap, get_hash, log, set}; @@ -23,7 +23,7 @@ use crate::ty::constructors::{ }; use crate::ty::free::{Constraint, FreeKind, HasLevel}; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; -use crate::ty::{HasType, ParamTy, SubrType, Type}; +use crate::ty::{HasType, ParamTy, SubrType, Type, Visibility}; use crate::build_hir::HIRBuilder; use crate::context::{ @@ -38,9 +38,9 @@ use crate::varinfo::{AbsLocation, Mutability, VarInfo, VarKind}; use crate::{feature_error, hir}; use Mutability::*; use RegistrationMode::*; -use Visibility::*; -use super::instantiate::{ParamKind, TyVarCache}; +use super::instantiate::TyVarCache; +use super::instantiate_spec::ParamKind; /// format: /// ```python @@ -133,7 +133,7 @@ impl Context { } other => unreachable!("{other}"), }; - let vis = ident.vis(); + let vis = self.instantiate_vis_modifier(&ident.vis)?; let kind = id.map_or(VarKind::Declared, VarKind::Defined); let sig_t = self.instantiate_var_sig_t(sig.t_spec.as_ref(), PreRegister)?; let py_name = if let ContextKind::PatchMethodDefs(_base) = &self.kind { @@ -153,7 +153,7 @@ impl Context { let vi = VarInfo::new( sig_t, muty, - vis, + Visibility::new(vis, self.name.clone()), kind, None, self.impl_of(), @@ -172,7 +172,7 @@ impl Context { id: Option, ) -> TyCheckResult<()> { let name = sig.ident.inspect(); - let vis = sig.ident.vis(); + let vis = self.instantiate_vis_modifier(&sig.ident.vis)?; let muty = Mutability::from(&name[..]); let kind = id.map_or(VarKind::Declared, VarKind::Defined); let comptime_decos = sig @@ -199,7 +199,7 @@ impl Context { let vi = VarInfo::new( t, muty, - vis, + Visibility::new(vis, self.name.clone()), kind, Some(comptime_decos), self.impl_of(), @@ -238,18 +238,19 @@ impl Context { ast::VarPattern::Discard(_) => { return Ok(VarInfo { t: body_t.clone(), - ..VarInfo::const_default() + ..VarInfo::const_default_private() }); } - _ => todo!(), + _ => unreachable!(), }; + let vis = self.instantiate_vis_modifier(&ident.vis)?; // already defined as const if sig.is_const() { let vi = self.decls.remove(ident.inspect()).unwrap_or_else(|| { VarInfo::new( body_t.clone(), Mutability::Const, - sig.vis(), + Visibility::new(vis, self.name.clone()), VarKind::Declared, None, self.impl_of(), @@ -270,7 +271,6 @@ impl Context { } else { py_name }; - let vis = ident.vis(); let kind = if id.0 == 0 { VarKind::Declared } else { @@ -279,14 +279,14 @@ impl Context { let vi = VarInfo::new( body_t.clone(), muty, - vis, + Visibility::new(vis, self.name.clone()), kind, None, self.impl_of(), py_name, self.absolutize(ident.name.loc()), ); - log!(info "Registered {}::{}: {}", self.name, ident.name, vi); + log!(info "Registered {}{}: {}", self.name, ident, vi); self.locals.insert(ident.name.clone(), vi.clone()); Ok(vi) } @@ -300,9 +300,9 @@ impl Context { kind: ParamKind, ) -> TyCheckResult<()> { let vis = if cfg!(feature = "py_compatible") { - Public + Visibility::BUILTIN_PUBLIC } else { - Private + Visibility::private(self.name.clone()) }; let default = kind.default_info(); let is_var_params = kind.is_var_params(); @@ -622,6 +622,7 @@ impl Context { self.locals.insert(sig.ident.name.clone(), vi.clone()); return Ok(vi); } + let vis = self.instantiate_vis_modifier(&sig.ident.vis)?; let muty = if sig.ident.is_const() { Mutability::Const } else { @@ -717,7 +718,7 @@ impl Context { let vi = VarInfo::new( found_t, muty, - sig.ident.vis(), + Visibility::new(vis, self.name.clone()), VarKind::Defined(id), Some(comptime_decos), self.impl_of(), @@ -746,6 +747,7 @@ impl Context { return Ok(()); } } + let vis = self.instantiate_vis_modifier(&ident.vis)?; let muty = if ident.is_const() { Mutability::Const } else { @@ -765,7 +767,7 @@ impl Context { let vi = VarInfo::new( failure_t, muty, - ident.vis(), + Visibility::new(vis, self.name.clone()), VarKind::DoesNotExist, Some(comptime_decos), self.impl_of(), @@ -814,7 +816,7 @@ impl Context { ast::Signature::Subr(sig) => { if sig.is_const() { let tv_cache = self.instantiate_ty_bounds(&sig.bounds, PreRegister)?; - let vis = def.sig.vis(); + let vis = self.instantiate_vis_modifier(sig.vis())?; self.grow(__name__, ContextKind::Proc, vis, Some(tv_cache)); let (obj, const_t) = match self.eval_const_block(&def.body.block) { Ok(obj) => (obj.clone(), v_enum(set! {obj})), @@ -852,7 +854,8 @@ impl Context { ast::Signature::Var(sig) => { if sig.is_const() { let kind = ContextKind::from(def.def_kind()); - self.grow(__name__, kind, sig.vis(), None); + let vis = self.instantiate_vis_modifier(sig.vis())?; + self.grow(__name__, kind, vis, None); let (obj, const_t) = match self.eval_const_block(&def.body.block) { Ok(obj) => (obj.clone(), v_enum(set! {obj})), Err(errs) => { @@ -1048,7 +1051,8 @@ impl Context { ident: &Identifier, obj: ValueObj, ) -> CompileResult<()> { - if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { + let vis = self.instantiate_vis_modifier(&ident.vis)?; + if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() { Err(CompileErrors::from(CompileError::reassign_error( self.cfg.input.clone(), line!() as usize, @@ -1068,7 +1072,7 @@ impl Context { let vi = VarInfo::new( v_enum(set! {other.clone()}), Const, - ident.vis(), + Visibility::new(vis, self.name.clone()), VarKind::Defined(id), None, self.impl_of(), @@ -1111,6 +1115,7 @@ impl Context { field.clone(), t.clone(), self.impl_of(), + ctx.name.clone(), ); ctx.decls.insert(varname, vi); } @@ -1120,7 +1125,7 @@ impl Context { "base", other.typ().clone(), Immutable, - Private, + Visibility::BUILTIN_PRIVATE, None, )?; } @@ -1133,12 +1138,18 @@ impl Context { "__new__", new_t.clone(), Immutable, - Private, + Visibility::BUILTIN_PRIVATE, Some("__call__".into()), )?; // 必要なら、ユーザーが独自に上書きする // users can override this if necessary - methods.register_auto_impl("new", new_t, Immutable, Public, None)?; + methods.register_auto_impl( + "new", + new_t, + Immutable, + Visibility::BUILTIN_PUBLIC, + None, + )?; ctx.methods_list .push((ClassDefType::Simple(gen.typ().clone()), methods)); self.register_gen_mono_type(ident, gen, ctx, Const) @@ -1189,6 +1200,7 @@ impl Context { field.clone(), t.clone(), self.impl_of(), + ctx.name.clone(), ); ctx.decls.insert(varname, vi); } @@ -1202,11 +1214,17 @@ impl Context { "__new__", new_t.clone(), Immutable, - Private, + Visibility::BUILTIN_PRIVATE, Some("__call__".into()), )?; // 必要なら、ユーザーが独自に上書きする - methods.register_auto_impl("new", new_t, Immutable, Public, None)?; + methods.register_auto_impl( + "new", + new_t, + Immutable, + Visibility::BUILTIN_PUBLIC, + None, + )?; ctx.methods_list .push((ClassDefType::Simple(gen.typ().clone()), methods)); self.register_gen_mono_type(ident, gen, ctx, Const) @@ -1242,7 +1260,12 @@ impl Context { ); let Some(TypeObj::Builtin(Type::Record(req))) = gen.base_or_sup() else { todo!("{gen}") }; for (field, t) in req.iter() { - let vi = VarInfo::instance_attr(field.clone(), t.clone(), self.impl_of()); + let vi = VarInfo::instance_attr( + field.clone(), + t.clone(), + self.impl_of(), + ctx.name.clone(), + ); ctx.decls .insert(VarName::from_str(field.symbol.clone()), vi); } @@ -1273,8 +1296,12 @@ impl Context { ); if let Some(additional) = additional { for (field, t) in additional.iter() { - let vi = - VarInfo::instance_attr(field.clone(), t.clone(), self.impl_of()); + let vi = VarInfo::instance_attr( + field.clone(), + t.clone(), + self.impl_of(), + ctx.name.clone(), + ); ctx.decls .insert(VarName::from_str(field.symbol.clone()), vi); } @@ -1330,6 +1357,7 @@ impl Context { } pub(crate) fn register_type_alias(&mut self, ident: &Identifier, t: Type) -> CompileResult<()> { + let vis = self.instantiate_vis_modifier(&ident.vis)?; if self.mono_types.contains_key(ident.inspect()) { Err(CompileErrors::from(CompileError::reassign_error( self.cfg.input.clone(), @@ -1338,7 +1366,7 @@ impl Context { self.caused_by(), ident.inspect(), ))) - } else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { + } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() { // TODO: display where defined Err(CompileErrors::from(CompileError::reassign_error( self.cfg.input.clone(), @@ -1354,7 +1382,7 @@ impl Context { let vi = VarInfo::new( Type::Type, muty, - ident.vis(), + Visibility::new(vis, self.name.clone()), VarKind::Defined(id), None, self.impl_of(), @@ -1376,6 +1404,7 @@ impl Context { ctx: Self, muty: Mutability, ) -> CompileResult<()> { + let vis = self.instantiate_vis_modifier(&ident.vis)?; // FIXME: recursive search if self.mono_types.contains_key(ident.inspect()) { Err(CompileErrors::from(CompileError::reassign_error( @@ -1385,7 +1414,7 @@ impl Context { self.caused_by(), ident.inspect(), ))) - } else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { + } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() { Err(CompileErrors::from(CompileError::reassign_error( self.cfg.input.clone(), line!() as usize, @@ -1401,7 +1430,7 @@ impl Context { let vi = VarInfo::new( meta_t, muty, - ident.vis(), + Visibility::new(vis, self.name.clone()), VarKind::Defined(id), None, self.impl_of(), @@ -1454,6 +1483,7 @@ impl Context { ctx: Self, muty: Mutability, ) -> CompileResult<()> { + let vis = self.instantiate_vis_modifier(&ident.vis)?; // FIXME: recursive search if self.patches.contains_key(ident.inspect()) { Err(CompileErrors::from(CompileError::reassign_error( @@ -1463,7 +1493,7 @@ impl Context { self.caused_by(), ident.inspect(), ))) - } else if self.rec_get_const_obj(ident.inspect()).is_some() && ident.vis().is_private() { + } else if self.rec_get_const_obj(ident.inspect()).is_some() && vis.is_private() { Err(CompileErrors::from(CompileError::reassign_error( self.cfg.input.clone(), line!() as usize, @@ -1481,7 +1511,7 @@ impl Context { VarInfo::new( meta_t, muty, - ident.vis(), + Visibility::new(vis, self.name.clone()), VarKind::Defined(id), None, self.impl_of(), @@ -1758,7 +1788,7 @@ impl Context { ))) } else if self.locals.get(ident.inspect()).is_some() { let vi = self.locals.remove(ident.inspect()).unwrap(); - self.deleted_locals.insert(ident.name.clone(), vi); + self.deleted_locals.insert(ident.raw.name.clone(), vi); Ok(()) } else { Err(TyCheckErrors::from(TyCheckError::no_var_error( @@ -1831,7 +1861,7 @@ impl Context { #[allow(clippy::single_match)] match acc { hir::Accessor::Ident(ident) => { - if let Some(vi) = self.get_mut_current_scope_var(&ident.name) { + if let Some(vi) = self.get_mut_current_scope_var(&ident.raw.name) { vi.t = t; } else { return Err(TyCheckErrors::from(TyCheckError::feature_error( @@ -1850,22 +1880,22 @@ impl Context { } pub(crate) fn inc_ref_simple_typespec(&self, simple: &SimpleTypeSpec) { - if let Ok(vi) = self.rec_get_var_info( + if let Triple::Ok(vi) = self.rec_get_var_info( &simple.ident, crate::compile::AccessKind::Name, &self.cfg.input, - &self.name, + self, ) { self.inc_ref(&vi, &simple.ident.name); } } pub(crate) fn inc_ref_const_local(&self, local: &ConstIdentifier) { - if let Ok(vi) = self.rec_get_var_info( + if let Triple::Ok(vi) = self.rec_get_var_info( local, crate::compile::AccessKind::Name, &self.cfg.input, - &self.name, + self, ) { self.inc_ref(&vi, &local.name); } diff --git a/crates/erg_compiler/declare.rs b/crates/erg_compiler/declare.rs index c2bdad789..81adb71c6 100644 --- a/crates/erg_compiler/declare.rs +++ b/crates/erg_compiler/declare.rs @@ -9,7 +9,7 @@ use crate::lower::ASTLowerer; use crate::ty::constructors::mono; use crate::ty::free::HasLevel; use crate::ty::value::{GenTypeObj, TypeObj}; -use crate::ty::{HasType, Type}; +use crate::ty::{HasType, Type, Visibility}; use crate::compile::AccessKind; use crate::context::RegistrationMode; @@ -73,7 +73,7 @@ impl ASTLowerer { .assign_var_sig(&sig, found_body_t, id, py_name.clone())?; } // FIXME: Identifier::new should be used - let mut ident = hir::Identifier::bare(ident.dot.clone(), ident.name.clone()); + let mut ident = hir::Identifier::bare(ident.clone()); ident.vi.t = found_body_t.clone(); ident.vi.py_name = py_name; let sig = hir::VarSignature::new(ident, sig.t_spec); @@ -127,20 +127,15 @@ impl ASTLowerer { let vi = self .module .context - .rec_get_var_info( - &ident, - AccessKind::Name, - self.input(), - &self.module.context.name, - ) + .rec_get_var_info(&ident, AccessKind::Name, self.input(), &self.module.context) .unwrap_or(VarInfo::default()); - let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); + let ident = hir::Identifier::new(ident, None, vi); let acc = hir::Accessor::Ident(ident); Ok(acc) } ast::Accessor::Attr(attr) => { let obj = self.fake_lower_expr(*attr.obj)?; - let ident = hir::Identifier::bare(attr.ident.dot, attr.ident.name); + let ident = hir::Identifier::bare(attr.ident); Ok(obj.attr(ident)) } other => Err(LowerErrors::from(LowerError::declare_error( @@ -177,9 +172,7 @@ impl ASTLowerer { fn fake_lower_call(&self, call: ast::Call) -> LowerResult { let obj = self.fake_lower_expr(*call.obj)?; - let attr_name = call - .attr_name - .map(|ident| hir::Identifier::bare(ident.dot, ident.name)); + let attr_name = call.attr_name.map(hir::Identifier::bare); let args = self.fake_lower_args(call.args)?; Ok(hir::Call::new(obj, attr_name, args)) } @@ -247,12 +240,12 @@ impl ASTLowerer { match sig { ast::Signature::Var(var) => { let ident = var.ident().unwrap().clone(); - let ident = hir::Identifier::bare(ident.dot, ident.name); + let ident = hir::Identifier::bare(ident); let sig = hir::VarSignature::new(ident, var.t_spec); Ok(hir::Signature::Var(sig)) } ast::Signature::Subr(subr) => { - let ident = hir::Identifier::bare(subr.ident.dot, subr.ident.name); + let ident = hir::Identifier::bare(subr.ident); let params = self.fake_lower_params(subr.params)?; let sig = hir::SubrSignature::new(ident, subr.bounds, params, subr.return_t_spec); Ok(hir::Signature::Subr(sig)) @@ -454,19 +447,19 @@ impl ASTLowerer { self.declare_subtype(&ident, &t)?; } let muty = Mutability::from(&ident.inspect()[..]); - let vis = ident.vis(); + let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?; let py_name = Str::rc(ident.inspect().trim_end_matches('!')); let vi = VarInfo::new( t, muty, - vis, + Visibility::new(vis, self.module.context.name.clone()), VarKind::Declared, None, None, Some(py_name), self.module.context.absolutize(ident.loc()), ); - let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); + let ident = hir::Identifier::new(ident, None, vi); let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?; let t_spec = hir::TypeSpecWithOp::new( tasc.t_spec.op, @@ -488,11 +481,10 @@ impl ASTLowerer { RegistrationMode::Normal, false, )?; - let namespace = self.module.context.name.clone(); let ctx = self .module .context - .get_mut_singular_ctx(attr.obj.as_ref(), &namespace)?; + .get_mut_singular_ctx(attr.obj.as_ref(), &self.module.context.name.clone())?; ctx.assign_var_sig( &ast::VarSignature::new(ast::VarPattern::Ident(attr.ident.clone()), None), &t, @@ -501,19 +493,22 @@ impl ASTLowerer { )?; let obj = self.fake_lower_expr(*attr.obj)?; let muty = Mutability::from(&attr.ident.inspect()[..]); - let vis = attr.ident.vis(); + let vis = self + .module + .context + .instantiate_vis_modifier(&attr.ident.vis)?; let py_name = Str::rc(attr.ident.inspect().trim_end_matches('!')); let vi = VarInfo::new( t, muty, - vis, + Visibility::new(vis, self.module.context.name.clone()), VarKind::Declared, None, None, Some(py_name), self.module.context.absolutize(attr.ident.loc()), ); - let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi); + let ident = hir::Identifier::new(attr.ident, None, vi); let attr = obj.attr_expr(ident); let t_spec_expr = self.fake_lower_expr(*tasc.t_spec.t_spec_as_expr)?; let t_spec = hir::TypeSpecWithOp::new( @@ -544,10 +539,11 @@ impl ASTLowerer { return Ok(()); } if ident.is_const() { + let vis = self.module.context.instantiate_vis_modifier(&ident.vis)?; let vi = VarInfo::new( t.clone(), Mutability::Const, - ident.vis(), + Visibility::new(vis, self.module.context.name.clone()), VarKind::Declared, None, None, diff --git a/crates/erg_compiler/effectcheck.rs b/crates/erg_compiler/effectcheck.rs index b437f803c..c74919757 100644 --- a/crates/erg_compiler/effectcheck.rs +++ b/crates/erg_compiler/effectcheck.rs @@ -5,15 +5,12 @@ use erg_common::config::ErgConfig; use erg_common::log; use erg_common::traits::{Locational, Stream}; -use erg_common::vis::Visibility; use erg_common::Str; use erg_parser::token::TokenKind; -use Visibility::*; - -use crate::ty::HasType; use crate::error::{EffectError, EffectErrors}; use crate::hir::{Array, Def, Dict, Expr, Params, Set, Signature, Tuple, HIR}; +use crate::ty::{HasType, Visibility}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] enum BlockKind { @@ -36,7 +33,7 @@ use BlockKind::*; #[derive(Debug)] pub struct SideEffectChecker { cfg: ErgConfig, - path_stack: Vec<(Str, Visibility)>, + path_stack: Vec, block_stack: Vec, errs: EffectErrors, } @@ -52,15 +49,13 @@ impl SideEffectChecker { } fn full_path(&self) -> String { - self.path_stack - .iter() - .fold(String::new(), |acc, (path, vis)| { - if vis.is_public() { - acc + "." + &path[..] - } else { - acc + "::" + &path[..] - } - }) + self.path_stack.iter().fold(String::new(), |acc, vis| { + if vis.is_public() { + acc + "." + &vis.def_namespace[..] + } else { + acc + "::" + &vis.def_namespace[..] + } + }) } /// It is permitted to define a procedure in a function, @@ -85,7 +80,7 @@ impl SideEffectChecker { } pub fn check(mut self, hir: HIR) -> Result { - self.path_stack.push((hir.name.clone(), Private)); + self.path_stack.push(Visibility::private(hir.name.clone())); self.block_stack.push(Module); log!(info "the side-effects checking process has started.{RESET}"); // At the top level, there is no problem with side effects, only check for purity violations. @@ -150,7 +145,8 @@ impl SideEffectChecker { } }, Expr::Record(rec) => { - self.path_stack.push((Str::ever(""), Private)); + self.path_stack + .push(Visibility::private(Str::ever(""))); self.block_stack.push(Instant); for attr in rec.attrs.iter() { self.check_def(attr); @@ -184,10 +180,12 @@ impl SideEffectChecker { Expr::Lambda(lambda) => { let is_proc = lambda.is_procedural(); if is_proc { - self.path_stack.push((Str::ever(""), Private)); + self.path_stack + .push(Visibility::private(Str::ever(""))); self.block_stack.push(Proc); } else { - self.path_stack.push((Str::ever(""), Private)); + self.path_stack + .push(Visibility::private(Str::ever(""))); self.block_stack.push(Func); } lambda.body.iter().for_each(|chunk| self.check_expr(chunk)); @@ -244,10 +242,7 @@ impl SideEffectChecker { } fn check_def(&mut self, def: &Def) { - let name_and_vis = match &def.sig { - Signature::Var(var) => (var.inspect().clone(), var.vis()), - Signature::Subr(subr) => (subr.ident.inspect().clone(), subr.ident.vis()), - }; + let name_and_vis = Visibility::new(def.sig.vis().clone(), def.sig.inspect().clone()); self.path_stack.push(name_and_vis); let is_procedural = def.sig.is_procedural(); let is_subr = def.sig.is_subr(); @@ -360,7 +355,8 @@ impl SideEffectChecker { } }, Expr::Record(record) => { - self.path_stack.push((Str::ever(""), Private)); + self.path_stack + .push(Visibility::private(Str::ever(""))); self.block_stack.push(Instant); for attr in record.attrs.iter() { self.check_def(attr); @@ -433,10 +429,12 @@ impl SideEffectChecker { Expr::Lambda(lambda) => { let is_proc = lambda.is_procedural(); if is_proc { - self.path_stack.push((Str::ever(""), Private)); + self.path_stack + .push(Visibility::private(Str::ever(""))); self.block_stack.push(Proc); } else { - self.path_stack.push((Str::ever(""), Private)); + self.path_stack + .push(Visibility::private(Str::ever(""))); self.block_stack.push(Func); } self.check_params(&lambda.params); diff --git a/crates/erg_compiler/error/lower.rs b/crates/erg_compiler/error/lower.rs index b887abf1c..fba11da9c 100644 --- a/crates/erg_compiler/error/lower.rs +++ b/crates/erg_compiler/error/lower.rs @@ -2,12 +2,12 @@ use erg_common::config::Input; use erg_common::error::{ErrorCore, ErrorKind::*, Location, SubMessage}; use erg_common::style::{StyledStr, StyledString, StyledStrings, Stylize}; use erg_common::traits::Locational; -use erg_common::vis::Visibility; use erg_common::{switch_lang, Str}; use crate::error::*; use crate::hir::{Expr, Identifier}; -use crate::ty::{HasType, Type}; +use crate::ty::{HasType, Type, Visibility}; +use crate::varinfo::VarInfo; pub type LowerError = CompileError; pub type LowerWarning = LowerError; @@ -196,7 +196,47 @@ impl LowerError { "english" => format!("exists a similar name variable: {n}"), ) }); - let found = StyledString::new(name, Some(ERR), Some(ATTR)); + let found = name.with_color_and_attr(ERR, ATTR); + Self::new( + ErrorCore::new( + vec![SubMessage::ambiguous_new(loc, vec![], hint)], + switch_lang!( + "japanese" => format!("{found}という変数は定義されていません"), + "simplified_chinese" => format!("{found}未定义"), + "traditional_chinese" => format!("{found}未定義"), + "english" => format!("{found} is not defined"), + ), + errno, + NameError, + loc, + ), + input, + caused_by, + ) + } + + /// TODO: replace `no_var_error` with this function + pub fn detailed_no_var_error( + input: Input, + errno: usize, + loc: Location, + caused_by: String, + name: &str, + similar_name: Option<&str>, + similar_info: Option<&VarInfo>, + ) -> Self { + let name = readable_name(name); + let hint = similar_name.map(|n| { + let vis = similar_info.map_or("".into(), |vi| vi.vis.modifier.display()); + let n = n.with_color_and_attr(HINT, ATTR); + switch_lang!( + "japanese" => format!("似た名前の{vis}変数があります: {n}"), + "simplified_chinese" => format!("存在相同名称{vis}变量: {n}"), + "traditional_chinese" => format!("存在相同名稱{vis}變量: {n}"), + "english" => format!("exists a similar name {vis} variable: {n}"), + ) + }); + let found = name.with_color_and_attr(ERR, ATTR); Self::new( ErrorCore::new( vec![SubMessage::ambiguous_new(loc, vec![], hint)], @@ -226,7 +266,7 @@ impl LowerError { ) -> Self { let name = readable_name(name); let hint = similar_name.map(|n| { - let n = StyledStr::new(n, Some(HINT), Some(ATTR)); + let n = n.with_color_and_attr(HINT, ATTR); switch_lang!( "japanese" => format!("似た名前の変数があります: {n}"), "simplified_chinese" => format!("存在相同名称变量: {n}"), @@ -234,7 +274,7 @@ impl LowerError { "english" => format!("exists a similar name variable: {n}"), ) }); - let found = StyledString::new(name, Some(ERR), Some(ATTR)); + let found = name.with_color_and_attr(ERR, ATTR); Self::new( ErrorCore::new( vec![SubMessage::ambiguous_new(loc, vec![], hint)], @@ -264,7 +304,7 @@ impl LowerError { ) -> Self { let name = readable_name(name); let hint = similar_name.map(|n| { - let n = StyledStr::new(n, Some(HINT), Some(ATTR)); + let n = n.with_color_and_attr(HINT, ATTR); switch_lang!( "japanese" => format!("似た名前の変数があります: {n}"), "simplified_chinese" => format!("存在相同名称变量: {n}"), @@ -272,7 +312,7 @@ impl LowerError { "english" => format!("exists a similar name variable: {n}"), ) }); - let found = StyledString::new(name, Some(ERR), Some(ATTR)); + let found = name.with_color_and_attr(ERR, ATTR); Self::new( ErrorCore::new( vec![SubMessage::ambiguous_new(loc, vec![], hint)], @@ -396,6 +436,45 @@ impl LowerError { ) } + #[allow(clippy::too_many_arguments)] + pub fn detailed_no_attr_error( + input: Input, + errno: usize, + loc: Location, + caused_by: String, + obj_t: &Type, + name: &str, + similar_name: Option<&str>, + similar_info: Option<&VarInfo>, + ) -> Self { + let hint = similar_name.map(|n| { + let vis = similar_info.map_or("".into(), |vi| vi.vis.modifier.display()); + switch_lang!( + "japanese" => format!("似た名前の{vis}属性があります: {n}"), + "simplified_chinese" => format!("具有相同名称的{vis}属性: {n}"), + "traditional_chinese" => format!("具有相同名稱的{vis}屬性: {n}"), + "english" => format!("has a similar name {vis} attribute: {n}"), + ) + }); + let found = StyledString::new(name, Some(ERR), Some(ATTR)); + Self::new( + ErrorCore::new( + vec![SubMessage::ambiguous_new(loc, vec![], hint)], + switch_lang!( + "japanese" => format!("{obj_t}型オブジェクトに{found}という属性はありません"), + "simplified_chinese" => format!("{obj_t}对象没有属性{found}"), + "traditional_chinese" => format!("{obj_t}對像沒有屬性{found}"), + "english" => format!("{obj_t} object has no attribute {found}"), + ), + errno, + AttributeError, + loc, + ), + input, + caused_by, + ) + } + #[allow(clippy::too_many_arguments)] pub fn singular_no_attr_error( input: Input, @@ -510,21 +589,7 @@ impl LowerError { name: &str, vis: Visibility, ) -> Self { - let visibility = if vis.is_private() { - switch_lang!( - "japanese" => "非公開", - "simplified_chinese" => "私有", - "traditional_chinese" => "私有", - "english" => "private", - ) - } else { - switch_lang!( - "japanese" => "公開", - "simplified_chinese" => "公有", - "traditional_chinese" => "公有", - "english" => "public", - ) - }; + let visibility = vis.modifier.display(); let found = StyledString::new(readable_name(name), Some(ERR), Some(ATTR)); Self::new( ErrorCore::new( diff --git a/crates/erg_compiler/error/mod.rs b/crates/erg_compiler/error/mod.rs index 257011266..1e8f268ad 100644 --- a/crates/erg_compiler/error/mod.rs +++ b/crates/erg_compiler/error/mod.rs @@ -323,7 +323,7 @@ caused from: {fn_name}"), SystemExit, Location::Unknown, ), - Input::Dummy, + Input::dummy(), "".to_owned(), ) } @@ -520,7 +520,7 @@ mod test { varinfo::{AbsLocation, VarInfo}, }; use erg_common::{config::Input, error::Location}; - use erg_parser::ast::VarName; + use erg_parser::ast::{VarName, VisModifierSpec}; // These Erg codes are not correct grammar. // This test make sure sub_msg and hint are displayed correctly. @@ -704,19 +704,17 @@ mod test { errors.push(err); let input = Input::pipe("ambiguous type error".to_string()); - let expr = Identifier::new( - Some(erg_parser::token::Token { - kind: erg_parser::token::TokenKind::EOF, - content: "expr_content".into(), - lineno: 1, - col_begin: 1, - }), + let raw = erg_parser::ast::Identifier::new( + VisModifierSpec::Private, VarName::from_str("variable_name".into()), + ); + let expr = Identifier::new( + raw, None, VarInfo::new( Type::Nat, crate::varinfo::Mutability::Const, - erg_common::vis::Visibility::Private, + crate::ty::Visibility::DUMMY_PRIVATE, crate::varinfo::VarKind::Builtin, None, None, @@ -759,7 +757,7 @@ mod test { let input = Input::pipe("visibility error".to_string()); let loc = Location::Line(1); - let vis = erg_common::vis::Visibility::Private; + let vis = crate::ty::Visibility::DUMMY_PRIVATE; let err = TyCheckError::visibility_error(input, errno, loc, caused_by.to_string(), name, vis); errors.push(err); diff --git a/crates/erg_compiler/hir.rs b/crates/erg_compiler/hir.rs index 8b835f5cb..34ad7b32b 100644 --- a/crates/erg_compiler/hir.rs +++ b/crates/erg_compiler/hir.rs @@ -6,7 +6,6 @@ use erg_common::error::Location; #[allow(unused_imports)] use erg_common::log; use erg_common::traits::{Locational, NestedDisplay, NoTypeDisplay, Stream}; -use erg_common::vis::{Field, Visibility}; use erg_common::Str; use erg_common::{ enum_unwrap, fmt_option, fmt_vec, impl_display_for_enum, impl_display_from_nested, @@ -23,7 +22,7 @@ use erg_parser::token::{Token, TokenKind, DOT}; use crate::ty::constructors::{array_t, dict_t, set_t, tuple_t}; use crate::ty::typaram::TyParam; use crate::ty::value::{GenTypeObj, ValueObj}; -use crate::ty::{HasType, Type}; +use crate::ty::{Field, HasType, Type, VisibilityModifier}; use crate::context::eval::type_from_token_kind; use crate::error::readable_name; @@ -381,22 +380,14 @@ impl Args { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Identifier { - pub dot: Option, - pub name: VarName, + pub raw: ast::Identifier, pub qual_name: Option, pub vi: VarInfo, } impl NestedDisplay for Identifier { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - match &self.dot { - Some(_dot) => { - write!(f, ".{}", self.name)?; - } - None => { - write!(f, "::{}", self.name)?; - } - } + write!(f, "{}", self.raw)?; if let Some(qn) = &self.qual_name { write!(f, "(qual_name: {qn})")?; } @@ -409,10 +400,7 @@ impl NestedDisplay for Identifier { impl NoTypeDisplay for Identifier { fn to_string_notype(&self) -> String { - match &self.dot { - Some(_dot) => format!(".{}", self.name), - None => format!("::{}", self.name), - } + self.raw.to_string() } } @@ -439,56 +427,50 @@ impl HasType for Identifier { impl Locational for Identifier { fn loc(&self) -> Location { - if let Some(dot) = &self.dot { - Location::concat(dot, &self.name) - } else { - self.name.loc() - } + self.raw.loc() } } impl From<&Identifier> for Field { fn from(ident: &Identifier) -> Self { - Self::new(ident.vis(), ident.inspect().clone()) + Self::new(ident.vis().clone(), ident.inspect().clone()) } } impl Identifier { - pub const fn new( - dot: Option, - name: VarName, - qual_name: Option, - vi: VarInfo, - ) -> Self { - Self { - dot, - name, - qual_name, - vi, - } + pub const fn new(raw: ast::Identifier, qual_name: Option, vi: VarInfo) -> Self { + Self { raw, qual_name, vi } } pub fn public(name: &'static str) -> Self { - Self::bare( - Some(Token::from_str(TokenKind::Dot, ".")), - VarName::from_static(name), - ) + let ident = ast::Identifier::public_from_token( + Token::from_str(TokenKind::Dot, "."), + Token::static_symbol(name), + ); + Self::bare(ident) } pub fn private(name: &'static str) -> Self { - Self::bare(None, VarName::from_static(name)) + let ident = ast::Identifier::private_from_token(Token::static_symbol(name)); + Self::bare(ident) } pub fn private_with_line(name: Str, line: u32) -> Self { - Self::bare(None, VarName::from_str_and_line(name, line)) + let ident = ast::Identifier::private_from_token(Token::symbol_with_line(&name, line)); + Self::bare(ident) } pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self { - Self::bare(Some(dot), VarName::from_str_and_line(name, line)) + let ident = ast::Identifier::public_from_token(dot, Token::symbol_with_line(&name, line)); + Self::bare(ident) } - pub const fn bare(dot: Option, name: VarName) -> Self { - Self::new(dot, name, None, VarInfo::const_default()) + pub const fn bare(ident: ast::Identifier) -> Self { + if ident.vis.is_public() { + Self::new(ident, None, VarInfo::const_default_public()) + } else { + Self::new(ident, None, VarInfo::const_default_private()) + } } pub fn is_py_api(&self) -> bool { @@ -496,18 +478,15 @@ impl Identifier { } pub fn is_const(&self) -> bool { - self.name.is_const() + self.raw.is_const() } - pub const fn vis(&self) -> Visibility { - match &self.dot { - Some(_) => Visibility::Public, - None => Visibility::Private, - } + pub fn vis(&self) -> &VisibilityModifier { + &self.vi.vis.modifier } pub const fn inspect(&self) -> &Str { - self.name.inspect() + self.raw.inspect() } /// show dot + name (no qual_name & type) @@ -516,11 +495,11 @@ impl Identifier { } pub fn is_procedural(&self) -> bool { - self.name.is_procedural() + self.raw.is_procedural() } - pub fn downcast(self) -> erg_parser::ast::Identifier { - erg_parser::ast::Identifier::new(self.dot, self.name) + pub fn downcast(self) -> ast::Identifier { + self.raw } } @@ -598,12 +577,20 @@ impl Accessor { Self::Ident(Identifier::public_with_line(DOT, name, line)) } - pub const fn private(name: Token, vi: VarInfo) -> Self { - Self::Ident(Identifier::new(None, VarName::new(name), None, vi)) + pub fn private(name: Token, vi: VarInfo) -> Self { + Self::Ident(Identifier::new( + ast::Identifier::private_from_token(name), + None, + vi, + )) } pub fn public(name: Token, vi: VarInfo) -> Self { - Self::Ident(Identifier::new(Some(DOT), VarName::new(name), None, vi)) + Self::Ident(Identifier::new( + ast::Identifier::public_from_token(DOT, name), + None, + vi, + )) } pub fn attr(obj: Expr, ident: Identifier) -> Self { @@ -655,12 +642,12 @@ impl Accessor { seps.remove(seps.len() - 1) }) .or_else(|| { - let mut raw_parts = ident.name.inspect().split_with(&["'"]); + let mut raw_parts = ident.inspect().split_with(&["'"]); // "'aaa'".split_with(&["'"]) == ["", "aaa", ""] if raw_parts.len() == 3 || raw_parts.len() == 4 { Some(raw_parts.remove(1)) } else { - Some(ident.name.inspect()) + Some(ident.inspect()) } }), _ => None, @@ -1580,9 +1567,13 @@ impl VarSignature { self.ident.inspect() } - pub fn vis(&self) -> Visibility { + pub fn vis(&self) -> &VisibilityModifier { self.ident.vis() } + + pub const fn name(&self) -> &VarName { + &self.ident.raw.name + } } /// Once the default_value is set to Some, all subsequent values must be Some @@ -1864,6 +1855,10 @@ impl SubrSignature { pub fn is_procedural(&self) -> bool { self.ident.is_procedural() } + + pub const fn name(&self) -> &VarName { + &self.ident.raw.name + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -1947,13 +1942,20 @@ impl Signature { } } - pub const fn vis(&self) -> Visibility { + pub fn vis(&self) -> &VisibilityModifier { match self { Self::Var(v) => v.ident.vis(), Self::Subr(s) => s.ident.vis(), } } + pub const fn inspect(&self) -> &Str { + match self { + Self::Var(v) => v.ident.inspect(), + Self::Subr(s) => s.ident.inspect(), + } + } + pub const fn ident(&self) -> &Identifier { match self { Self::Var(v) => &v.ident, @@ -1975,6 +1977,13 @@ impl Signature { } } + pub const fn name(&self) -> &VarName { + match self { + Self::Var(v) => v.name(), + Self::Subr(s) => s.name(), + } + } + pub fn t_spec(&self) -> Option<&TypeSpec> { match self { Self::Var(v) => v.t_spec.as_ref(), diff --git a/crates/erg_compiler/link.rs b/crates/erg_compiler/link.rs index a4b3a555e..0ad888dd0 100644 --- a/crates/erg_compiler/link.rs +++ b/crates/erg_compiler/link.rs @@ -1,7 +1,7 @@ use std::mem; -use std::path::{Path, PathBuf}; +use std::path::Path; -use erg_common::config::{ErgConfig, Input}; +use erg_common::config::ErgConfig; use erg_common::pathutil::squash; use erg_common::python_util::BUILTIN_PYTHON_MODS; use erg_common::traits::Locational; @@ -360,12 +360,7 @@ impl<'a> Linker<'a> { /// x = __import__("a.x").x /// ``` fn replace_py_import(&self, expr: &mut Expr) { - let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { - path.pop(); - path - } else { - PathBuf::new() - }; + let mut dir = self.cfg.input.dir(); let args = &mut enum_unwrap!(expr, Expr::Call).args; let mod_name_lit = enum_unwrap!(args.remove_left_or_key("Path").unwrap(), Expr::Lit); let mod_name_str = enum_unwrap!(mod_name_lit.value.clone(), ValueObj::Str); diff --git a/crates/erg_compiler/lower.rs b/crates/erg_compiler/lower.rs index fc49a2dd4..84025a991 100644 --- a/crates/erg_compiler/lower.rs +++ b/crates/erg_compiler/lower.rs @@ -9,10 +9,10 @@ use erg_common::error::{Location, MultiErrorDisplay}; use erg_common::set; use erg_common::set::Set; use erg_common::traits::{Locational, NoTypeDisplay, Runnable, Stream}; -use erg_common::vis::Visibility; +use erg_common::triple::Triple; use erg_common::{fmt_option, fn_name, log, option_enum_unwrap, switch_lang, Str}; -use erg_parser::ast; +use erg_parser::ast::{self, VisModifierSpec}; use erg_parser::ast::{OperationKind, TypeSpecWithOp, VarName, AST}; use erg_parser::build_ast::ASTBuilder; use erg_parser::token::{Token, TokenKind}; @@ -27,7 +27,7 @@ use crate::ty::constructors::{ use crate::ty::free::Constraint; use crate::ty::typaram::TyParam; use crate::ty::value::{GenTypeObj, TypeObj, ValueObj}; -use crate::ty::{HasType, ParamTy, Type}; +use crate::ty::{HasType, ParamTy, Type, VisibilityModifier}; use crate::context::{ ClassDefType, Context, ContextKind, ContextProvider, ModuleContext, RegistrationMode, @@ -43,7 +43,8 @@ use crate::reorder::Reorderer; use crate::varinfo::{VarInfo, VarKind}; use crate::AccessKind; use crate::{feature_error, unreachable_error}; -use Visibility::*; + +use VisibilityModifier::*; /// Checks & infers types of an AST, and convert (lower) it into a HIR #[derive(Debug)] @@ -624,14 +625,40 @@ impl ASTLowerer { } ast::Accessor::Attr(attr) => { let obj = self.lower_expr(*attr.obj)?; - let vi = self.module.context.get_attr_info( + let vi = match self.module.context.get_attr_info( &obj, &attr.ident, &self.cfg.input, - &self.module.context.name, - )?; + &self.module.context, + ) { + Triple::Ok(vi) => vi, + Triple::Err(errs) => { + self.errs.push(errs); + VarInfo::ILLEGAL.clone() + } + Triple::None => { + let self_t = obj.t(); + let (similar_info, similar_name) = self + .module + .context + .get_similar_attr_and_info(&self_t, attr.ident.inspect()) + .unzip(); + let err = LowerError::detailed_no_attr_error( + self.cfg.input.clone(), + line!() as usize, + attr.ident.loc(), + self.module.context.caused_by(), + &self_t, + attr.ident.inspect(), + similar_name, + similar_info, + ); + self.errs.push(err); + VarInfo::ILLEGAL.clone() + } + }; self.inc_ref(&vi, &attr.ident.name); - let ident = hir::Identifier::new(attr.ident.dot, attr.ident.name, None, vi); + let ident = hir::Identifier::new(attr.ident, None, vi); let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident)); Ok(acc) } @@ -649,7 +676,7 @@ impl ASTLowerer { fn lower_ident(&mut self, ident: ast::Identifier) -> LowerResult { // `match` is a special form, typing is magic - let (vi, __name__) = if ident.vis().is_private() + let (vi, __name__) = if ident.vis.is_private() && (&ident.inspect()[..] == "match" || &ident.inspect()[..] == "match!") { ( @@ -660,22 +687,47 @@ impl ASTLowerer { None, ) } else { + let res = match self.module.context.rec_get_var_info( + &ident, + AccessKind::Name, + &self.cfg.input, + &self.module.context, + ) { + Triple::Ok(vi) => vi, + Triple::Err(err) => { + self.errs.push(err); + VarInfo::ILLEGAL.clone() + } + Triple::None => { + let (similar_info, similar_name) = self + .module + .context + .get_similar_name_and_info(ident.inspect()) + .unzip(); + let err = LowerError::detailed_no_var_error( + self.cfg.input.clone(), + line!() as usize, + ident.loc(), + self.module.context.caused_by(), + ident.inspect(), + similar_name, + similar_info, + ); + self.errs.push(err); + VarInfo::ILLEGAL.clone() + } + }; ( - self.module.context.rec_get_var_info( - &ident, - AccessKind::Name, - &self.cfg.input, - &self.module.context.name, - )?, + res, self.module .context - .get_singular_ctx_by_ident(&ident, &self.module.context.name) + .get_singular_ctx_by_ident(&ident, &self.module.context) .ok() .map(|ctx| ctx.name.clone()), ) }; self.inc_ref(&vi, &ident.name); - let ident = hir::Identifier::new(ident.dot, ident.name, __name__, vi); + let ident = hir::Identifier::new(ident, __name__, vi); Ok(ident) } @@ -700,7 +752,7 @@ impl ASTLowerer { let t = self .module .context - .get_binop_t(&bin.op, &args, &self.cfg.input, &self.module.context.name) + .get_binop_t(&bin.op, &args, &self.cfg.input, &self.module.context) .unwrap_or_else(|errs| { self.errs.extend(errs); VarInfo::ILLEGAL.clone() @@ -724,7 +776,7 @@ impl ASTLowerer { let t = self .module .context - .get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.module.context.name) + .get_unaryop_t(&unary.op, &args, &self.cfg.input, &self.module.context) .unwrap_or_else(|errs| { self.errs.extend(errs); VarInfo::ILLEGAL.clone() @@ -824,7 +876,7 @@ impl ASTLowerer { &hir_args.pos_args, &hir_args.kw_args, &self.cfg.input, - &self.module.context.name, + &self.module.context, ) { Ok(vi) => vi, Err((vi, es)) => { @@ -835,12 +887,7 @@ impl ASTLowerer { }; let attr_name = if let Some(attr_name) = call.attr_name { self.inc_ref(&vi, &attr_name.name); - Some(hir::Identifier::new( - attr_name.dot, - attr_name.name, - None, - vi, - )) + Some(hir::Identifier::new(attr_name, None, vi)) } else { *obj.ref_mut_t() = vi.t; None @@ -904,17 +951,17 @@ impl ASTLowerer { let args = self.lower_record(pack.args)?; let args = vec![hir::PosArg::new(hir::Expr::Record(args))]; let attr_name = ast::Identifier::new( - Some(Token::new( + VisModifierSpec::Public(Token::new( TokenKind::Dot, Str::ever("."), - pack.connector.lineno, - pack.connector.col_begin, + pack.connector.ln_begin().unwrap(), + pack.connector.col_begin().unwrap(), )), ast::VarName::new(Token::new( TokenKind::Symbol, Str::ever("new"), - pack.connector.lineno, - pack.connector.col_begin, + pack.connector.ln_begin().unwrap(), + pack.connector.col_begin().unwrap(), )), ); let vi = match self.module.context.get_call_t( @@ -923,7 +970,7 @@ impl ASTLowerer { &args, &[], &self.cfg.input, - &self.module.context.name, + &self.module.context, ) { Ok(vi) => vi, Err((vi, errs)) => { @@ -932,7 +979,7 @@ impl ASTLowerer { } }; let args = hir::Args::pos_only(args, None); - let attr_name = hir::Identifier::new(attr_name.dot, attr_name.name, None, vi); + let attr_name = hir::Identifier::new(attr_name, None, vi); Ok(hir::Call::new(class, Some(attr_name), args)) } @@ -1209,7 +1256,10 @@ impl ASTLowerer { )); } let kind = ContextKind::from(def.def_kind()); - let vis = def.sig.vis(); + let vis = self + .module + .context + .instantiate_vis_modifier(def.sig.vis())?; let res = match def.sig { ast::Signature::Subr(sig) => { let tv_cache = self @@ -1263,7 +1313,7 @@ impl ASTLowerer { let ident = match &sig.pat { ast::VarPattern::Ident(ident) => ident.clone(), ast::VarPattern::Discard(token) => { - ast::Identifier::new(None, VarName::new(token.clone())) + ast::Identifier::private_from_token(token.clone()) } _ => unreachable!(), }; @@ -1287,7 +1337,7 @@ impl ASTLowerer { body.id, None, )?; - let ident = hir::Identifier::new(ident.dot, ident.name, None, vi); + let ident = hir::Identifier::new(ident, None, vi); let sig = hir::VarSignature::new(ident, sig.t_spec); let body = hir::DefBody::new(body.op, block, body.id); Ok(hir::Def::new(hir::Signature::Var(sig), body)) @@ -1358,7 +1408,7 @@ impl ASTLowerer { ); self.warns.push(warn); } - let ident = hir::Identifier::new(sig.ident.dot, sig.ident.name, None, vi); + let ident = hir::Identifier::new(sig.ident, None, vi); let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec); let body = hir::DefBody::new(body.op, block, body.id); @@ -1371,7 +1421,7 @@ impl ASTLowerer { &Type::Failure, )?; self.errs.extend(errs); - let ident = hir::Identifier::new(sig.ident.dot, sig.ident.name, None, vi); + let ident = hir::Identifier::new(sig.ident, None, vi); let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec); let block = @@ -1396,7 +1446,7 @@ impl ASTLowerer { .unwrap() .fake_subr_assign(&sig.ident, &sig.decorators, Type::Failure)?; let block = self.lower_block(body.block)?; - let ident = hir::Identifier::bare(sig.ident.dot, sig.ident.name); + let ident = hir::Identifier::bare(sig.ident); let sig = hir::SubrSignature::new(ident, sig.bounds, params, sig.return_t_spec); let body = hir::DefBody::new(body.op, block, body.id); Ok(hir::Def::new(hir::Signature::Subr(sig), body)) @@ -1439,12 +1489,12 @@ impl ASTLowerer { let kind = ContextKind::MethodDefs(impl_trait.as_ref().map(|(t, _)| t.clone())); self.module .context - .grow(&class.local_name(), kind, hir_def.sig.vis(), None); + .grow(&class.local_name(), kind, hir_def.sig.vis().clone(), None); for attr in methods.attrs.iter_mut() { match attr { ast::ClassAttr::Def(def) => { - if methods.vis.is(TokenKind::Dot) { - def.sig.ident_mut().unwrap().dot = Some(Token::new( + if methods.vis.is_public() { + def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(Token::new( TokenKind::Dot, ".", def.sig.ln_begin().unwrap_or(0), @@ -1641,14 +1691,17 @@ impl ASTLowerer { let mut hir_methods = hir::Block::empty(); for mut methods in class_def.methods_list.into_iter() { let kind = ContextKind::PatchMethodDefs(base_t.clone()); - self.module - .context - .grow(hir_def.sig.ident().inspect(), kind, hir_def.sig.vis(), None); + self.module.context.grow( + hir_def.sig.ident().inspect(), + kind, + hir_def.sig.vis().clone(), + None, + ); for attr in methods.attrs.iter_mut() { match attr { ast::ClassAttr::Def(def) => { - if methods.vis.is(TokenKind::Dot) { - def.sig.ident_mut().unwrap().dot = Some(Token::new( + if methods.vis.is_public() { + def.sig.ident_mut().unwrap().vis = VisModifierSpec::Public(Token::new( TokenKind::Dot, ".", def.sig.ln_begin().unwrap(), @@ -2037,7 +2090,7 @@ impl ASTLowerer { let ctx = self .module .context - .get_singular_ctx_by_hir_expr(&expr, &self.module.context.name)?; + .get_singular_ctx_by_hir_expr(&expr, &self.module.context)?; // REVIEW: need to use subtype_of? if ctx.super_traits.iter().all(|trait_| trait_ != &spec_t) && ctx.super_classes.iter().all(|class| class != &spec_t) @@ -2089,14 +2142,30 @@ impl ASTLowerer { &ident, AccessKind::Name, &self.cfg.input, - &self.module.context.name, + &self.module.context, ) - .or_else(|_e| { + .none_or_else(|| { self.module.context.rec_get_var_info( &ident, AccessKind::Name, &self.cfg.input, - &self.module.context.name, + &self.module.context, + ) + }) + .none_or_result(|| { + let (similar_info, similar_name) = self + .module + .context + .get_similar_name_and_info(ident.inspect()) + .unzip(); + LowerError::detailed_no_var_error( + self.cfg.input.clone(), + line!() as usize, + ident.loc(), + self.module.context.caused_by(), + ident.inspect(), + similar_name, + similar_info, ) })?; if is_instance_ascription { @@ -2119,10 +2188,10 @@ impl ASTLowerer { let qual_name = self .module .context - .get_singular_ctx_by_ident(&ident, &self.module.context.name) + .get_singular_ctx_by_ident(&ident, &self.module.context) .ok() .map(|ctx| ctx.name.clone()); - let ident = hir::Identifier::new(ident.dot, ident.name, qual_name, ident_vi); + let ident = hir::Identifier::new(ident, qual_name, ident_vi); let expr = hir::Expr::Accessor(hir::Accessor::Ident(ident)); let t_spec = self.lower_type_spec_with_op(tasc.t_spec, spec_t)?; Ok(expr.type_asc(t_spec)) diff --git a/crates/erg_compiler/ownercheck.rs b/crates/erg_compiler/ownercheck.rs index 96ef68445..4313c89ef 100644 --- a/crates/erg_compiler/ownercheck.rs +++ b/crates/erg_compiler/ownercheck.rs @@ -6,13 +6,11 @@ use erg_common::error::Location; use erg_common::set::Set; use erg_common::style::colors::DEBUG_MAIN; use erg_common::traits::{Locational, Stream}; -use erg_common::vis::Visibility; use erg_common::Str; use erg_common::{impl_display_from_debug, log}; use erg_parser::ast::{ParamPattern, VarName}; -use Visibility::*; -use crate::ty::{HasType, Ownership}; +use crate::ty::{HasType, Ownership, Visibility}; use crate::error::{OwnershipError, OwnershipErrors}; use crate::hir::{self, Accessor, Array, Block, Def, Expr, Identifier, Signature, Tuple, HIR}; @@ -39,7 +37,7 @@ impl_display_from_debug!(LocalVars); #[derive(Debug)] pub struct OwnershipChecker { cfg: ErgConfig, - path_stack: Vec<(Str, Visibility)>, + path_stack: Vec, dict: Dict, errs: OwnershipErrors, } @@ -55,15 +53,13 @@ impl OwnershipChecker { } fn full_path(&self) -> String { - self.path_stack - .iter() - .fold(String::new(), |acc, (path, vis)| { - if vis.is_public() { - acc + "." + &path[..] - } else { - acc + "::" + &path[..] - } - }) + self.path_stack.iter().fold(String::new(), |acc, vis| { + if vis.is_public() { + acc + "." + &vis.def_namespace[..] + } else { + acc + "::" + &vis.def_namespace[..] + } + }) } // moveされた後の変数が使用されていないかチェックする @@ -71,7 +67,7 @@ impl OwnershipChecker { pub fn check(&mut self, hir: HIR) -> Result { log!(info "the ownership checking process has started.{RESET}"); if self.full_path() != ("::".to_string() + &hir.name[..]) { - self.path_stack.push((hir.name.clone(), Private)); + self.path_stack.push(Visibility::private(hir.name.clone())); self.dict .insert(Str::from(self.full_path()), LocalVars::default()); } @@ -106,7 +102,8 @@ impl OwnershipChecker { Signature::Var(var) => var.inspect().clone(), Signature::Subr(subr) => subr.ident.inspect().clone(), }; - self.path_stack.push((name, def.sig.vis())); + self.path_stack + .push(Visibility::new(def.sig.vis().clone(), name)); self.dict .insert(Str::from(self.full_path()), LocalVars::default()); if let Signature::Subr(subr) = &def.sig { @@ -247,7 +244,8 @@ impl OwnershipChecker { }, // TODO: capturing Expr::Lambda(lambda) => { - let name_and_vis = (Str::from(format!("", lambda.id)), Private); + let name_and_vis = + Visibility::private(Str::from(format!("", lambda.id))); self.path_stack.push(name_and_vis); self.dict .insert(Str::from(self.full_path()), LocalVars::default()); @@ -289,11 +287,11 @@ impl OwnershipChecker { fn nth_outer_scope(&mut self, n: usize) -> &mut LocalVars { let path = self.path_stack.iter().take(self.path_stack.len() - n).fold( String::new(), - |acc, (path, vis)| { + |acc, vis| { if vis.is_public() { - acc + "." + &path[..] + acc + "." + &vis.def_namespace[..] } else { - acc + "::" + &path[..] + acc + "::" + &vis.def_namespace[..] } }, ); diff --git a/crates/erg_compiler/reorder.rs b/crates/erg_compiler/reorder.rs index 09c7aa62c..e24ff9b89 100644 --- a/crates/erg_compiler/reorder.rs +++ b/crates/erg_compiler/reorder.rs @@ -123,7 +123,6 @@ impl Reorderer { /// ``` fn flatten_method_decls(&mut self, new: &mut Vec, methods: Methods) { let class = methods.class_as_expr.as_ref(); - let vis = methods.vis(); for method in methods.attrs.into_iter() { match method { ClassAttr::Decl(decl) => { @@ -138,11 +137,7 @@ impl Reorderer { )); continue; }; - let attr = if vis.is_public() { - Identifier::new(Some(methods.vis.clone()), ident.name) - } else { - Identifier::new(None, ident.name) - }; + let attr = Identifier::new(methods.vis.clone(), ident.name); let expr = class.clone().attr_expr(attr); let decl = TypeAscription::new(expr, decl.t_spec); new.push(Expr::TypeAscription(decl)); diff --git a/crates/erg_compiler/transpile.rs b/crates/erg_compiler/transpile.rs index ce31a3ccc..156ba22a2 100644 --- a/crates/erg_compiler/transpile.rs +++ b/crates/erg_compiler/transpile.rs @@ -787,9 +787,9 @@ impl ScriptGenerator { if let Some(py_name) = ident.vi.py_name { return demangle(&py_name); } - let name = ident.name.into_token().content.to_string(); + let name = ident.inspect().to_string(); let name = replace_non_symbolic(name); - if ident.dot.is_some() { + if ident.vis().is_public() { name } else { format!("{name}__") @@ -941,7 +941,7 @@ impl ScriptGenerator { demangle(&patch_def.sig.ident().to_string_notype()), demangle(&def.sig.ident().to_string_notype()), ); - def.sig.ident_mut().name = VarName::from_str(Str::from(name)); + def.sig.ident_mut().raw.name = VarName::from_str(Str::from(name)); code += &" ".repeat(self.level); code += &self.transpile_def(def); code.push('\n'); diff --git a/crates/erg_compiler/ty/deserialize.rs b/crates/erg_compiler/ty/deserialize.rs index aa64648f9..ca296c995 100644 --- a/crates/erg_compiler/ty/deserialize.rs +++ b/crates/erg_compiler/ty/deserialize.rs @@ -2,7 +2,7 @@ use std::string::FromUtf8Error; use erg_common::cache::CacheSet; -use erg_common::config::{ErgConfig, Input}; +use erg_common::config::ErgConfig; use erg_common::dict::Dict; use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage}; use erg_common::python_util::PythonVersion; @@ -111,11 +111,11 @@ impl Deserializer { } pub fn run(cfg: ErgConfig) -> ExitStatus { - let Input::File(filename) = cfg.input else { + let Some(filename) = cfg.input.path() else { eprintln!("{:?} is not a filename", cfg.input); return ExitStatus::ERR1; }; - match CodeObj::from_pyc(&filename) { + match CodeObj::from_pyc(filename) { Ok(codeobj) => { println!("{}", codeobj.code_info(None)); ExitStatus::OK diff --git a/crates/erg_compiler/ty/mod.rs b/crates/erg_compiler/ty/mod.rs index 3a28f992f..97bf40480 100644 --- a/crates/erg_compiler/ty/mod.rs +++ b/crates/erg_compiler/ty/mod.rs @@ -11,6 +11,7 @@ pub mod free; pub mod predicate; pub mod typaram; pub mod value; +pub mod vis; use std::fmt; use std::ops::{BitAnd, BitOr, Deref, Not, Range, RangeInclusive}; @@ -22,7 +23,6 @@ use erg_common::fresh::fresh_varname; use erg_common::log; use erg_common::set::Set; use erg_common::traits::{LimitedDisplay, StructuralEq}; -use erg_common::vis::Field; use erg_common::{enum_unwrap, fmt_option, ref_addr_eq, set, Str}; use erg_parser::token::TokenKind; @@ -35,6 +35,7 @@ use typaram::{IntervalOp, TyParam}; use value::value_set::*; use value::ValueObj; use value::ValueObj::{Inf, NegInf}; +pub use vis::*; /// cloneのコストがあるためなるべく.ref_tを使うようにすること /// いくつかの構造体は直接Typeを保持していないので、その場合は.tを使う @@ -534,9 +535,6 @@ impl LimitedDisplay for RefinementType { write!(f, "{rhs}, ")?; } write!(f, "}}")?; - if cfg!(feature = "debug") { - write!(f, "(<: {})", self.t)?; - } Ok(()) } else { write!(f, "{{{}: ", self.var)?; diff --git a/crates/erg_compiler/ty/typaram.rs b/crates/erg_compiler/ty/typaram.rs index f65640296..a3a6bdacf 100644 --- a/crates/erg_compiler/ty/typaram.rs +++ b/crates/erg_compiler/ty/typaram.rs @@ -7,7 +7,6 @@ use erg_common::dict::Dict; use erg_common::set; use erg_common::set::Set; use erg_common::traits::{LimitedDisplay, StructuralEq}; -use erg_common::vis::Field; use erg_common::Str; use erg_common::{dict, log}; @@ -19,7 +18,7 @@ use super::free::{ }; use super::value::ValueObj; use super::Type; -use super::{ConstSubr, ParamTy, UserConstSubr}; +use super::{ConstSubr, Field, ParamTy, UserConstSubr}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[repr(u8)] diff --git a/crates/erg_compiler/ty/value.rs b/crates/erg_compiler/ty/value.rs index eb2b5391d..b369e5c45 100644 --- a/crates/erg_compiler/ty/value.rs +++ b/crates/erg_compiler/ty/value.rs @@ -16,7 +16,6 @@ use erg_common::python_util::PythonVersion; use erg_common::serialize::*; use erg_common::set::Set; use erg_common::shared::Shared; -use erg_common::vis::Field; use erg_common::{dict, fmt_iter, impl_display_from_debug, log, switch_lang}; use erg_common::{RcArray, Str}; use erg_parser::ast::{ConstArgs, ConstExpr}; @@ -28,7 +27,7 @@ use self::value_set::inner_class; use super::codeobj::CodeObj; use super::constructors::{array_t, dict_t, mono, poly, refinement, set_t, tuple_t}; use super::typaram::TyParam; -use super::{ConstSubr, HasType, Predicate, Type}; +use super::{ConstSubr, Field, HasType, Predicate, Type}; pub struct EvalValueError(pub Box); @@ -1311,11 +1310,11 @@ impl ValueObj { } Self::Subr(subr) => subr.as_type().map(TypeObj::Builtin), Self::Array(elems) | Self::Tuple(elems) => { - erg_common::log!(err "as_type({})", erg_common::fmt_vec(elems)); + log!(err "as_type({})", erg_common::fmt_vec(elems)); None } Self::Dict(elems) => { - erg_common::log!(err "as_type({elems})"); + log!(err "as_type({elems})"); None } _other => None, diff --git a/crates/erg_compiler/ty/vis.rs b/crates/erg_compiler/ty/vis.rs new file mode 100644 index 000000000..812bac0f5 --- /dev/null +++ b/crates/erg_compiler/ty/vis.rs @@ -0,0 +1,233 @@ +use std::borrow::Borrow; +use std::fmt; + +#[allow(unused_imports)] +use erg_common::log; +use erg_common::set::Set; +use erg_common::{switch_lang, Str}; + +use erg_parser::ast::AccessModifier; + +use crate::context::Context; +use crate::ty::Type; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum VisibilityModifier { + Public, + Private, + Restricted(Set), + SubtypeRestricted(Type), +} + +impl fmt::Display for VisibilityModifier { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Private => write!(f, "::"), + Self::Public => write!(f, "."), + Self::Restricted(namespaces) => write!(f, "::[{namespaces}]"), + Self::SubtypeRestricted(typ) => write!(f, "::[<: {typ}]"), + } + } +} + +impl VisibilityModifier { + pub const fn is_public(&self) -> bool { + matches!(self, Self::Public) + } + pub const fn is_private(&self) -> bool { + matches!(self, Self::Private) + } + + pub const fn display_as_accessor(&self) -> &'static str { + match self { + Self::Public => ".", + Self::Private | Self::Restricted(_) | Self::SubtypeRestricted(_) => "::", + } + } + + pub fn display(&self) -> String { + match self { + Self::Private => switch_lang!( + "japanese" => "非公開", + "simplified_chinese" => "私有", + "traditional_chinese" => "私有", + "english" => "private", + ) + .into(), + Self::Public => switch_lang!( + "japanese" => "公開", + "simplified_chinese" => "公开", + "traditional_chinese" => "公開", + "english" => "public", + ) + .into(), + Self::Restricted(namespaces) => switch_lang!( + "japanese" => format!("制限付き公開({namespaces}でのみ公開)"), + "simplified_chinese" => format!("受限公开({namespaces}中可见)"), + "traditional_chinese" => format!("受限公開({namespaces}中可見)"), + "english" => format!("restricted public ({namespaces} only)"), + ), + Self::SubtypeRestricted(typ) => switch_lang!( + "japanese" => format!("制限付き公開({typ}の部分型でのみ公開)"), + "simplified_chinese" => format!("受限公开({typ}的子类型中可见)"), + "traditional_chinese" => format!("受限公開({typ}的子類型中可見)"), + "english" => format!("restricted public (subtypes of {typ} only)"), + ), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Visibility { + pub modifier: VisibilityModifier, + pub def_namespace: Str, +} + +impl Visibility { + pub const DUMMY_PRIVATE: Self = Self { + modifier: VisibilityModifier::Private, + def_namespace: Str::ever(""), + }; + pub const DUMMY_PUBLIC: Self = Self { + modifier: VisibilityModifier::Public, + def_namespace: Str::ever(""), + }; + pub const BUILTIN_PRIVATE: Self = Self { + modifier: VisibilityModifier::Private, + def_namespace: Str::ever(""), + }; + pub const BUILTIN_PUBLIC: Self = Self { + modifier: VisibilityModifier::Public, + def_namespace: Str::ever(""), + }; + + pub const fn new(modifier: VisibilityModifier, def_namespace: Str) -> Self { + Self { + modifier, + def_namespace, + } + } + + pub fn private>(namespace: S) -> Self { + Self { + modifier: VisibilityModifier::Private, + def_namespace: namespace.into(), + } + } + + pub const fn is_public(&self) -> bool { + self.modifier.is_public() + } + pub const fn is_private(&self) -> bool { + self.modifier.is_private() + } + + pub fn compatible(&self, access: &AccessModifier, namespace: &Context) -> bool { + match (&self.modifier, access) { + (_, AccessModifier::Force) => true, + (VisibilityModifier::Public, AccessModifier::Auto | AccessModifier::Public) => true, + // compatible example: + // def_namespace: ::C + // namespace: ::C::f + (VisibilityModifier::Private, AccessModifier::Auto | AccessModifier::Private) => { + &self.def_namespace[..] == "" + || namespace.name.starts_with(&self.def_namespace[..]) + } + ( + VisibilityModifier::Restricted(namespaces), + AccessModifier::Auto | AccessModifier::Private, + ) => { + namespace.name.starts_with(&self.def_namespace[..]) + || namespaces.contains(&namespace.name) + } + ( + VisibilityModifier::SubtypeRestricted(typ), + AccessModifier::Auto | AccessModifier::Private, + ) => { + namespace.name.starts_with(&self.def_namespace[..]) || { + let Some(space_t) = namespace.rec_get_self_t() else { + return false; + }; + namespace.subtype_of(&space_t, typ) + } + } + _ => false, + } + } +} + +/// same structure as `Identifier`, but only for Record fields. +#[derive(Debug, Clone, Eq)] +pub struct Field { + pub vis: VisibilityModifier, + pub symbol: Str, +} + +impl PartialEq for Field { + fn eq(&self, other: &Self) -> bool { + self.symbol == other.symbol + } +} + +impl std::hash::Hash for Field { + fn hash(&self, state: &mut H) { + self.symbol.hash(state); + } +} + +impl fmt::Display for Field { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}{}", self.vis, self.symbol) + } +} + +impl Borrow for Field { + #[inline] + fn borrow(&self) -> &str { + &self.symbol[..] + } +} + +impl Borrow for Field { + #[inline] + fn borrow(&self) -> &Str { + &self.symbol + } +} + +impl Field { + pub const fn new(vis: VisibilityModifier, symbol: Str) -> Self { + Field { vis, symbol } + } + + pub fn private(symbol: Str) -> Self { + Field::new(VisibilityModifier::Private, symbol) + } + + pub fn public(symbol: Str) -> Self { + Field::new(VisibilityModifier::Public, symbol) + } + + pub fn is_const(&self) -> bool { + self.symbol.starts_with(char::is_uppercase) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use erg_common::dict; + + #[test] + fn test_std_key() { + let dict = dict! {Str::ever("a") => 1, Str::rc("b") => 2}; + assert_eq!(dict.get("a"), Some(&1)); + assert_eq!(dict.get("b"), Some(&2)); + assert_eq!(dict.get(&Str::ever("b")), Some(&2)); + assert_eq!(dict.get(&Str::rc("b")), Some(&2)); + + let dict = dict! {Field::private(Str::ever("a")) => 1, Field::public(Str::ever("b")) => 2}; + assert_eq!(dict.get("a"), Some(&1)); + assert_eq!(dict.get("b"), Some(&2)); + } +} diff --git a/crates/erg_compiler/varinfo.rs b/crates/erg_compiler/varinfo.rs index 5b60f79dd..66a0803bc 100644 --- a/crates/erg_compiler/varinfo.rs +++ b/crates/erg_compiler/varinfo.rs @@ -3,14 +3,12 @@ use std::path::PathBuf; use erg_common::error::Location; use erg_common::set::Set; -use erg_common::vis::{Field, Visibility}; use erg_common::Str; -use Visibility::*; use erg_parser::ast::DefId; use crate::context::DefaultInfo; -use crate::ty::{HasType, Type}; +use crate::ty::{Field, HasType, Type, Visibility}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[repr(u8)] @@ -200,18 +198,31 @@ impl HasType for VarInfo { impl Default for VarInfo { fn default() -> Self { - Self::const_default() + Self::const_default_private() } } impl VarInfo { - pub const ILLEGAL: &'static Self = &Self::const_default(); + pub const ILLEGAL: &'static Self = &Self::const_default_private(); - pub const fn const_default() -> Self { + pub const fn const_default_private() -> Self { Self::new( Type::Failure, Immutable, - Private, + Visibility::DUMMY_PRIVATE, + VarKind::DoesNotExist, + None, + None, + None, + AbsLocation::unknown(), + ) + } + + pub const fn const_default_public() -> Self { + Self::new( + Type::Failure, + Immutable, + Visibility::DUMMY_PUBLIC, VarKind::DoesNotExist, None, None, @@ -250,16 +261,25 @@ impl VarInfo { } } - pub fn nd_parameter(t: Type, def_loc: AbsLocation) -> Self { + pub fn nd_parameter(t: Type, def_loc: AbsLocation, namespace: Str) -> Self { let kind = VarKind::Parameter { def_id: DefId(0), var: false, default: DefaultInfo::NonDefault, }; - Self::new(t, Immutable, Private, kind, None, None, None, def_loc) + Self::new( + t, + Immutable, + Visibility::private(namespace), + kind, + None, + None, + None, + def_loc, + ) } - pub fn instance_attr(field: Field, t: Type, impl_of: Option) -> Self { + pub fn instance_attr(field: Field, t: Type, impl_of: Option, namespace: Str) -> Self { let muty = if field.is_const() { Mutability::Const } else { @@ -269,7 +289,7 @@ impl VarInfo { Self::new( t, muty, - field.vis, + Visibility::new(field.vis, namespace), kind, None, impl_of, diff --git a/crates/erg_parser/ast.rs b/crates/erg_parser/ast.rs index 3e27db7e8..cc016f6d0 100644 --- a/crates/erg_parser/ast.rs +++ b/crates/erg_parser/ast.rs @@ -7,7 +7,6 @@ use erg_common::error::Location; use erg_common::set::Set as HashSet; // use erg_common::dict::Dict as HashMap; use erg_common::traits::{Locational, NestedDisplay, Stream}; -use erg_common::vis::{Field, Visibility}; use erg_common::{ fmt_option, fmt_vec, impl_display_for_enum, impl_display_for_single_struct, impl_display_from_nested, impl_displayable_stream_for_wrapper, impl_from_trait_for_enum, @@ -493,11 +492,31 @@ impl_locational_for_enum!(Accessor; Ident, Attr, TupleAttr, Subscr, TypeApp); impl Accessor { pub const fn local(symbol: Token) -> Self { - Self::Ident(Identifier::new(None, VarName::new(symbol))) + Self::Ident(Identifier::new( + VisModifierSpec::Private, + VarName::new(symbol), + )) } pub const fn public(dot: Token, symbol: Token) -> Self { - Self::Ident(Identifier::new(Some(dot), VarName::new(symbol))) + Self::Ident(Identifier::new( + VisModifierSpec::Public(dot), + VarName::new(symbol), + )) + } + + pub const fn explicit_local(dcolon: Token, symbol: Token) -> Self { + Self::Ident(Identifier::new( + VisModifierSpec::ExplicitPrivate(dcolon), + VarName::new(symbol), + )) + } + + pub const fn restricted(rest: VisRestriction, symbol: Token) -> Self { + Self::Ident(Identifier::new( + VisModifierSpec::Restricted(rest), + VarName::new(symbol), + )) } pub fn attr(obj: Expr, ident: Identifier) -> Self { @@ -1201,7 +1220,7 @@ impl Call { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct DataPack { pub class: Box, - pub connector: Token, + pub connector: VisModifierSpec, pub args: Record, } @@ -1220,7 +1239,7 @@ impl Locational for DataPack { } impl DataPack { - pub fn new(class: Expr, connector: Token, args: Record) -> Self { + pub fn new(class: Expr, connector: VisModifierSpec, args: Record) -> Self { Self { class: Box::new(class), connector, @@ -1392,7 +1411,10 @@ impl_locational_for_enum!(ConstAccessor; Local, SelfDot, Attr, TupleAttr, Subscr impl ConstAccessor { pub const fn local(symbol: Token) -> Self { - Self::Local(ConstIdentifier::new(None, VarName::new(symbol))) + Self::Local(ConstIdentifier::new( + VisModifierSpec::Private, + VarName::new(symbol), + )) } pub fn attr(obj: ConstExpr, name: ConstIdentifier) -> Self { @@ -2655,18 +2677,108 @@ impl VarName { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Namespaces(Vec); + +impl_displayable_stream_for_wrapper!(Namespaces, Accessor); + +impl NestedDisplay for Namespaces { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + for (i, ns) in self.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + write!(f, "{ns}")?; + } + Ok(()) + } +} + +impl Locational for Namespaces { + fn loc(&self) -> Location { + Location::concat(self.first().unwrap(), self.last().unwrap()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum VisRestriction { + Namespaces(Namespaces), + SubtypeOf(Box), +} + +impl_locational_for_enum!(VisRestriction; Namespaces, SubtypeOf); +impl_display_from_nested!(VisRestriction); + +impl NestedDisplay for VisRestriction { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + match self { + Self::Namespaces(ns) => write!(f, "{ns}"), + Self::SubtypeOf(ty) => write!(f, "<: {ty}"), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum VisModifierSpec { + Private, + Auto, + Public(Token), + ExplicitPrivate(Token), + Restricted(VisRestriction), +} + +impl NestedDisplay for VisModifierSpec { + fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { + match self { + Self::Private => Ok(()), + Self::Auto => write!(f, ":auto:"), + Self::Public(_token) => write!(f, "."), + Self::ExplicitPrivate(_token) => write!(f, "::"), + Self::Restricted(rest) => write!(f, "::[{rest}]"), + } + } +} + +impl_display_from_nested!(VisModifierSpec); + +impl Locational for VisModifierSpec { + fn loc(&self) -> Location { + match self { + Self::Private | Self::Auto => Location::Unknown, + Self::Public(token) => token.loc(), + Self::ExplicitPrivate(token) => token.loc(), + Self::Restricted(rest) => rest.loc(), + } + } +} + +impl VisModifierSpec { + pub const fn is_public(&self) -> bool { + matches!(self, Self::Public(_)) + } + + pub const fn is_private(&self) -> bool { + matches!(self, Self::Private | Self::ExplicitPrivate(_)) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum AccessModifier { + Private, // `::` + Public, // `.` + Auto, // record unpacking + Force, // can access any identifiers +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Identifier { - pub dot: Option, + pub vis: VisModifierSpec, pub name: VarName, } impl NestedDisplay for Identifier { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, _level: usize) -> fmt::Result { - match &self.dot { - Some(_dot) => write!(f, ".{}", self.name), - None => write!(f, "::{}", self.name), - } + write!(f, "{}{}", self.vis, self.name) } } @@ -2674,24 +2786,16 @@ impl_display_from_nested!(Identifier); impl Locational for Identifier { fn loc(&self) -> Location { - if let Some(dot) = &self.dot { - if dot.loc().is_unknown() { - self.name.loc() - } else { - Location::concat(dot, &self.name) + match &self.vis { + VisModifierSpec::Private | VisModifierSpec::Auto => self.name.loc(), + VisModifierSpec::ExplicitPrivate(token) | VisModifierSpec::Public(token) => { + Location::concat(token, &self.name) } - } else { - self.name.loc() + VisModifierSpec::Restricted(args) => Location::concat(args, &self.name), } } } -impl From<&Identifier> for Field { - fn from(ident: &Identifier) -> Self { - Self::new(ident.vis(), ident.inspect().clone()) - } -} - impl From for Expr { fn from(ident: Identifier) -> Self { Self::Accessor(Accessor::Ident(ident)) @@ -2699,34 +2803,52 @@ impl From for Expr { } impl Identifier { - pub const fn new(dot: Option, name: VarName) -> Self { - Self { dot, name } + pub const fn new(vis: VisModifierSpec, name: VarName) -> Self { + Self { vis, name } } pub fn static_public(name: &'static str) -> Self { Self::new( - Some(Token::from_str(TokenKind::Dot, ".")), + VisModifierSpec::Public(Token::from_str(TokenKind::Dot, ".")), VarName::from_static(name), ) } pub fn public(name: Str) -> Self { Self::new( - Some(Token::from_str(TokenKind::Dot, ".")), + VisModifierSpec::Public(Token::from_str(TokenKind::Dot, ".")), VarName::from_str(name), ) } pub fn private(name: Str) -> Self { - Self::new(None, VarName::from_str(name)) + Self::new(VisModifierSpec::Private, VarName::from_str(name)) + } + + pub fn private_from_token(symbol: Token) -> Self { + Self::new(VisModifierSpec::Private, VarName::new(symbol)) + } + + pub fn private_from_varname(name: VarName) -> Self { + Self::new(VisModifierSpec::Private, name) } pub fn private_with_line(name: Str, line: u32) -> Self { - Self::new(None, VarName::from_str_and_line(name, line)) + Self::new( + VisModifierSpec::Private, + VarName::from_str_and_line(name, line), + ) } pub fn public_with_line(dot: Token, name: Str, line: u32) -> Self { - Self::new(Some(dot), VarName::from_str_and_line(name, line)) + Self::new( + VisModifierSpec::Public(dot), + VarName::from_str_and_line(name, line), + ) + } + + pub fn public_from_token(dot: Token, symbol: Token) -> Self { + Self::new(VisModifierSpec::Public(dot), VarName::new(symbol)) } pub fn is_const(&self) -> bool { @@ -2737,10 +2859,13 @@ impl Identifier { self.name.is_raw() } - pub const fn vis(&self) -> Visibility { - match &self.dot { - Some(_) => Visibility::Public, - None => Visibility::Private, + pub fn acc_kind(&self) -> AccessModifier { + match &self.vis { + VisModifierSpec::Auto => AccessModifier::Auto, + VisModifierSpec::Public(_) => AccessModifier::Public, + VisModifierSpec::ExplicitPrivate(_) + | VisModifierSpec::Restricted(_) + | VisModifierSpec::Private => AccessModifier::Private, } } @@ -2983,11 +3108,11 @@ impl VarPattern { } } - pub const fn vis(&self) -> Visibility { + pub fn vis(&self) -> &VisModifierSpec { match self { - Self::Ident(ident) => ident.vis(), + Self::Ident(ident) => &ident.vis, // TODO: `[.x, .y]`? - _ => Visibility::Private, + _ => &VisModifierSpec::Private, } } @@ -3036,7 +3161,7 @@ impl VarSignature { self.pat.is_const() } - pub const fn vis(&self) -> Visibility { + pub fn vis(&self) -> &VisModifierSpec { self.pat.vis() } @@ -3493,8 +3618,8 @@ impl SubrSignature { self.ident.is_const() } - pub const fn vis(&self) -> Visibility { - self.ident.vis() + pub fn vis(&self) -> &VisModifierSpec { + &self.ident.vis } } @@ -3693,7 +3818,7 @@ impl Signature { matches!(self, Self::Subr(_)) } - pub const fn vis(&self) -> Visibility { + pub fn vis(&self) -> &VisModifierSpec { match self { Self::Var(var) => var.vis(), Self::Subr(subr) => subr.vis(), @@ -3893,13 +4018,13 @@ impl ReDef { pub struct Methods { pub class: TypeSpec, pub class_as_expr: Box, - pub vis: Token, // `.` or `::` + pub vis: VisModifierSpec, // `.` or `::` pub attrs: ClassAttrs, } impl NestedDisplay for Methods { fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result { - writeln!(f, "{}{}", self.class, self.vis.content)?; + writeln!(f, "{}{}", self.class, self.vis)?; self.attrs.fmt_nest(f, level + 1) } } @@ -3908,7 +4033,12 @@ impl_display_from_nested!(Methods); impl_locational!(Methods, class, attrs); impl Methods { - pub fn new(class: TypeSpec, class_as_expr: Expr, vis: Token, attrs: ClassAttrs) -> Self { + pub fn new( + class: TypeSpec, + class_as_expr: Expr, + vis: VisModifierSpec, + attrs: ClassAttrs, + ) -> Self { Self { class, class_as_expr: Box::new(class_as_expr), @@ -3916,14 +4046,6 @@ impl Methods { attrs, } } - - pub fn vis(&self) -> Visibility { - if self.vis.is(TokenKind::Dot) { - Visibility::Public - } else { - Visibility::Private - } - } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] diff --git a/crates/erg_parser/desugar.rs b/crates/erg_parser/desugar.rs index 350ee28a6..b4e68f41c 100644 --- a/crates/erg_parser/desugar.rs +++ b/crates/erg_parser/desugar.rs @@ -16,7 +16,7 @@ use crate::ast::{ ParamPattern, ParamRecordAttr, Params, PatchDef, PosArg, ReDef, Record, RecordAttrOrIdent, RecordAttrs, Set as astSet, SetWithLength, Signature, SubrSignature, Tuple, TupleTypeSpec, TypeAppArgs, TypeAppArgsKind, TypeBoundSpecs, TypeSpec, TypeSpecWithOp, UnaryOp, VarName, - VarPattern, VarRecordAttr, VarSignature, + VarPattern, VarRecordAttr, VarSignature, VisModifierSpec, }; use crate::token::{Token, TokenKind, COLON, DOT}; @@ -636,7 +636,10 @@ impl Desugarer { r_brace, ) } - BufIndex::Record(attr) => obj.attr(attr.clone()), + BufIndex::Record(attr) => { + let attr = Identifier::new(VisModifierSpec::Auto, attr.name.clone()); + obj.attr(attr) + } }; let id = DefId(get_hash(&(&acc, buf_name))); let block = Block::new(vec![Expr::Accessor(acc)]); @@ -1001,7 +1004,10 @@ impl Desugarer { r_brace, ) } - BufIndex::Record(attr) => obj.attr(attr.clone()), + BufIndex::Record(attr) => { + let attr = Identifier::new(VisModifierSpec::Auto, attr.name.clone()); + obj.attr(attr) + } }; let id = DefId(get_hash(&(&acc, buf_name))); let block = Block::new(vec![Expr::Accessor(acc)]); @@ -1166,7 +1172,7 @@ impl Desugarer { } */ ParamPattern::VarName(name) => { - let ident = Identifier::new(None, name.clone()); + let ident = Identifier::new(VisModifierSpec::Private, name.clone()); let v = VarSignature::new( VarPattern::Ident(ident), sig.t_spec.as_ref().map(|ts| ts.t_spec.clone()), diff --git a/crates/erg_parser/parse.rs b/crates/erg_parser/parse.rs index d0934da03..04b0aee35 100644 --- a/crates/erg_parser/parse.rs +++ b/crates/erg_parser/parse.rs @@ -6,7 +6,7 @@ use std::fmt::Debug; use std::mem; use erg_common::config::ErgConfig; -use erg_common::config::Input; +use erg_common::config::{Input, InputKind}; use erg_common::error::Location; use erg_common::set::Set as HashSet; use erg_common::str::Str; @@ -331,7 +331,7 @@ impl ParserRunner { } pub fn parse(&mut self, src: String) -> Result { - let ts = Lexer::new(Input::Str(self.cfg.input.id(), src)) + let ts = Lexer::new(Input::new(InputKind::Str(src), self.cfg.input.id())) .lex() .map_err(|errs| ParserRunnerErrors::convert(self.input(), errs))?; Parser::new(ts) @@ -560,6 +560,37 @@ impl Parser { Ok(TypeAppArgs::new(l_vbar, args, r_vbar)) } + fn try_reduce_restriction(&mut self) -> ParseResult { + debug_call_info!(self); + expect_pop!(self, LSqBr); + let rest = match self.peek_kind() { + Some(SubtypeOf) => { + self.lpop(); + let t_spec_as_expr = self + .try_reduce_expr(false, true, false, false) + .map_err(|_| self.stack_dec(fn_name!()))?; + match Parser::expr_to_type_spec(t_spec_as_expr) { + Ok(t_spec) => VisRestriction::SubtypeOf(Box::new(t_spec)), + Err(err) => { + self.errs.push(err); + debug_exit_info!(self); + return Err(()); + } + } + } + _ => { + // FIXME: reduce namespaces + let acc = self + .try_reduce_acc_lhs() + .map_err(|_| self.stack_dec(fn_name!()))?; + VisRestriction::Namespaces(Namespaces::new(vec![acc])) + } + }; + expect_pop!(self, RSqBr); + debug_exit_info!(self); + Ok(rest) + } + fn try_reduce_acc_lhs(&mut self) -> ParseResult { debug_call_info!(self); let acc = match self.peek_kind() { @@ -576,6 +607,19 @@ impl Parser { return Err(()); } } + Some(DblColon) => { + let dbl_colon = self.lpop(); + if let Some(LSqBr) = self.peek_kind() { + let rest = self + .try_reduce_restriction() + .map_err(|_| self.stack_dec(fn_name!()))?; + let symbol = expect_pop!(self, Symbol); + Accessor::restricted(rest, symbol) + } else { + let symbol = expect_pop!(self, Symbol); + Accessor::explicit_local(dbl_colon, symbol) + } + } _ => { let err = self.skip_and_throw_syntax_err(caused_by!()); self.errs.push(err); @@ -1000,7 +1044,11 @@ impl Parser { } } - fn try_reduce_method_defs(&mut self, class: Expr, vis: Token) -> ParseResult { + fn try_reduce_method_defs( + &mut self, + class: Expr, + vis: VisModifierSpec, + ) -> ParseResult { debug_call_info!(self); expect_pop!(self, fail_next Indent); while self.cur_is(Newline) { @@ -1205,7 +1253,7 @@ impl Parser { )); } Some(t) if t.is(DblColon) => { - let vis = self.lpop(); + let vis = VisModifierSpec::ExplicitPrivate(self.lpop()); match self.lpop() { symbol if symbol.is(Symbol) => { let Some(ExprOrOp::Expr(obj)) = stack.pop() else { @@ -1219,11 +1267,13 @@ impl Parser { .transpose() .map_err(|_| self.stack_dec(fn_name!()))? { - let ident = Identifier::new(None, VarName::new(symbol)); + let ident = + Identifier::new(VisModifierSpec::Private, VarName::new(symbol)); let call = Call::new(obj, Some(ident), args); stack.push(ExprOrOp::Expr(Expr::Call(call))); } else { - let ident = Identifier::new(None, VarName::new(symbol)); + let ident = + Identifier::new(VisModifierSpec::Private, VarName::new(symbol)); stack.push(ExprOrOp::Expr(obj.attr_expr(ident))); } } @@ -1267,7 +1317,7 @@ impl Parser { } } Some(t) if t.is(Dot) => { - let vis = self.lpop(); + let dot = self.lpop(); match self.lpop() { symbol if symbol.is(Symbol) => { let Some(ExprOrOp::Expr(obj)) = stack.pop() else { @@ -1281,15 +1331,16 @@ impl Parser { .transpose() .map_err(|_| self.stack_dec(fn_name!()))? { - let ident = Identifier::new(Some(vis), VarName::new(symbol)); + let ident = Identifier::public_from_token(dot, symbol); let call = Expr::Call(Call::new(obj, Some(ident), args)); stack.push(ExprOrOp::Expr(call)); } else { - let ident = Identifier::new(Some(vis), VarName::new(symbol)); + let ident = Identifier::public_from_token(dot, symbol); stack.push(ExprOrOp::Expr(obj.attr_expr(ident))); } } line_break if line_break.is(Newline) => { + let vis = VisModifierSpec::Public(dot); let maybe_class = enum_unwrap!(stack.pop(), Some:(ExprOrOp::Expr:(_))); let defs = self .try_reduce_method_defs(maybe_class, vis) @@ -1488,11 +1539,17 @@ impl Parser { .transpose() .map_err(|_| self.stack_dec(fn_name!()))? { - let ident = Identifier::new(Some(vis), VarName::new(symbol)); + let ident = Identifier::new( + VisModifierSpec::Public(vis), + VarName::new(symbol), + ); let call = Call::new(obj, Some(ident), args); stack.push(ExprOrOp::Expr(Expr::Call(call))); } else { - let ident = Identifier::new(Some(vis), VarName::new(symbol)); + let ident = Identifier::new( + VisModifierSpec::Public(vis), + VarName::new(symbol), + ); stack.push(ExprOrOp::Expr(obj.attr_expr(ident))); } } @@ -1696,7 +1753,7 @@ impl Parser { } } } - Some(t) if t.is(Symbol) || t.is(Dot) || t.is(UBar) => { + Some(t) if t.is(Symbol) || t.is(Dot) || t.is(DblColon) || t.is(UBar) => { let call_or_acc = self .try_reduce_call_or_acc(in_type_args) .map_err(|_| self.stack_dec(fn_name!()))?; @@ -1861,7 +1918,8 @@ impl Parser { let token = self.lpop(); match token.kind { Symbol => { - let ident = Identifier::new(Some(vis), VarName::new(token)); + let ident = + Identifier::new(VisModifierSpec::Public(vis), VarName::new(token)); obj = obj.attr_expr(ident); } NatLit => { @@ -1895,7 +1953,10 @@ impl Parser { let token = self.lpop(); match token.kind { Symbol => { - let ident = Identifier::new(None, VarName::new(token)); + let ident = Identifier::new( + VisModifierSpec::ExplicitPrivate(vis), + VarName::new(token), + ); obj = obj.attr_expr(ident); } LBrace => { @@ -1905,6 +1966,7 @@ impl Parser { .map_err(|_| self.stack_dec(fn_name!()))?; match args { BraceContainer::Record(args) => { + let vis = VisModifierSpec::ExplicitPrivate(vis); obj = Expr::DataPack(DataPack::new(obj, vis, args)); } other => { @@ -2023,15 +2085,15 @@ impl Parser { } // Empty brace literals - if let Some(first) = self.peek() { - if first.is(RBrace) { + match self.peek_kind() { + Some(RBrace) => { let r_brace = self.lpop(); let arg = Args::empty(); let set = NormalSet::new(l_brace, r_brace, arg); debug_exit_info!(self); return Ok(BraceContainer::Set(Set::Normal(set))); } - if first.is(Equal) { + Some(Equal) => { let _eq = self.lpop(); if let Some(t) = self.peek() { if t.is(RBrace) { @@ -2045,7 +2107,7 @@ impl Parser { debug_exit_info!(self); return Err(()); } - if first.is(Colon) { + Some(Colon) => { let _colon = self.lpop(); if let Some(t) = self.peek() { if t.is(RBrace) { @@ -2060,6 +2122,7 @@ impl Parser { debug_exit_info!(self); return Err(()); } + _ => {} } let first = self @@ -2541,7 +2604,8 @@ impl Parser { .transpose() .map_err(|_| self.stack_dec(fn_name!()))? { - let ident = Identifier::new(Some(vis), VarName::new(symbol)); + let ident = + Identifier::new(VisModifierSpec::Public(vis), VarName::new(symbol)); let mut call = Expr::Call(Call::new(obj, Some(ident), args)); while let Some(res) = self.opt_reduce_args(false) { let args = res.map_err(|_| self.stack_dec(fn_name!()))?; diff --git a/crates/erg_parser/tests/parse_test.rs b/crates/erg_parser/tests/parse_test.rs index 60e4317ce..cf7e7ba48 100644 --- a/crates/erg_parser/tests/parse_test.rs +++ b/crates/erg_parser/tests/parse_test.rs @@ -68,7 +68,7 @@ fn exec_invalid_chunk_prs_err() -> Result<(), ()> { } fn _parse_test_from_code(file_path: &'static str) -> Result<(), ParserRunnerErrors> { - let input = Input::File(file_path.into()); + let input = Input::file(file_path.into()); let cfg = ErgConfig { input: input.clone(), py_server_timeout: 100, diff --git a/crates/erg_parser/tests/tokenize_test.rs b/crates/erg_parser/tests/tokenize_test.rs index d6746ecb4..70fa950c8 100644 --- a/crates/erg_parser/tests/tokenize_test.rs +++ b/crates/erg_parser/tests/tokenize_test.rs @@ -17,7 +17,7 @@ const FILE5: &str = "tests/for.er"; #[test] fn test_lexer_for_basic() -> ParseResult<()> { - let mut lexer = Lexer::new(Input::File(FILE1.into())); + let mut lexer = Lexer::new(Input::file(FILE1.into())); let newline = "\n"; let token_array = vec![ (Newline, newline), @@ -131,7 +131,7 @@ fn test_lexer_for_basic() -> ParseResult<()> { #[test] fn test_lexer_for_advanced() -> ParseResult<()> { - let mut lexer = Lexer::new(Input::File(FILE2.into())); + let mut lexer = Lexer::new(Input::file(FILE2.into())); let newline = "\n"; let token_array = vec![ (Newline, newline), @@ -224,7 +224,7 @@ fn test_lexer_for_advanced() -> ParseResult<()> { #[test] fn test_lexer_for_literals() -> ParseResult<()> { - let mut lexer = Lexer::new(Input::File(FILE3.into())); + let mut lexer = Lexer::new(Input::file(FILE3.into())); let newline = "\n"; let token_array = vec![ (Newline, newline), @@ -309,7 +309,7 @@ fn test_lexer_for_literals() -> ParseResult<()> { #[test] fn test_lexer_for_multi_line_str_literal() -> ParseResult<()> { - let mut lexer = Lexer::new(Input::File(FILE4.into())); + let mut lexer = Lexer::new(Input::file(FILE4.into())); let newline = "\n"; let token_array = [ (Newline, newline), @@ -405,7 +405,7 @@ line break\"\"\"", #[test] fn for_loop() -> ParseResult<()> { - let mut lexer = Lexer::new(Input::File(FILE5.into())); + let mut lexer = Lexer::new(Input::file(FILE5.into())); let newline = "\n"; let token_array = [ (Symbol, "for!"), diff --git a/crates/erg_parser/typespec.rs b/crates/erg_parser/typespec.rs index fb6b2ab78..940d5fa54 100644 --- a/crates/erg_parser/typespec.rs +++ b/crates/erg_parser/typespec.rs @@ -229,11 +229,12 @@ impl Parser { (ParamPattern::VarName(name), Some(t_spec_with_op)) => { ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) } - (ParamPattern::VarName(name), None) => { - ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple( - SimpleTypeSpec::new(Identifier::new(None, name), ConstArgs::empty()), - ))) - } + (ParamPattern::VarName(name), None) => ParamTySpec::anonymous(TypeSpec::PreDeclTy( + PreDeclTypeSpec::Simple(SimpleTypeSpec::new( + Identifier::new(VisModifierSpec::Private, name), + ConstArgs::empty(), + )), + )), _ => todo!(), }; non_defaults.push(param); @@ -247,11 +248,12 @@ impl Parser { (ParamPattern::VarName(name), Some(t_spec_with_op)) => { ParamTySpec::new(Some(name.into_token()), t_spec_with_op.t_spec) } - (ParamPattern::VarName(name), None) => { - ParamTySpec::anonymous(TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple( - SimpleTypeSpec::new(Identifier::new(None, name), ConstArgs::empty()), - ))) - } + (ParamPattern::VarName(name), None) => ParamTySpec::anonymous( + TypeSpec::PreDeclTy(PreDeclTypeSpec::Simple(SimpleTypeSpec::new( + Identifier::new(VisModifierSpec::Private, name), + ConstArgs::empty(), + ))), + ), _ => todo!(), }); let mut defaults = vec![]; diff --git a/examples/class.er b/examples/class.er index 17d0f5614..586ff982b 100644 --- a/examples/class.er +++ b/examples/class.er @@ -4,7 +4,7 @@ print! empty # Inheritance is prohibited by default. Remove this decorator and check for errors. @Inheritable -Point2D = Class {x = Int; y = Int} +Point2D = Class {::[<: Self]x = Int; ::[<: Self]y = Int} Point2D:: one = 1 Point2D. diff --git a/examples/unpack.er b/examples/unpack.er index b4823e431..049cb6808 100644 --- a/examples/unpack.er +++ b/examples/unpack.er @@ -1,5 +1,5 @@ -UnpackPoint2D = Class {x = Int; y = Int}, Impl := Unpack +UnpackPoint2D = Class {.x = Int; .y = Int}, Impl := Unpack -q = UnpackPoint2D::{x = 1; y = 2} +q = UnpackPoint2D::{.x = 1; .y = 2} UnpackPoint2D::{x; y} = q print! x, y diff --git a/tests/common.rs b/tests/common.rs index 2da6f07f3..bed4d2417 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -140,7 +140,7 @@ fn _exec_file(file_path: &'static str) -> Result { pub fn _exec_repl(name: &'static str, lines: Vec) -> Result { println!("{DEBUG_MAIN}[test] exec dummy REPL: {lines:?}{RESET}"); let cfg = ErgConfig { - input: Input::DummyREPL(DummyStdin::new(name.to_string(), lines)), + input: Input::dummy_repl(DummyStdin::new(name.to_string(), lines)), quiet_repl: true, ..Default::default() }; diff --git a/tests/repl.rs b/tests/repl.rs index 816e2c737..1de3531aa 100644 --- a/tests/repl.rs +++ b/tests/repl.rs @@ -107,7 +107,7 @@ fn exec_invalid_class_inheritable() -> Result<(), ()> { "repl_auto_indent_dedent", [ "@Inheritable", - "Point2d = Class{ x = Int; y = Int }", + "Point2d = Class{ ::[<: Self]x = Int; ::[<: Self]y = Int }", "Point2d::", "one = 1", "", diff --git a/tests/should_err/visibility.er b/tests/should_err/visibility.er new file mode 100644 index 000000000..709a1b506 --- /dev/null +++ b/tests/should_err/visibility.er @@ -0,0 +1,33 @@ +@Inheritable +Point2D = Class {::[<: Self]x = Int; ::[<: Self]y = Int} +Point2D. + norm self = self::x**2 + self::y**2 #OK + +Point3D = Inherit Point2D, Additional := {z = Int} +Point3D. + @Override + norm self = self::x**2 + self::y**2 + self::z**2 #OK + +C = Class() +C. + method point: Point2D = point::x # ERR + +p = Point3D.new {x = 1; y = 2; z = 3} +p::x # ERR +p.x # ERR +p::z # ERR + +rec = { + ::[f] x = 1 +} + +f x = rec::x + x # OK +g x = rec::x + x # ERR + +unpack {x; y}: {.x = Int; .y = Int} = x + y + +private = { x = 1; y = 2 } +public = { .x = 1; .y = 2 } + +_ = unpack public # OK +_ = unpack private # ERR diff --git a/tests/should_ok/pattern.er b/tests/should_ok/pattern.er index c276ef8d9..f0a1aa341 100644 --- a/tests/should_ok/pattern.er +++ b/tests/should_ok/pattern.er @@ -1,6 +1,6 @@ -f {x; y}, [_], (_, _) = x + y +f {.x; .y}, [_], (_, _) = x + y -x = f {x = 1; y = 2}, [3], (4, 5) +x = f {.x = 1; .y = 2}, [3], (4, 5) assert x == 3 #[ diff --git a/tests/test.rs b/tests/test.rs index 3bd9c7e47..398e2d5f5 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -306,6 +306,11 @@ fn exec_var_args_err() -> Result<(), ()> { expect_failure("tests/should_err/var_args.er", 3) } +#[test] +fn exec_visibility() -> Result<(), ()> { + expect_failure("tests/should_err/visibility.er", 6) +} + #[test] fn exec_move() -> Result<(), ()> { expect_failure("tests/should_err/move.er", 1)