From 9b7694ccf5510e97375b53af4f0adea5675434b0 Mon Sep 17 00:00:00 2001 From: Grant Wuerker Date: Mon, 19 Feb 2024 17:46:49 -0700 Subject: [PATCH] library2 --- Cargo.lock | 9 ++ crates/common2/src/input.rs | 2 +- crates/driver2/Cargo.toml | 1 + crates/driver2/src/lib.rs | 23 ++- crates/driver2/tests/std_lib.rs | 13 ++ crates/hir/src/analysis_pass.rs | 15 +- crates/library2/Cargo.toml | 11 ++ crates/library2/build.rs | 3 + crates/library2/src/lib.rs | 58 +++++++ crates/library2/std/src/lib.fe | 1 + crates/library2/std/src/num.fe | 1 + crates/library2/std/src/num/int.fe | 4 + crates/library2/std/src/num/int/extend.fe | 69 ++++++++ crates/library2/std/src/num/int/ops.fe | 1 + crates/library2/std/src/num/int/ops/arith.fe | 159 +++++++++++++++++++ crates/library2/std/src/num/int/ops/cmp.fe | 82 ++++++++++ crates/library2/std/src/num/int/saturate.fe | 70 ++++++++ crates/library2/std/src/num/int/truncate.fe | 69 ++++++++ crates/library2/std/src/ops.fe | 1 + crates/library2/std/src/ops/arith.fe | 64 ++++++++ crates/library2/std/src/ops/cmp.fe | 30 ++++ crates/library2/std/src/ops/logical.fe | 30 ++++ 22 files changed, 712 insertions(+), 4 deletions(-) create mode 100644 crates/driver2/tests/std_lib.rs create mode 100644 crates/library2/Cargo.toml create mode 100644 crates/library2/build.rs create mode 100644 crates/library2/src/lib.rs create mode 100644 crates/library2/std/src/lib.fe create mode 100644 crates/library2/std/src/num.fe create mode 100644 crates/library2/std/src/num/int.fe create mode 100644 crates/library2/std/src/num/int/extend.fe create mode 100644 crates/library2/std/src/num/int/ops.fe create mode 100644 crates/library2/std/src/num/int/ops/arith.fe create mode 100644 crates/library2/std/src/num/int/ops/cmp.fe create mode 100644 crates/library2/std/src/num/int/saturate.fe create mode 100644 crates/library2/std/src/num/int/truncate.fe create mode 100644 crates/library2/std/src/ops.fe create mode 100644 crates/library2/std/src/ops/arith.fe create mode 100644 crates/library2/std/src/ops/cmp.fe create mode 100644 crates/library2/std/src/ops/logical.fe diff --git a/Cargo.lock b/Cargo.lock index 82b70f7916..104f0fa0ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1229,6 +1229,7 @@ dependencies = [ "fe-common2", "fe-hir", "fe-hir-analysis", + "fe-library2", "fe-macros", "salsa-2022", ] @@ -1318,6 +1319,14 @@ dependencies = [ "smol_str", ] +[[package]] +name = "fe-library2" +version = "0.23.0" +dependencies = [ + "fe-common2", + "include_dir", +] + [[package]] name = "fe-macros" version = "0.26.0" diff --git a/crates/common2/src/input.rs b/crates/common2/src/input.rs index 4eb82cba62..48841ad0f9 100644 --- a/crates/common2/src/input.rs +++ b/crates/common2/src/input.rs @@ -10,7 +10,7 @@ use crate::InputDb; #[salsa::input(constructor = __new_impl)] pub struct InputIngot { /// An absolute path to the ingot root directory. - /// The all files in the ingot should be located under this directory. + /// All files in the ingot should be located under this directory. #[return_ref] pub path: Utf8PathBuf, diff --git a/crates/driver2/Cargo.toml b/crates/driver2/Cargo.toml index 8a8b6804ec..08fef5d158 100644 --- a/crates/driver2/Cargo.toml +++ b/crates/driver2/Cargo.toml @@ -12,6 +12,7 @@ description = "Provides Fe driver" [dependencies] salsa = { git = "https://github.com/salsa-rs/salsa", package = "salsa-2022" } codespan-reporting = "0.11" +library2 = { path = "../library2", package = "fe-library2" } hir = { path = "../hir", package = "fe-hir" } common = { path = "../common2", package = "fe-common2" } diff --git a/crates/driver2/src/lib.rs b/crates/driver2/src/lib.rs index 0541146869..c574427cf4 100644 --- a/crates/driver2/src/lib.rs +++ b/crates/driver2/src/lib.rs @@ -12,8 +12,11 @@ use common::{ InputDb, InputFile, InputIngot, }; use hir::{ - analysis_pass::AnalysisPassManager, diagnostics::DiagnosticVoucher, hir_def::TopLevelMod, - lower::map_file_to_mod, HirDb, LowerHirDb, ParsingPass, SpannedHirDb, + analysis_pass::AnalysisPassManager, + diagnostics::DiagnosticVoucher, + hir_def::TopLevelMod, + lower::{map_file_to_mod, module_tree}, + HirDb, LowerHirDb, ParsingPass, SpannedHirDb, }; use hir_analysis::{ name_resolution::{DefConflictAnalysisPass, ImportAnalysisPass, PathAnalysisPass}, @@ -58,6 +61,10 @@ impl DriverDataBase { self.run_on_file_with_pass_manager(top_mod, initialize_analysis_pass); } + pub fn run_on_ingot(&mut self, ingot: InputIngot) { + self.run_on_ingot_with_pass_manager(ingot, initialize_analysis_pass); + } + pub fn run_on_file_with_pass_manager(&mut self, top_mod: TopLevelMod, pm_builder: F) where F: FnOnce(&DriverDataBase) -> AnalysisPassManager<'_>, @@ -69,6 +76,18 @@ impl DriverDataBase { }; } + pub fn run_on_ingot_with_pass_manager(&mut self, ingot: InputIngot, pm_builder: F) + where + F: FnOnce(&DriverDataBase) -> AnalysisPassManager<'_>, + { + self.diags.clear(); + let tree = module_tree(self, ingot); + self.diags = { + let mut pass_manager = pm_builder(self); + pass_manager.run_on_module_tree(tree) + }; + } + pub fn top_mod_from_file(&mut self, file_path: &path::Path, source: &str) -> TopLevelMod { let kind = IngotKind::StandAlone; diff --git a/crates/driver2/tests/std_lib.rs b/crates/driver2/tests/std_lib.rs new file mode 100644 index 0000000000..3d5256bfc3 --- /dev/null +++ b/crates/driver2/tests/std_lib.rs @@ -0,0 +1,13 @@ +use fe_driver2::DriverDataBase; + +#[test] +fn check_std_lib() { + let mut driver = DriverDataBase::default(); + let std_ingot = library2::std_lib_input_ingot(&mut driver); + driver.run_on_ingot(std_ingot); + + let diags = driver.format_diags(); + if !diags.is_empty() { + panic!("{diags}") + } +} diff --git a/crates/hir/src/analysis_pass.rs b/crates/hir/src/analysis_pass.rs index ebfad04d0c..eb21a2c096 100644 --- a/crates/hir/src/analysis_pass.rs +++ b/crates/hir/src/analysis_pass.rs @@ -1,4 +1,7 @@ -use crate::{diagnostics::DiagnosticVoucher, hir_def::TopLevelMod}; +use crate::{ + diagnostics::DiagnosticVoucher, + hir_def::{ModuleTree, TopLevelMod}, +}; /// All analysis passes that run analysis on the HIR top level module /// granularity should implement this trait. @@ -27,4 +30,14 @@ impl<'db> AnalysisPassManager<'db> { } diags } + + pub fn run_on_module_tree(&mut self, tree: &ModuleTree) -> Vec> { + let mut diags = vec![]; + for module in tree.all_modules() { + for pass in self.module_passes.iter_mut() { + diags.extend(pass.run_on_module(module)); + } + } + diags + } } diff --git a/crates/library2/Cargo.toml b/crates/library2/Cargo.toml new file mode 100644 index 0000000000..d2ddd0ed7d --- /dev/null +++ b/crates/library2/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "fe-library2" +version = "0.23.0" +authors = ["The Fe Developers "] +edition = "2021" +license = "Apache-2.0" +repository = "https://github.com/ethereum/fe" + +[dependencies] +include_dir = "0.7.2" +common = { path = "../common2", package = "fe-common2" } diff --git a/crates/library2/build.rs b/crates/library2/build.rs new file mode 100644 index 0000000000..0ce78ee5e7 --- /dev/null +++ b/crates/library2/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rerun-if-changed=./std"); +} diff --git a/crates/library2/src/lib.rs b/crates/library2/src/lib.rs new file mode 100644 index 0000000000..5c50b9499d --- /dev/null +++ b/crates/library2/src/lib.rs @@ -0,0 +1,58 @@ +use std::collections::BTreeSet; + +pub use ::include_dir; +use common::{ + input::{IngotKind, Version}, + InputDb, InputFile, InputIngot, +}; +use include_dir::{include_dir, Dir}; + +pub const STD: Dir = include_dir!("$CARGO_MANIFEST_DIR/std"); + +fn std_src_input_files(db: &mut dyn InputDb, ingot: InputIngot) -> BTreeSet { + static_dir_files(&STD) + .into_iter() + .map(|(path, content)| InputFile::new(db, ingot, path.into(), content.into())) + .collect() +} + +pub fn std_lib_input_ingot(db: &mut dyn InputDb) -> InputIngot { + let ingot = InputIngot::new( + db, + "/", + IngotKind::Std, + Version::new(0, 0, 0), + BTreeSet::default(), + ); + + let input_files = std_src_input_files(db, ingot); + let root_file = input_files + .iter() + .find(|file| file.path(db).ends_with("lib.fe")) + .unwrap() + .to_owned(); + + ingot.set_root_file(db, root_file); + ingot.set_files(db, input_files); + + ingot +} + +pub fn static_dir_files(dir: &'static Dir) -> Vec<(&'static str, &'static str)> { + fn add_files(dir: &'static Dir, accum: &mut Vec<(&'static str, &'static str)>) { + accum.extend(dir.files().map(|file| { + ( + file.path().to_str().unwrap(), + file.contents_utf8().expect("non-utf8 static file"), + ) + })); + + for sub_dir in dir.dirs() { + add_files(sub_dir, accum) + } + } + + let mut files = vec![]; + add_files(dir, &mut files); + files +} diff --git a/crates/library2/std/src/lib.fe b/crates/library2/std/src/lib.fe new file mode 100644 index 0000000000..9be3508f4e --- /dev/null +++ b/crates/library2/std/src/lib.fe @@ -0,0 +1 @@ +//! The Fe standard library. \ No newline at end of file diff --git a/crates/library2/std/src/num.fe b/crates/library2/std/src/num.fe new file mode 100644 index 0000000000..80406128ed --- /dev/null +++ b/crates/library2/std/src/num.fe @@ -0,0 +1 @@ +//! Basic numeric functionality. \ No newline at end of file diff --git a/crates/library2/std/src/num/int.fe b/crates/library2/std/src/num/int.fe new file mode 100644 index 0000000000..bd31d2e18b --- /dev/null +++ b/crates/library2/std/src/num/int.fe @@ -0,0 +1,4 @@ +//! Basic integer functionality. + +pub type isize = i256 +pub type usize = u256 \ No newline at end of file diff --git a/crates/library2/std/src/num/int/extend.fe b/crates/library2/std/src/num/int/extend.fe new file mode 100644 index 0000000000..2e052ce7c1 --- /dev/null +++ b/crates/library2/std/src/num/int/extend.fe @@ -0,0 +1,69 @@ +//! Integer extension. + +extern { + fn u8_u16_extend(_ x: u8) -> u16 + fn u8_u32_extend(_ x: u8) -> u32 + fn u8_u64_extend(_ x: u8) -> u64 + fn u8_u128_extend(_ x: u8) -> u128 + fn u8_u256_extend(_ x: u8) -> u256 + fn u16_u32_extend(_ x: u16) -> u32 + fn u16_u64_extend(_ x: u16) -> u64 + fn u16_u128_extend(_ x: u16) -> u128 + fn u16_u256_extend(_ x: u16) -> u256 + fn u32_u64_extend(_ x: u32) -> u64 + fn u32_u128_extend(_ x: u32) -> u128 + fn u32_u256_extend(_ x: u32) -> u256 + fn u64_u128_extend(_ x: u64) -> u128 + fn u64_u256_extend(_ x: u64) -> u256 + fn u128_u256_extend(_ x: u128) -> u256 + fn i8_i16_extend(_ x: i8) -> i16 + fn i8_i32_extend(_ x: i8) -> i32 + fn i8_i64_extend(_ x: i8) -> i64 + fn i8_i128_extend(_ x: i8) -> i128 + fn i8_i256_extend(_ x: i8) -> i256 + fn i16_i32_extend(_ x: i16) -> i32 + fn i16_i64_extend(_ x: i16) -> i64 + fn i16_i128_extend(_ x: i16) -> i128 + fn i16_i256_extend(_ x: i16) -> i256 + fn i32_i64_extend(_ x: i32) -> i64 + fn i32_i128_extend(_ x: i32) -> i128 + fn i32_i256_extend(_ x: i32) -> i256 + fn i64_i128_extend(_ x: i64) -> i128 + fn i64_i256_extend(_ x: i64) -> i256 + fn i128_i256_extend(_ x: i128) -> i256 +} + +pub trait Extend { + fn extend(self) -> Out +} + +impl Extend for u8 { fn extend(self) -> u16 { u8_u16_extend(self) } } +impl Extend for u8 { fn extend(self) -> u32 { u8_u32_extend(self) } } +impl Extend for u8 { fn extend(self) -> u64 { u8_u64_extend(self) } } +impl Extend for u8 { fn extend(self) -> u128 { u8_u128_extend(self) } } +impl Extend for u8 { fn extend(self) -> u256 { u8_u256_extend(self) } } +impl Extend for u16 { fn extend(self) -> u32 { u16_u32_extend(self) } } +impl Extend for u16 { fn extend(self) -> u64 { u16_u64_extend(self) } } +impl Extend for u16 { fn extend(self) -> u128 { u16_u128_extend(self) } } +impl Extend for u16 { fn extend(self) -> u256 { u16_u256_extend(self) } } +impl Extend for u32 { fn extend(self) -> u64 { u32_u64_extend(self) } } +impl Extend for u32 { fn extend(self) -> u128 { u32_u128_extend(self) } } +impl Extend for u32 { fn extend(self) -> u256 { u32_u256_extend(self) } } +impl Extend for u64 { fn extend(self) -> u128 { u64_u128_extend(self) } } +impl Extend for u64 { fn extend(self) -> u256 { u64_u256_extend(self) } } +impl Extend for u128 { fn extend(self) -> u256 { u128_u256_extend(self) } } +impl Extend for i8 { fn extend(self) -> i16 { i8_i16_extend(self) } } +impl Extend for i8 { fn extend(self) -> i32 { i8_i32_extend(self) } } +impl Extend for i8 { fn extend(self) -> i64 { i8_i64_extend(self) } } +impl Extend for i8 { fn extend(self) -> i128 { i8_i128_extend(self) } } +impl Extend for i8 { fn extend(self) -> i256 { i8_i256_extend(self) } } +impl Extend for i16 { fn extend(self) -> i32 { i16_i32_extend(self) } } +impl Extend for i16 { fn extend(self) -> i64 { i16_i64_extend(self) } } +impl Extend for i16 { fn extend(self) -> i128 { i16_i128_extend(self) } } +impl Extend for i16 { fn extend(self) -> i256 { i16_i256_extend(self) } } +impl Extend for i32 { fn extend(self) -> i64 { i32_i64_extend(self) } } +impl Extend for i32 { fn extend(self) -> i128 { i32_i128_extend(self) } } +impl Extend for i32 { fn extend(self) -> i256 { i32_i256_extend(self) } } +impl Extend for i64 { fn extend(self) -> i128 { i64_i128_extend(self) } } +impl Extend for i64 { fn extend(self) -> i256 { i64_i256_extend(self) } } +impl Extend for i128 { fn extend(self) -> i256 { i128_i256_extend(self) } } \ No newline at end of file diff --git a/crates/library2/std/src/num/int/ops.fe b/crates/library2/std/src/num/int/ops.fe new file mode 100644 index 0000000000..7eb988130b --- /dev/null +++ b/crates/library2/std/src/num/int/ops.fe @@ -0,0 +1 @@ +//! Integer operations. \ No newline at end of file diff --git a/crates/library2/std/src/num/int/ops/arith.fe b/crates/library2/std/src/num/int/ops/arith.fe new file mode 100644 index 0000000000..2dad574c55 --- /dev/null +++ b/crates/library2/std/src/num/int/ops/arith.fe @@ -0,0 +1,159 @@ +use ingot::ops::arith::{ + Add, Sub, Div, Mul, Exp, + Mod, Shl, Shr, Minus, + BitAnd, BitOr, BitNot +} +use ingot::num::int::{usize, isize} + +extern { + fn abort() -> ! +} + +impl Add for i8 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for i16 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for i32 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for i64 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for i128 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for i256 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for u8 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for u16 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for u32 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for u64 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for u128 { fn add(self, rhs: Self) -> Self { abort() } } +impl Add for u256 { fn add(self, rhs: Self) -> Self { abort() } } + +impl Sub for i8 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for i16 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for i32 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for i64 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for i128 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for i256 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for u8 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for u16 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for u32 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for u64 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for u128 { fn sub(self, rhs: Self) -> Self { abort() } } +impl Sub for u256 { fn sub(self, rhs: Self) -> Self { abort() } } + +impl Mul for i8 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for i16 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for i32 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for i64 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for i128 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for i256 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for u8 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for u16 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for u32 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for u64 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for u128 { fn mul(self, rhs: Self) -> Self { abort() } } +impl Mul for u256 { fn mul(self, rhs: Self) -> Self { abort() } } + +impl Div for i8 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for i16 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for i32 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for i64 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for i128 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for i256 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for u8 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for u16 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for u32 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for u64 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for u128 { fn div(self, rhs: Self) -> Self { abort() } } +impl Div for u256 { fn div(self, rhs: Self) -> Self { abort() } } + +impl Exp for i8 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for i16 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for i32 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for i64 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for i128 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for i256 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for u8 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for u16 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for u32 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for u64 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for u128 { fn exp(self, rhs: Self) -> Self { abort() } } +impl Exp for u256 { fn exp(self, rhs: Self) -> Self { abort() } } + +impl Mod for i8 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for i16 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for i32 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for i64 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for i128 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for i256 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for u8 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for u16 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for u32 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for u64 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for u128 { fn modulo(self, rhs: Self) -> Self { abort() } } +impl Mod for u256 { fn modulo(self, rhs: Self) -> Self { abort() } } + +impl Shl for i8 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for i16 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for i32 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for i64 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for i128 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for i256 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for u8 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for u16 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for u32 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for u64 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for u128 { fn shl(self, rhs: usize) -> Self { abort() } } +impl Shl for u256 { fn shl(self, rhs: usize) -> Self { abort() } } + +impl Shr for i16 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for i32 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for i64 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for i128 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for i256 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for u8 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for u16 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for u32 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for u64 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for u128 { fn shr(self, rhs: usize) -> Self { abort() } } +impl Shr for u256 { fn shr(self, rhs: usize) -> Self { abort() } } + +impl BitAnd for i8 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for i16 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for i32 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for i64 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for i128 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for i256 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for u8 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for u16 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for u32 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for u64 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for u128 { fn bit_and(self, rhs: Self) -> Self { abort() } } +impl BitAnd for u256 { fn bit_and(self, rhs: Self) -> Self { abort() } } + +impl BitOr for i8 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for i16 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for i32 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for i64 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for i128 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for i256 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for u8 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for u16 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for u32 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for u64 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for u128 { fn bit_or(self, rhs: Self) -> Self { abort() } } +impl BitOr for u256 { fn bit_or(self, rhs: Self) -> Self { abort() } } + +impl BitNot for i8 { fn bit_not(self) -> Self { abort() } } +impl BitNot for i16 { fn bit_not(self) -> Self { abort() } } +impl BitNot for i32 { fn bit_not(self) -> Self { abort() } } +impl BitNot for i64 { fn bit_not(self) -> Self { abort() } } +impl BitNot for i128 { fn bit_not(self) -> Self { abort() } } +impl BitNot for i256 { fn bit_not(self) -> Self { abort() } } +impl BitNot for u8 { fn bit_not(self) -> Self { abort() } } +impl BitNot for u16 { fn bit_not(self) -> Self { abort() } } +impl BitNot for u32 { fn bit_not(self) -> Self { abort() } } +impl BitNot for u64 { fn bit_not(self) -> Self { abort() } } +impl BitNot for u128 { fn bit_not(self) -> Self { abort() } } +impl BitNot for u256 { fn bit_not(self) -> Self { abort() } } + +impl Minus for i8 { fn minus(self) -> Self { abort() } } +impl Minus for i16 { fn minus(self) -> Self { abort() } } +impl Minus for i32 { fn minus(self) -> Self { abort() } } +impl Minus for i64 { fn minus(self) -> Self { abort() } } +impl Minus for i128 { fn minus(self) -> Self { abort() } } +impl Minus for i256 { fn minus(self) -> Self { abort() } } diff --git a/crates/library2/std/src/num/int/ops/cmp.fe b/crates/library2/std/src/num/int/ops/cmp.fe new file mode 100644 index 0000000000..c1e04fcf33 --- /dev/null +++ b/crates/library2/std/src/num/int/ops/cmp.fe @@ -0,0 +1,82 @@ +use ingot::ops::cmp::{Eq, NotEq, Lt, LtEq, Gt, Gt, GtEq} + +extern { + fn abort() -> ! +} + +impl Eq for i8 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for i16 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for i32 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for i64 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for i128 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for i256 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for u8 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for u16 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for u32 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for u64 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for u128 { fn eq(self, rhs: Self) -> Self { abort() } } +impl Eq for u256 { fn eq(self, rhs: Self) -> Self { abort() } } + +impl NotEq for i8 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for i16 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for i32 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for i64 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for i128 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for i256 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for u8 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for u16 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for u32 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for u64 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for u128 { fn not_eq(self, rhs: Self) -> Self { abort() } } +impl NotEq for u256 { fn not_eq(self, rhs: Self) -> Self { abort() } } + +impl Lt for i8 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for i16 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for i32 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for i64 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for i128 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for i256 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for u8 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for u16 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for u32 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for u64 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for u128 { fn lt(self, rhs: Self) -> Self { abort() } } +impl Lt for u256 { fn lt(self, rhs: Self) -> Self { abort() } } + +impl LtEq for i8 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for i16 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for i32 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for i64 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for i128 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for i256 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for u8 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for u16 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for u32 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for u64 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for u128 { fn lt_eq(self, rhs: Self) -> Self { abort() } } +impl LtEq for u256 { fn lt_eq(self, rhs: Self) -> Self { abort() } } + +impl Gt for i8 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for i16 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for i32 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for i64 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for i128 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for i256 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for u8 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for u16 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for u32 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for u64 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for u128 { fn gt(self, rhs: Self) -> Self { abort() } } +impl Gt for u256 { fn gt(self, rhs: Self) -> Self { abort() } } + +impl GtEq for i8 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for i16 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for i32 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for i64 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for i128 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for i256 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for u8 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for u16 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for u32 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for u64 { fn gt_eq(self, rhs: Self) -> Self { abort() } } +impl GtEq for u128 { fn gt_eq(self, rhs: Self) -> Self { abort() } } \ No newline at end of file diff --git a/crates/library2/std/src/num/int/saturate.fe b/crates/library2/std/src/num/int/saturate.fe new file mode 100644 index 0000000000..fad693350e --- /dev/null +++ b/crates/library2/std/src/num/int/saturate.fe @@ -0,0 +1,70 @@ +//! Integer saturation. + +extern { + fn u16_u8_saturate(_ x: u16) -> u8 + fn u32_u8_saturate(_ x: u32) -> u8 + fn u32_u16_saturate(_ x: u32) -> u16 + fn u64_u8_saturate(_ x: u64) -> u8 + fn u64_u16_saturate(_ x: u64) -> u16 + fn u64_u32_saturate(_ x: u64) -> u32 + fn u128_u8_saturate(_ x: u128) -> u8 + fn u128_u16_saturate(_ x: u128) -> u16 + fn u128_u32_saturate(_ x: u128) -> u32 + fn u128_u64_saturate(_ x: u128) -> u64 + fn u256_u8_saturate(_ x: u256) -> u8 + fn u256_u16_saturate(_ x: u256) -> u16 + fn u256_u32_saturate(_ x: u256) -> u32 + fn u256_u64_saturate(_ x: u256) -> u64 + fn u256_u128_saturate(_ x: u256) -> u128 + fn i16_i8_saturate(_ x: i16) -> i8 + fn i32_i8_saturate(_ x: i32) -> i8 + fn i32_i16_saturate(_ x: i32) -> i16 + fn i64_i8_saturate(_ x: i64) -> i8 + fn i64_i16_saturate(_ x: i64) -> i16 + fn i64_i32_saturate(_ x: i64) -> i32 + fn i128_i8_saturate(_ x: i128) -> i8 + fn i128_i16_saturate(_ x: i128) -> i16 + fn i128_i32_saturate(_ x: i128) -> i32 + fn i128_i64_saturate(_ x: i128) -> i64 + fn i256_i8_saturate(_ x: i256) -> i8 + fn i256_i16_saturate(_ x: i256) -> i16 + fn i256_i32_saturate(_ x: i256) -> i32 + fn i256_i64_saturate(_ x: i256) -> i64 + fn i256_i128_saturate(_ x: i256) -> i128 +} + +pub trait Saturate { + fn saturate(self) -> Out +} + +impl Saturate for u16 { fn saturate(self) -> u8 { u16_u8_saturate(self) } } +impl Saturate for u32 { fn saturate(self) -> u8 { u32_u8_saturate(self) } } +impl Saturate for u32 { fn saturate(self) -> u16 { u32_u16_saturate(self) } } +impl Saturate for u64 { fn saturate(self) -> u8 { u64_u8_saturate(self) } } +impl Saturate for u64 { fn saturate(self) -> u16 { u64_u16_saturate(self) } } +impl Saturate for u64 { fn saturate(self) -> u32 { u64_u32_saturate(self) } } +impl Saturate for u128 { fn saturate(self) -> u8 { u128_u8_saturate(self) } } +impl Saturate for u128 { fn saturate(self) -> u16 { u128_u16_saturate(self) } } +impl Saturate for u128 { fn saturate(self) -> u32 { u128_u32_saturate(self) } } +impl Saturate for u128 { fn saturate(self) -> u64 { u128_u64_saturate(self) } } +impl Saturate for u256 { fn saturate(self) -> u8 { u256_u8_saturate(self) } } +impl Saturate for u256 { fn saturate(self) -> u16 { u256_u16_saturate(self) } } +impl Saturate for u256 { fn saturate(self) -> u32 { u256_u32_saturate(self) } } +impl Saturate for u256 { fn saturate(self) -> u64 { u256_u64_saturate(self) } } +impl Saturate for u256 { fn saturate(self) -> u128 { u256_u128_saturate(self) } } +impl Saturate for i16 { fn saturate(self) -> i8 { i16_i8_saturate(self) } } +impl Saturate for i32 { fn saturate(self) -> i8 { i32_i8_saturate(self) } } +impl Saturate for i32 { fn saturate(self) -> i16 { i32_i16_saturate(self) } } +impl Saturate for i64 { fn saturate(self) -> i8 { i64_i8_saturate(self) } } +impl Saturate for i64 { fn saturate(self) -> i16 { i64_i16_saturate(self) } } +impl Saturate for i64 { fn saturate(self) -> i32 { i64_i32_saturate(self) } } +impl Saturate for i128 { fn saturate(self) -> i8 { i128_i8_saturate(self) } } +impl Saturate for i128 { fn saturate(self) -> i16 { i128_i16_saturate(self) } } +impl Saturate for i128 { fn saturate(self) -> i32 { i128_i32_saturate(self) } } +impl Saturate for i128 { fn saturate(self) -> i64 { i128_i64_saturate(self) } } +impl Saturate for i256 { fn saturate(self) -> i8 { i256_i8_saturate(self) } } +impl Saturate for i256 { fn saturate(self) -> i16 { i256_i16_saturate(self) } } +impl Saturate for i256 { fn saturate(self) -> i32 { i256_i32_saturate(self) } } +impl Saturate for i256 { fn saturate(self) -> i64 { i256_i64_saturate(self) } } +impl Saturate for i256 { fn saturate(self) -> i128 { i256_i128_saturate(self) } } + diff --git a/crates/library2/std/src/num/int/truncate.fe b/crates/library2/std/src/num/int/truncate.fe new file mode 100644 index 0000000000..2fd6045451 --- /dev/null +++ b/crates/library2/std/src/num/int/truncate.fe @@ -0,0 +1,69 @@ +//! Integer truncation. + +extern { + fn u16_u8_truncate(_ x: u16) -> u8 + fn u32_u8_truncate(_ x: u32) -> u8 + fn u32_u16_truncate(_ x: u32) -> u16 + fn u64_u8_truncate(_ x: u64) -> u8 + fn u64_u16_truncate(_ x: u64) -> u16 + fn u64_u32_truncate(_ x: u64) -> u32 + fn u128_u8_truncate(_ x: u128) -> u8 + fn u128_u16_truncate(_ x: u128) -> u16 + fn u128_u32_truncate(_ x: u128) -> u32 + fn u128_u64_truncate(_ x: u128) -> u64 + fn u256_u8_truncate(_ x: u256) -> u8 + fn u256_u16_truncate(_ x: u256) -> u16 + fn u256_u32_truncate(_ x: u256) -> u32 + fn u256_u64_truncate(_ x: u256) -> u64 + fn u256_u128_truncate(_ x: u256) -> u128 + fn i16_i8_truncate(_ x: i16) -> i8 + fn i32_i8_truncate(_ x: i32) -> i8 + fn i32_i16_truncate(_ x: i32) -> i16 + fn i64_i8_truncate(_ x: i64) -> i8 + fn i64_i16_truncate(_ x: i64) -> i16 + fn i64_i32_truncate(_ x: i64) -> i32 + fn i128_i8_truncate(_ x: i128) -> i8 + fn i128_i16_truncate(_ x: i128) -> i16 + fn i128_i32_truncate(_ x: i128) -> i32 + fn i128_i64_truncate(_ x: i128) -> i64 + fn i256_i8_truncate(_ x: i256) -> i8 + fn i256_i16_truncate(_ x: i256) -> i16 + fn i256_i32_truncate(_ x: i256) -> i32 + fn i256_i64_truncate(_ x: i256) -> i64 + fn i256_i128_truncate(_ x: i256) -> i128 +} + +pub trait Truncate { + fn truncate(self) -> Out +} + +impl Truncate for u16 { fn truncate(self) -> u8 { u16_u8_truncate(self) } } +impl Truncate for u32 { fn truncate(self) -> u8 { u32_u8_truncate(self) } } +impl Truncate for u32 { fn truncate(self) -> u16 { u32_u16_truncate(self) } } +impl Truncate for u64 { fn truncate(self) -> u8 { u64_u8_truncate(self) } } +impl Truncate for u64 { fn truncate(self) -> u16 { u64_u16_truncate(self) } } +impl Truncate for u64 { fn truncate(self) -> u32 { u64_u32_truncate(self) } } +impl Truncate for u128 { fn truncate(self) -> u8 { u128_u8_truncate(self) } } +impl Truncate for u128 { fn truncate(self) -> u16 { u128_u16_truncate(self) } } +impl Truncate for u128 { fn truncate(self) -> u32 { u128_u32_truncate(self) } } +impl Truncate for u128 { fn truncate(self) -> u64 { u128_u64_truncate(self) } } +impl Truncate for u256 { fn truncate(self) -> u8 { u256_u8_truncate(self) } } +impl Truncate for u256 { fn truncate(self) -> u16 { u256_u16_truncate(self) } } +impl Truncate for u256 { fn truncate(self) -> u32 { u256_u32_truncate(self) } } +impl Truncate for u256 { fn truncate(self) -> u64 { u256_u64_truncate(self) } } +impl Truncate for u256 { fn truncate(self) -> u128 { u256_u128_truncate(self) } } +impl Truncate for i16 { fn truncate(self) -> i8 { i16_i8_truncate(self) } } +impl Truncate for i32 { fn truncate(self) -> i8 { i32_i8_truncate(self) } } +impl Truncate for i32 { fn truncate(self) -> i16 { i32_i16_truncate(self) } } +impl Truncate for i64 { fn truncate(self) -> i8 { i64_i8_truncate(self) } } +impl Truncate for i64 { fn truncate(self) -> i16 { i64_i16_truncate(self) } } +impl Truncate for i64 { fn truncate(self) -> i32 { i64_i32_truncate(self) } } +impl Truncate for i128 { fn truncate(self) -> i8 { i128_i8_truncate(self) } } +impl Truncate for i128 { fn truncate(self) -> i16 { i128_i16_truncate(self) } } +impl Truncate for i128 { fn truncate(self) -> i32 { i128_i32_truncate(self) } } +impl Truncate for i128 { fn truncate(self) -> i64 { i128_i64_truncate(self) } } +impl Truncate for i256 { fn truncate(self) -> i8 { i256_i8_truncate(self) } } +impl Truncate for i256 { fn truncate(self) -> i16 { i256_i16_truncate(self) } } +impl Truncate for i256 { fn truncate(self) -> i32 { i256_i32_truncate(self) } } +impl Truncate for i256 { fn truncate(self) -> i64 { i256_i64_truncate(self) } } +impl Truncate for i256 { fn truncate(self) -> i128 { i256_i128_truncate(self) } } diff --git a/crates/library2/std/src/ops.fe b/crates/library2/std/src/ops.fe new file mode 100644 index 0000000000..441c99fdf8 --- /dev/null +++ b/crates/library2/std/src/ops.fe @@ -0,0 +1 @@ +//! Overloadable operators. \ No newline at end of file diff --git a/crates/library2/std/src/ops/arith.fe b/crates/library2/std/src/ops/arith.fe new file mode 100644 index 0000000000..69d43bfdf3 --- /dev/null +++ b/crates/library2/std/src/ops/arith.fe @@ -0,0 +1,64 @@ +/// Addition (e.g. `x + y`) +pub trait Add { + fn add(self, rhs: RHS) -> Out +} + +/// Subtraction (e.g. `x - y`) +pub trait Sub { + fn sub(self, rhs: RHS) -> Out +} + +/// Multiplication (e.g. `x * y`) +pub trait Mul { + fn mul(self, rhs: RHS) -> Out +} + +/// Division (e.g. `x / y`) +pub trait Div { + fn div(self, rhs: RHS) -> Out +} + +/// Modulo (e.g. `x % y`) +pub trait Mod { + fn modulo(self, rhs: RHS) -> Out +} + +/// Exponentiation (e.g. `x ** y`) +pub trait Exp { + fn exp(self, rhs: RHS) -> Out +} + +/// Left shift (e.g. `x << y`) +pub trait Shl { + fn shl(self, rhs: RHS) -> Out +} + +/// Right shift (e.g. `x >> y`) +pub trait Shr { + fn shr(self, rhs: RHS) -> Out +} + +/// Plus (e.g. `+x`) +pub trait Plus { + fn plus(self) -> Out +} + +/// Minus (e.g. `-x`) +pub trait Minus { + fn minus(self) -> Out +} + +/// Bitwise and (e.g. `x && y`) +pub trait BitAnd { + fn bit_and(self, rhs: RHS) -> Out +} + +/// Bitwise or (e.g. `x || y`) +pub trait BitOr { + fn bit_or(self, rhs: RHS) -> Out +} + +/// Bitwise not (e.g. `~x`) +pub trait BitNot { + fn bit_not(self) -> Out +} \ No newline at end of file diff --git a/crates/library2/std/src/ops/cmp.fe b/crates/library2/std/src/ops/cmp.fe new file mode 100644 index 0000000000..ad48a1edcb --- /dev/null +++ b/crates/library2/std/src/ops/cmp.fe @@ -0,0 +1,30 @@ +/// Equal (e.g. `x == y`) +pub trait Eq { + fn eq(self, rhs: RHS) -> Out +} + +/// `Not equal (e.g. `x != y`) +pub trait NotEq { + fn not_eq(self, rhs: RHS) -> Out +} + +/// Less than (e.g. `x < y`) +pub trait Lt { + fn lt(self, rhs: RHS) -> Out +} + +/// Less than or equal (e.g. `x <= y`) +pub trait LtEq { + fn lt_eq(self, rhs: RHS) -> Out +} + +/// Greater than (e.g. `x > y`) +pub trait Gt { + fn gt(self, rhs: RHS) -> Out +} + +/// Greater than or equal (e.g. `x >= y`) +pub trait GtEq { + fn gt_eq(self, rhs: RHS) -> Out +} + diff --git a/crates/library2/std/src/ops/logical.fe b/crates/library2/std/src/ops/logical.fe new file mode 100644 index 0000000000..67d04f508d --- /dev/null +++ b/crates/library2/std/src/ops/logical.fe @@ -0,0 +1,30 @@ +extern { + fn abort() -> ! +} + +/// Logical and (e.g. `x && y`) +pub trait And { + fn and(self, rhs: RHS) -> Out +} + +/// Logical or (e.g. `x || y`) +pub trait Or { + fn or(self, rhs: RHS) -> Out +} + +/// Logical not (e.g. `!x`) +pub trait Not { + fn not(self) -> Out +} + +impl And for bool { + fn and(self, rhs: Self) -> Self { abort() } +} + +impl Or for bool { + fn or(self, rhs: Self) -> Self { abort() } +} + +impl Not for bool { + fn not(self) -> Self { abort() } +} \ No newline at end of file