diff --git a/forc-pkg/src/manifest/mod.rs b/forc-pkg/src/manifest/mod.rs index 8f77091b518..5df01024621 100644 --- a/forc-pkg/src/manifest/mod.rs +++ b/forc-pkg/src/manifest/mod.rs @@ -523,7 +523,7 @@ impl GenericManifestFile for PackageManifestFile { /// This also `validate`s the manifest, returning an `Err` in the case that invalid names, /// fields were used. /// - /// If `core` and `std` are unspecified, `std` will be added to the `dependencies` table + /// If `std` is unspecified, `std` will be added to the `dependencies` table /// implicitly. In this case, the git tag associated with the version of this crate is used to /// specify the pinned commit at which we fetch `std`. fn from_file>(path: P) -> Result { @@ -591,7 +591,7 @@ impl PackageManifest { /// This also `validate`s the manifest, returning an `Err` in the case that invalid names, /// fields were used. /// - /// If `core` and `std` are unspecified, `std` will be added to the `dependencies` table + /// If `std` is unspecified, `std` will be added to the `dependencies` table /// implicitly. In this case, the git tag associated with the version of this crate is used to /// specify the pinned commit at which we fetch `std`. pub fn from_file>(path: P) -> Result { @@ -609,7 +609,7 @@ impl PackageManifest { /// This also `validate`s the manifest, returning an `Err` in the case that invalid names, /// fields were used. /// - /// If `core` and `std` are unspecified, `std` will be added to the `dependencies` table + /// If `std` is unspecified, `std` will be added to the `dependencies` table /// implicitly. In this case, the git tag associated with the version of this crate is used to /// specify the pinned commit at which we fetch `std`. pub fn from_string(contents: String) -> Result { @@ -722,14 +722,12 @@ impl PackageManifest { /// Note: If only `core` is specified, we are unable to implicitly add `std` as we cannot /// guarantee that the user's `core` is compatible with the implicit `std`. fn implicitly_include_std_if_missing(&mut self) { - use sway_types::constants::{CORE, STD}; + use sway_types::constants::STD; // Don't include `std` if: - // - this *is* `core` or `std`. - // - either `core` or `std` packages are already specified. + // - this *is* `std`. + // - `std` package is already specified. // - a dependency already exists with the name "std". - if self.project.name == CORE - || self.project.name == STD - || self.pkg_dep(CORE).is_some() + if self.project.name == STD || self.pkg_dep(STD).is_some() || self.dep(STD).is_some() || !self.project.implicit_std.unwrap_or(true) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index 8baa265b812..b14b123c951 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -49,7 +49,6 @@ use sway_core::{ use sway_core::{set_bytecode_configurables_offset, PrintAsm, PrintIr}; use sway_error::{error::CompileError, handler::Handler, warning::CompileWarning}; use sway_features::ExperimentalFeatures; -use sway_types::constants::{CORE, STD}; use sway_types::{Ident, Span, Spanned}; use sway_utils::{constants, time_expr, PerformanceData, PerformanceMetric}; use tracing::{debug, info}; @@ -1605,7 +1604,6 @@ pub fn dependency_namespace( }; // Add direct dependencies. - let mut core_added = false; for edge in graph.edges_directed(node, Direction::Outgoing) { let dep_node = edge.target(); let dep_name = kebab_to_snake_case(&edge.weight().name); @@ -1635,59 +1633,11 @@ pub fn dependency_namespace( } }; root_namespace.add_external(dep_name, dep_namespace); - let dep = &graph[dep_node]; - if dep.name == CORE { - core_added = true; - } - } - - // Add `core` if not already added. - if !core_added { - if let Some(core_node) = find_core_dep(graph, node) { - let core_namespace = &lib_namespace_map[&core_node]; - root_namespace.add_external(CORE.to_string(), core_namespace.clone()); - } } Ok(root_namespace) } -/// Find the `core` dependency (whether direct or transitive) for the given node if it exists. -fn find_core_dep(graph: &Graph, node: NodeIx) -> Option { - // If we are `core`, do nothing. - let pkg = &graph[node]; - if pkg.name == CORE { - return None; - } - - // If we have `core` as a direct dep, use it. - let mut maybe_std = None; - for edge in graph.edges_directed(node, Direction::Outgoing) { - let dep_node = edge.target(); - let dep = &graph[dep_node]; - match &dep.name[..] { - CORE => return Some(dep_node), - STD => maybe_std = Some(dep_node), - _ => {} - } - } - - // If we have `std`, select `core` via `std`. - if let Some(std) = maybe_std { - return find_core_dep(graph, std); - } - - // Otherwise, search from this node. - for dep_node in Dfs::new(graph, node).iter(graph) { - let dep = &graph[dep_node]; - if dep.name == CORE { - return Some(dep_node); - } - } - - None -} - /// Compiles the given package. /// /// ## Program Types diff --git a/sway-ast/src/expr/mod.rs b/sway-ast/src/expr/mod.rs index 52999a63dcf..a94a0e9fa1b 100644 --- a/sway-ast/src/expr/mod.rs +++ b/sway-ast/src/expr/mod.rs @@ -295,7 +295,7 @@ pub enum ReassignmentOpVariant { } impl ReassignmentOpVariant { - pub fn core_name(&self) -> &'static str { + pub fn std_name(&self) -> &'static str { match self { ReassignmentOpVariant::Equals => "eq", ReassignmentOpVariant::AddEquals => "add", diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs index 735484b8479..feeeed2f059 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/auto_impl.rs @@ -440,8 +440,13 @@ where engines: &Engines, decl: &TyDecl, ) -> Option<(Option, Option)> { - if self.ctx.namespace.current_package_name().as_str() == "core" { - return Some((None, None)); + if self.ctx.namespace.current_package_name().as_str() == "std" { + if matches!( + self.ctx.namespace.current_module().name().as_str(), + "codec" | "raw_slice" | "raw_ptr" | "ops" | "primitives" | "registers" | "flags" + ) { + return Some((None, None)); + } } let implementing_for_decl_id = decl.to_struct_decl(&Handler::default(), engines).unwrap(); @@ -475,8 +480,13 @@ where engines: &Engines, decl: &TyDecl, ) -> Option<(Option, Option)> { - if self.ctx.namespace.current_package_name().as_str() == "core" { - return Some((None, None)); + if self.ctx.namespace.current_package_name().as_str() == "std" { + if matches!( + self.ctx.namespace.current_module().name().as_str(), + "codec" | "raw_slice" | "raw_ptr" | "ops" | "primitives" | "registers" | "flags" + ) { + return Some((None, None)); + } } let enum_decl_id = decl.to_enum_id(&Handler::default(), engines).unwrap(); diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs index 792de9d779b..cf4a83ee921 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/typed/instantiate.rs @@ -165,7 +165,7 @@ impl Instantiate { lhs: ty::TyExpression, rhs: ty::TyExpression, ) -> Result { - ty::TyExpression::core_ops_eq(handler, ctx, vec![lhs, rhs], self.dummy_span()) + ty::TyExpression::std_ops_eq(handler, ctx, vec![lhs, rhs], self.dummy_span()) } /// Instantiates an expression equivalent to ` != `. @@ -176,7 +176,7 @@ impl Instantiate { lhs: ty::TyExpression, rhs: ty::TyExpression, ) -> Result { - ty::TyExpression::core_ops_neq(handler, ctx, vec![lhs, rhs], self.dummy_span()) + ty::TyExpression::std_ops_neq(handler, ctx, vec![lhs, rhs], self.dummy_span()) } /// Instantiates an expression equivalent to ` == `. The method expects that @@ -187,8 +187,8 @@ impl Instantiate { lhs: ty::TyExpression, rhs: ty::TyExpression, ) -> ty::TyExpression { - ty::TyExpression::core_ops_eq(&Handler::default(), ctx, vec![lhs, rhs], self.dummy_span()) - .expect("Instantiating `core::ops::eq` is expected to always work.") + ty::TyExpression::std_ops_eq(&Handler::default(), ctx, vec![lhs, rhs], self.dummy_span()) + .expect("Instantiating `std::ops::eq` is expected to always work.") } /// Instantiates a [ty::TyExpressionVariant::TupleElemAccess] `.`. The method expects that diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index 65d645dffed..376d8f6653c 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -54,7 +54,7 @@ use type_resolve::{resolve_call_path, VisibilityCheck}; #[allow(clippy::too_many_arguments)] impl ty::TyExpression { - pub(crate) fn core_ops_eq( + pub(crate) fn std_ops_eq( handler: &Handler, ctx: TypeCheckContext, arguments: Vec, @@ -66,10 +66,10 @@ impl ty::TyExpression { TypeInfo::Boolean, span.source_id(), )); - Self::core_ops(handler, ctx, OpVariant::Equals, arguments, span) + Self::std_ops(handler, ctx, OpVariant::Equals, arguments, span) } - pub(crate) fn core_ops_neq( + pub(crate) fn std_ops_neq( handler: &Handler, ctx: TypeCheckContext, arguments: Vec, @@ -81,10 +81,10 @@ impl ty::TyExpression { TypeInfo::Boolean, span.source_id(), )); - Self::core_ops(handler, ctx, OpVariant::NotEquals, arguments, span) + Self::std_ops(handler, ctx, OpVariant::NotEquals, arguments, span) } - fn core_ops( + fn std_ops( handler: &Handler, mut ctx: TypeCheckContext, op_variant: OpVariant, @@ -95,7 +95,7 @@ impl ty::TyExpression { let call_path = CallPath { prefixes: vec![ - Ident::new_with_override("core".into(), span.clone()), + Ident::new_with_override("std".into(), span.clone()), Ident::new_with_override("ops".into(), span.clone()), ], suffix: Op { @@ -1242,11 +1242,12 @@ impl ty::TyExpression { ) })?; - // The type of a storage access is `core::storage::StorageKey`. This is + // The type of a storage access is `std::storage::storage_key::StorageKey`. This is // the path to it. let storage_key_mod_path = vec![ - Ident::new_with_override("core".into(), span.clone()), + Ident::new_with_override("std".into(), span.clone()), Ident::new_with_override("storage".into(), span.clone()), + Ident::new_with_override("storage_key".into(), span.clone()), ]; let storage_key_ident = Ident::new_with_override("StorageKey".into(), span.clone()); diff --git a/sway-core/src/semantic_analysis/namespace/namespace.rs b/sway-core/src/semantic_analysis/namespace/namespace.rs index ab6ad42a89f..df9e20d5f62 100644 --- a/sway-core/src/semantic_analysis/namespace/namespace.rs +++ b/sway-core/src/semantic_analysis/namespace/namespace.rs @@ -4,7 +4,7 @@ use super::{module::Module, root::Root, ModulePath, ModulePathBuf}; use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::{ - constants::{CONTRACT_ID, CORE, PRELUDE, STD}, + constants::{CONTRACT_ID, PRELUDE, STD}, span::Span, }; @@ -29,13 +29,13 @@ impl Namespace { /// Initialize the namespace /// See also the factory functions in contract_helpers.rs /// - /// If `import_preludes_into_root` is true then core::prelude::* and std::prelude::* will be - /// imported into the root module, provided core and std are available in the external modules. + /// If `import_prelude_into_root` is true then and std::prelude::* will be + /// imported into the root module, provided std is available in the external modules. pub fn new( handler: &Handler, engines: &Engines, package_root: Root, - import_preludes_into_root: bool, + import_prelude_into_root: bool, ) -> Result { let package_name = package_root.current_package_name().clone(); let mut res = Self { @@ -43,7 +43,7 @@ impl Namespace { current_mod_path: vec![package_name], }; - if import_preludes_into_root { + if import_prelude_into_root { res.import_implicits(handler, engines)?; } Ok(res) @@ -206,7 +206,7 @@ impl Namespace { } } - // Import core::prelude::*, std::prelude::* and ::CONTRACT_ID as appropriate into the current module + // Import std::prelude::* and ::CONTRACT_ID as appropriate into the current module fn import_implicits( &mut self, handler: &Handler, @@ -214,33 +214,12 @@ impl Namespace { ) -> Result<(), ErrorEmitted> { // Import preludes let package_name = self.current_package_name().to_string(); - let core_string = CORE.to_string(); - let core_ident = Ident::new_no_span(core_string.clone()); let prelude_ident = Ident::new_no_span(PRELUDE.to_string()); - if package_name == CORE { + + if package_name == STD { // Do nothing - } else if package_name == STD { - // Import core::prelude::* - assert!(self.root.exists_as_external(&core_string)); - self.root.star_import( - handler, - engines, - &[core_ident, prelude_ident], - &self.current_mod_path, - Visibility::Private, - )? } else { - // Import core::prelude::* and std::prelude::* - if self.root.exists_as_external(&core_string) { - self.root.star_import( - handler, - engines, - &[core_ident, prelude_ident.clone()], - &self.current_mod_path, - Visibility::Private, - )?; - } - + // Import std::prelude::* let std_string = STD.to_string(); // Only import std::prelude::* if std exists as a dependency if self.root.exists_as_external(&std_string) { diff --git a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs index 5615851fb60..a5a66d67316 100644 --- a/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs +++ b/sway-core/src/transform/to_parsed_lang/convert_parse_tree.rs @@ -2491,7 +2491,7 @@ fn expr_to_expression( assignable.clone(), )?; let rhs = Box::new(op_call( - op_variant.core_name(), + op_variant.std_name(), op_span, span.clone(), &vec![ @@ -2527,7 +2527,7 @@ fn op_call( inner: MethodName::FromTrait { call_path: CallPath { prefixes: vec![ - Ident::new_with_override("core".into(), op_span.clone()), + Ident::new_with_override("std".into(), op_span.clone()), Ident::new_with_override("ops".into(), op_span.clone()), ], suffix: Ident::new_with_override(name.into(), op_span.clone()), diff --git a/sway-lib-core/Forc.toml b/sway-lib-core/Forc.toml deleted file mode 100644 index 29ea1385066..00000000000 --- a/sway-lib-core/Forc.toml +++ /dev/null @@ -1,5 +0,0 @@ -[project] -authors = ["Fuel Labs "] -entry = "lib.sw" -license = "Apache-2.0" -name = "core" diff --git a/sway-lib-core/README.md b/sway-lib-core/README.md deleted file mode 100644 index af1caba31c1..00000000000 --- a/sway-lib-core/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# lib-core - -This Sway project contains core operators and extremely primitive logic for use in the standard library of the Sway programming language. - -## Usage - -To build this project, you must have installed [forc](https://crates.io/crates/forc). Once `forc` is installed, run `forc build` in the root of this project to build it. diff --git a/sway-lib-core/src/lib.sw b/sway-lib-core/src/lib.sw deleted file mode 100644 index 4437bdd85cb..00000000000 --- a/sway-lib-core/src/lib.sw +++ /dev/null @@ -1,13 +0,0 @@ -library; - -pub mod primitives; -pub mod raw_ptr; -pub mod raw_slice; -pub mod slice; -pub mod r#str; -pub mod ops; -pub mod primitive_conversions; -pub mod never; -pub mod r#storage; -pub mod prelude; -pub mod codec; diff --git a/sway-lib-core/src/prelude.sw b/sway-lib-core/src/prelude.sw deleted file mode 100644 index cdec0239241..00000000000 --- a/sway-lib-core/src/prelude.sw +++ /dev/null @@ -1,14 +0,0 @@ -library; - -//! Defines the Sway core library prelude. -//! The prelude consists of implicitly available items, -//! for which `use` is not required. -pub use ::primitives::*; -pub use ::primitive_conversions::*; -pub use ::raw_ptr::*; -pub use ::raw_slice::*; -pub use ::never::*; -pub use ::ops::*; -pub use ::storage::*; -pub use ::str::*; -pub use ::codec::*; diff --git a/sway-lib-core/src/primitive_conversions.sw b/sway-lib-core/src/primitive_conversions.sw deleted file mode 100644 index f0a1a14de81..00000000000 --- a/sway-lib-core/src/primitive_conversions.sw +++ /dev/null @@ -1,362 +0,0 @@ -library; - -impl u64 { - /// Extends a `u64` to a `u256`. - /// - /// # Returns - /// - /// * [u256] - The converted `u64` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2; - /// let result = val.as_u256(); - /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); - /// } - /// ``` - pub fn as_u256(self) -> u256 { - let input = (0u64, 0u64, 0u64, self); - asm(input: input) { - input: u256 - } - } -} - -impl u32 { - /// Extends a `u32` to a `u64`. - /// - /// # Returns - /// - /// * [u64] - The converted `u32` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 10u32; - /// let result = val.as_u64(); - /// assert(result == 10); - /// } - /// ``` - pub fn as_u64(self) -> u64 { - asm(input: self) { - input: u64 - } - } - - /// Extends a `u32` to a `u256`. - /// - /// # Returns - /// - /// * [u256] - The converted `u32` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2u32; - /// let result = val.as_u256(); - /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); - /// } - /// ``` - pub fn as_u256(self) -> u256 { - let input = (0u64, 0u64, 0u64, self.as_u64()); - asm(input: input) { - input: u256 - } - } -} - -impl u16 { - /// Extends a `u16` to a `u32`. - /// - /// # Returns - /// - /// * [u32] - The converted `u16` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 10u16; - /// let result = val.as_u32(); - /// assert(result == 10u32); - /// } - /// ``` - pub fn as_u32(self) -> u32 { - asm(input: self) { - input: u32 - } - } - - /// Extends a `u16` to a `u64`. - /// - /// # Returns - /// - /// * [u64] - The converted `u16` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 10u16; - /// let result = val.as_u64(); - /// assert(result == 10); - /// } - /// ``` - pub fn as_u64(self) -> u64 { - asm(input: self) { - input: u64 - } - } - - /// Extends a `u16` to a `u256`. - /// - /// # Returns - /// - /// * [u256] - The converted `u16` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2u16; - /// let result = val.as_u256(); - /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); - /// } - /// ``` - pub fn as_u256(self) -> u256 { - let input = (0u64, 0u64, 0u64, self.as_u64()); - asm(input: input) { - input: u256 - } - } -} - -impl u8 { - /// Extends a `u8` to a `u16`. - /// - /// # Returns - /// - /// * [u16] - The converted `u8` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2u8; - /// let result = val.as_u16(); - /// assert(result == 2u16); - /// } - /// ``` - pub fn as_u16(self) -> u16 { - asm(input: self) { - input: u16 - } - } - - /// Extends a `u8` to a `u32`. - /// - /// # Returns - /// - /// * [u32] - The converted `u8` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2u8; - /// let result = val.as_u32(); - /// assert(result == 2u32); - /// } - /// ``` - pub fn as_u32(self) -> u32 { - asm(input: self) { - input: u32 - } - } - - /// Extends a `u8` to a `u64`. - /// - /// # Returns - /// - /// * [u64] - The converted `u8` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2u8; - /// let result = val.as_u64(); - /// assert(result == 2); - /// } - /// ``` - pub fn as_u64(self) -> u64 { - asm(input: self) { - input: u64 - } - } - - /// Extends a `u8` to a `u256`. - /// - /// # Returns - /// - /// * [u256] - The converted `u8` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val = 2u8; - /// let result = val.as_u256(); - /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); - /// } - /// ``` - pub fn as_u256(self) -> u256 { - let input = (0u64, 0u64, 0u64, self.as_u64()); - asm(input: input) { - input: u256 - } - } -} - -impl b256 { - /// Converts a `b256` to a `u256`. - /// - /// # Returns - /// - /// * [u256] - The converted `b256` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val: b256 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20; - /// let result = val.as_u256(); - /// assert(result == 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20u256); - /// } - /// ``` - pub fn as_u256(self) -> u256 { - asm(input: self) { - input: u256 - } - } -} - -impl u256 { - /// Converts a `u256` to a `b256`. - /// - /// # Returns - /// - /// * [b256] - The converted `u256` value. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let val: u256 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20u256; - /// let result = val.as_b256(); - /// assert(result == 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20); - /// } - /// ``` - pub fn as_b256(self) -> b256 { - asm(input: self) { - input: b256 - } - } -} - -fn assert(condition: bool) { - if !condition { - __revert(0) - } -} - -#[test] -fn test_u64_as_u256() { - let val = 2; - let result = val.as_u256(); - assert( - result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, - ); -} - -#[test] -fn test_u32_as_u64() { - let val = 2u32; - let result = val.as_u64(); - assert(result == 2); -} - -#[test] -fn test_u32_as_u256() { - let val = 2u32; - let result = val.as_u256(); - assert( - result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, - ); -} - -#[test] -fn test_u16_as_u64() { - let val = 2u16; - let result = val.as_u64(); - assert(result == 2); -} - -#[test] -fn test_u16_as_u32() { - let val = 2u16; - let result = val.as_u32(); - assert(result == 2u32); -} - -#[test] -fn test_u16_as_u256() { - let val = 2u16; - let result = val.as_u256(); - assert( - result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, - ); -} - -#[test] -fn test_u8_as_u64() { - let val = 2u8; - let result = val.as_u64(); - assert(result == 2); -} - -#[test] -fn test_u8_as_u32() { - let val = 2u8; - let result = val.as_u32(); - assert(result == 2u32); -} - -#[test] -fn test_u8_as_u16() { - let val = 2u8; - let result = val.as_u16(); - assert(result == 2u16); -} - -#[test] -fn test_u8_as_u256() { - let val = 2u8; - let result = val.as_u256(); - assert( - result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, - ); -} - -#[test] -fn test_b256_as_u256() { - let val = 0x0000000000000000000000000000000000000000000000000000000000000002; - let result = val.as_u256(); - assert( - result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, - ); -} diff --git a/sway-lib-core/src/storage.sw b/sway-lib-core/src/storage.sw deleted file mode 100644 index ed0eb8edecf..00000000000 --- a/sway-lib-core/src/storage.sw +++ /dev/null @@ -1,118 +0,0 @@ -library; - -/// Describes a location in storage. -/// -/// # Additional Information -/// -/// The location in storage is specified by the `b256` key of a particular storage slot and an -/// offset, in words, from the start of the storage slot at `key`. The parameter `T` is the type of -/// the data to be read from or written to at `offset`. -/// `field_id` is a unique identifier for the storage field being referred to, it is different even -/// for multiple zero sized fields that might live at the same location but -/// represent different storage constructs. -pub struct StorageKey { - /// The assigned location in storage. - slot: b256, - /// The assigned offset based on the data structure `T`. - offset: u64, - /// A unique identifier. - field_id: b256, -} - -impl StorageKey { - /// Create a new `StorageKey`. - /// - /// # Arguments - /// - /// * `slot`: [b256] - The assigned location in storage for the new `StorageKey`. - /// * `offset`: [u64] - The assigned offset based on the data structure `T` for the new `StorageKey`. - /// * `field_id`: [b256] - A unique identifier for the new `StorageKey`. - /// - /// # Returns - /// - /// * [StorageKey] - The newly created `StorageKey`. - /// - /// # Examples - /// - /// ```sway - /// use std::hash::sha256; - /// - /// fn foo() { - /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); - /// assert(my_key.slot() == b256::zero()); - /// } - /// ``` - pub fn new(slot: b256, offset: u64, field_id: b256) -> Self { - Self { - slot, - offset, - field_id, - } - } - - /// Returns the storage slot address. - /// - /// # Returns - /// - /// * [b256] - The address in storage that this storage slot points to. - /// - /// # Examples - /// - /// ```sway - /// use std::hash::sha256; - /// - /// fn foo() { - /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); - /// assert(my_key.slot() == b256::zero()); - /// } - /// ``` - pub fn slot(self) -> b256 { - self.slot - } - - /// Returns the offset on the storage slot. - /// - /// # Returns - /// - /// * [u64] - The offset in storage that this storage slot points to. - /// - /// # Examples - /// - /// ```sway - /// use std::hash::sha256; - /// - /// fn foo() { - /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); - /// assert(my_key.offset() == 0); - /// } - /// ``` - pub fn offset(self) -> u64 { - self.offset - } - - /// Returns the storage slot field id. - /// - /// # Additional Information - /// - /// The field id is a unique identifier for the storage field being referred to, it is different even - /// for multiple zero sized fields that might live at the same location but - /// represent different storage constructs. - /// - /// # Returns - /// - /// * [b256] - The field id for this storage slot. - /// - /// # Examples - /// - /// ```sway - /// use std::hash::sha256; - /// - /// fn foo() { - /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); - /// assert(my_key.field_id() == sha256(b256::zero())); - /// } - /// ``` - pub fn field_id(self) -> b256 { - self.field_id - } -} diff --git a/sway-lib-std/Forc.toml b/sway-lib-std/Forc.toml index 2082ccb3b1d..c080d3870cc 100644 --- a/sway-lib-std/Forc.toml +++ b/sway-lib-std/Forc.toml @@ -5,4 +5,3 @@ license = "Apache-2.0" name = "std" [dependencies] -core = { path = "../sway-lib-core" } diff --git a/sway-lib-core/generate.sh b/sway-lib-std/generate.sh similarity index 100% rename from sway-lib-core/generate.sh rename to sway-lib-std/generate.sh diff --git a/sway-lib-std/src/address.sw b/sway-lib-std/src/address.sw index 3a55037b51d..baff920229f 100644 --- a/sway-lib-std/src/address.sw +++ b/sway-lib-std/src/address.sw @@ -3,6 +3,8 @@ library; use ::convert::{From, Into, TryFrom}; use ::hash::{Hash, Hasher}; +use ::ops::Eq; +use ::primitives::*; use ::bytes::Bytes; use ::option::Option::{self, *}; @@ -70,7 +72,7 @@ impl Address { } } -impl core::ops::Eq for Address { +impl Eq for Address { fn eq(self, other: Self) -> bool { self.bits == other.bits } diff --git a/sway-lib-std/src/alloc.sw b/sway-lib-std/src/alloc.sw index bd3dd7cc095..62bccb902ed 100644 --- a/sway-lib-std/src/alloc.sw +++ b/sway-lib-std/src/alloc.sw @@ -1,6 +1,9 @@ //! A library for allocating memory inspired by [Rust's std::alloc](https://doc.rust-lang.org/std/alloc/index.html). library; +use ::ops::*; +use ::raw_ptr::*; + /// Allocates zeroed memory on the heap. /// /// # Additional Information diff --git a/sway-lib-std/src/assert.sw b/sway-lib-std/src/assert.sw index a3bb6e3e7f1..b42e315d508 100644 --- a/sway-lib-std/src/assert.sw +++ b/sway-lib-std/src/assert.sw @@ -4,6 +4,9 @@ library; use ::logging::log; use ::revert::revert; use ::error_signals::{FAILED_ASSERT_EQ_SIGNAL, FAILED_ASSERT_NE_SIGNAL, FAILED_ASSERT_SIGNAL}; +use ::codec::AbiEncode; +use ::ops::*; +use ::never::*; /// Asserts that the given `condition` will always be `true` during runtime. /// diff --git a/sway-lib-std/src/asset_id.sw b/sway-lib-std/src/asset_id.sw index 4cd2b8feae6..25e361ba204 100644 --- a/sway-lib-std/src/asset_id.sw +++ b/sway-lib-std/src/asset_id.sw @@ -5,6 +5,8 @@ use ::alias::SubId; use ::contract_id::ContractId; use ::convert::{From, Into, TryFrom}; use ::hash::{Hash, Hasher}; +use ::ops::Eq; +use ::primitives::*; use ::bytes::Bytes; use ::option::Option::{self, *}; @@ -29,7 +31,7 @@ impl Hash for AssetId { } } -impl core::ops::Eq for AssetId { +impl Eq for AssetId { fn eq(self, other: Self) -> bool { self.bits == other.bits } @@ -83,7 +85,7 @@ impl AssetId { /// } /// ``` pub fn new(contract_id: ContractId, sub_id: SubId) -> Self { - let result_buffer = 0x0000000000000000000000000000000000000000000000000000000000000000; + let result_buffer = b256::zero(); asm( asset_id: result_buffer, ptr: (contract_id, sub_id), @@ -122,13 +124,10 @@ impl AssetId { let contract_id = asm() { fp: b256 }; - let result_buffer = 0x0000000000000000000000000000000000000000000000000000000000000000; + let result_buffer = b256::zero(); asm( asset_id: result_buffer, - ptr: ( - contract_id, - 0x0000000000000000000000000000000000000000000000000000000000000000, - ), + ptr: (contract_id, b256::zero()), bytes: 64, ) { s256 asset_id ptr bytes; diff --git a/sway-lib-std/src/b512.sw b/sway-lib-std/src/b512.sw index a6673741c5a..8958529d5d2 100644 --- a/sway-lib-std/src/b512.sw +++ b/sway-lib-std/src/b512.sw @@ -1,9 +1,12 @@ //! The `B512` type supports the usage of 64-byte values in Sway which are needed when working with public keys and signatures. library; +use ::ops::*; +use ::primitives::*; use ::convert::{From, Into, TryFrom}; use ::bytes::Bytes; use ::option::Option::{self, *}; +use ::raw_slice::*; /// Stores two `b256`s in contiguous memory. /// Guaranteed to be contiguous for use with ec-recover: `std::ecr::ec_recover`. @@ -12,7 +15,7 @@ pub struct B512 { bits: [b256; 2], } -impl core::ops::Eq for B512 { +impl Eq for B512 { fn eq(self, other: Self) -> bool { (self.bits)[0] == (other.bits)[0] && (self.bits)[1] == (other.bits)[1] } diff --git a/sway-lib-std/src/block.sw b/sway-lib-std/src/block.sw index dc9e597962e..8d57e631652 100644 --- a/sway-lib-std/src/block.sw +++ b/sway-lib-std/src/block.sw @@ -4,6 +4,8 @@ library; use ::assert::assert; use ::result::Result::{self, *}; use ::logging::log; +use ::primitives::*; +use ::ops::*; /// Error type for when the block hash cannot be found. pub enum BlockHashError { diff --git a/sway-lib-std/src/bytes.sw b/sway-lib-std/src/bytes.sw index 76075df80ce..d2918e3c0fc 100644 --- a/sway-lib-std/src/bytes.sw +++ b/sway-lib-std/src/bytes.sw @@ -7,6 +7,9 @@ use ::intrinsics::size_of_val; use ::option::Option::{self, *}; use ::convert::{From, Into, *}; use ::clone::Clone; +use ::codec::*; +use ::raw_slice::*; +use ::ops::*; struct RawBytes { ptr: raw_ptr, @@ -873,7 +876,7 @@ impl Bytes { } } -impl core::ops::Eq for Bytes { +impl Eq for Bytes { fn eq(self, other: Self) -> bool { if self.len != other.len { return false; diff --git a/sway-lib-std/src/call_frames.sw b/sway-lib-std/src/call_frames.sw index 21b009659c3..fad2673e391 100644 --- a/sway-lib-std/src/call_frames.sw +++ b/sway-lib-std/src/call_frames.sw @@ -6,6 +6,8 @@ use ::asset_id::AssetId; use ::contract_id::ContractId; use ::intrinsics::is_reference_type; use ::registers::frame_ptr; +use ::raw_ptr::*; +use ::codec::*; // Note that everything when serialized is padded to word length. // @@ -122,7 +124,7 @@ pub fn second_param() -> u64 { /// Get the called method name from the current call frame. pub fn called_method() -> str { - use core::codec::decode_first_param; + use ::codec::decode_first_param; decode_first_param::() } @@ -131,7 +133,7 @@ pub fn called_args() -> T where T: AbiDecode, { - use core::codec::decode_second_param; + use ::codec::decode_second_param; decode_second_param::() } diff --git a/sway-lib-core/src/codec.sw b/sway-lib-std/src/codec.sw similarity index 99% rename from sway-lib-core/src/codec.sw rename to sway-lib-std/src/codec.sw index 913da976a0c..5eb70e86fb2 100644 --- a/sway-lib-core/src/codec.sw +++ b/sway-lib-std/src/codec.sw @@ -2557,22 +2557,32 @@ impl AbiDecode for u64 { } } +pub fn as_u16(input: u8) -> u16 { + asm(input: input) { + input: u16 + } +} + +pub fn as_u32(input: u8) -> u32 { + asm(input: input) { + input: u32 + } +} + impl AbiDecode for u32 { fn abi_decode(ref mut buffer: BufferReader) -> u32 { - use ::primitive_conversions::*; - let a = buffer.read::().as_u32(); - let b = buffer.read::().as_u32(); - let c = buffer.read::().as_u32(); - let d = buffer.read::().as_u32(); + let a = as_u32(buffer.read::()); + let b = as_u32(buffer.read::()); + let c = as_u32(buffer.read::()); + let d = as_u32(buffer.read::()); (a << 24) | (b << 16) | (c << 8) | d } } impl AbiDecode for u16 { fn abi_decode(ref mut buffer: BufferReader) -> u16 { - use ::primitive_conversions::*; - let a = buffer.read::().as_u16(); - let b = buffer.read::().as_u16(); + let a = as_u16(buffer.read::()); + let b = as_u16(buffer.read::()); (a << 8) | b } } diff --git a/sway-lib-std/src/constants.sw b/sway-lib-std/src/constants.sw index 68cecbfb965..308ab9a85c4 100644 --- a/sway-lib-std/src/constants.sw +++ b/sway-lib-std/src/constants.sw @@ -1,6 +1,8 @@ //! Definitions for constant values in Sway. library; +use ::primitives::*; + /// A b256 of zero value. /// /// # Additional Information diff --git a/sway-lib-std/src/contract_id.sw b/sway-lib-std/src/contract_id.sw index 2763fa92a82..899969bfc93 100644 --- a/sway-lib-std/src/contract_id.sw +++ b/sway-lib-std/src/contract_id.sw @@ -3,6 +3,9 @@ library; use ::convert::{From, Into, TryFrom}; use ::hash::{Hash, Hasher}; +use ::ops::Eq; +use ::primitives::*; +use ::codec::*; use ::bytes::Bytes; use ::option::Option::{self, *}; @@ -32,7 +35,7 @@ impl ContractId { } } -impl core::ops::Eq for ContractId { +impl Eq for ContractId { fn eq(self, other: Self) -> bool { self.bits == other.bits } @@ -212,3 +215,9 @@ impl ContractId { self.bits == b256::zero() } } + +impl AbiEncode for ContractId { + fn abi_encode(self, buffer: Buffer) -> Buffer { + self.bits.abi_encode(buffer) + } +} diff --git a/sway-lib-std/src/crypto/ed25519.sw b/sway-lib-std/src/crypto/ed25519.sw index c8c57c5538c..5ae77a4684b 100644 --- a/sway-lib-std/src/crypto/ed25519.sw +++ b/sway-lib-std/src/crypto/ed25519.sw @@ -8,6 +8,7 @@ use ::crypto::{message::Message, public_key::PublicKey, signature_error::Signatu use ::hash::*; use ::result::Result::{self, *}; use ::option::Option::{self, *}; +use ::ops::Eq; /// An ed25519 signature. pub struct Ed25519 { @@ -189,7 +190,7 @@ impl Into for Ed25519 { } } -impl core::ops::Eq for Ed25519 { +impl Eq for Ed25519 { fn eq(self, other: Self) -> bool { let mut iter = 0; while iter < 64 { diff --git a/sway-lib-std/src/crypto/message.sw b/sway-lib-std/src/crypto/message.sw index 811051c02fa..ae319682fed 100644 --- a/sway-lib-std/src/crypto/message.sw +++ b/sway-lib-std/src/crypto/message.sw @@ -6,6 +6,7 @@ use ::alloc::alloc_bytes; use ::convert::{From, TryFrom, TryInto}; use ::option::Option::{self, *}; use ::hash::*; +use ::ops::Eq; /// Normalized (hashed) message authenticated by a signature. pub struct Message { @@ -83,7 +84,7 @@ impl TryInto for Message { } } -impl core::ops::Eq for Message { +impl Eq for Message { fn eq(self, other: Self) -> bool { if self.bytes.len() != other.bytes.len() { return false; diff --git a/sway-lib-std/src/crypto/public_key.sw b/sway-lib-std/src/crypto/public_key.sw index b940395ebf0..6e58a00393e 100644 --- a/sway-lib-std/src/crypto/public_key.sw +++ b/sway-lib-std/src/crypto/public_key.sw @@ -7,6 +7,7 @@ use ::constants::ZERO_B256; use ::convert::{From, TryFrom, TryInto}; use ::option::Option::{self, *}; use ::hash::*; +use ::ops::Eq; /// Asymmetric public key, i.e. verifying key, in uncompressed form. /// @@ -172,7 +173,7 @@ impl TryInto for PublicKey { } } -impl core::ops::Eq for PublicKey { +impl Eq for PublicKey { fn eq(self, other: Self) -> bool { if self.bytes.len() != other.bytes.len() { return false; diff --git a/sway-lib-std/src/crypto/secp256k1.sw b/sway-lib-std/src/crypto/secp256k1.sw index 2249df6ecad..b1340f25681 100644 --- a/sway-lib-std/src/crypto/secp256k1.sw +++ b/sway-lib-std/src/crypto/secp256k1.sw @@ -11,7 +11,7 @@ use ::registers::error; use ::result::Result::{self, *}; use ::option::Option::{self, *}; use ::vm::evm::evm_address::EvmAddress; - +use ::ops::Eq; /// A secp256k1 signature. pub struct Secp256k1 { /// The underlying raw `[u8; 64]` data of the signature. @@ -424,7 +424,7 @@ impl Into for Secp256k1 { } } -impl core::ops::Eq for Secp256k1 { +impl Eq for Secp256k1 { fn eq(self, other: Self) -> bool { let mut iter = 0; while iter < 64 { diff --git a/sway-lib-std/src/crypto/secp256r1.sw b/sway-lib-std/src/crypto/secp256r1.sw index 560e8558f87..0e5194b2bed 100644 --- a/sway-lib-std/src/crypto/secp256r1.sw +++ b/sway-lib-std/src/crypto/secp256r1.sw @@ -11,7 +11,7 @@ use ::registers::error; use ::result::Result::{self, *}; use ::option::Option::{self, *}; use ::vm::evm::evm_address::EvmAddress; - +use ::ops::Eq; /// A secp256r1 signature. pub struct Secp256r1 { /// The underlying raw `[u8; 64]` data of the signature. @@ -425,7 +425,7 @@ impl Into for Secp256r1 { } } -impl core::ops::Eq for Secp256r1 { +impl Eq for Secp256r1 { fn eq(self, other: Self) -> bool { let mut iter = 0; while iter < 64 { diff --git a/sway-lib-std/src/flags.sw b/sway-lib-std/src/flags.sw index 956f5024218..3958291930c 100644 --- a/sway-lib-std/src/flags.sw +++ b/sway-lib-std/src/flags.sw @@ -1,7 +1,7 @@ //! Functionality for setting and unsetting FuelVM flags to modify behavior related to the `$err` and `$of` registers. library; -use ::{assert::assert, logging::log, registers::{error, flags}}; +use ::registers::flags; // Mask second bit, which is `F_WRAPPING`. pub const F_WRAPPING_DISABLE_MASK: u64 = 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000010; @@ -82,7 +82,7 @@ pub fn disable_panic_on_overflow() -> u64 { // Get the current value of the flags register and mask it, setting the // masked bit. Flags are inverted, so set = off. - let flag_val = prior_flags | F_WRAPPING_DISABLE_MASK; + let flag_val = __or(prior_flags, F_WRAPPING_DISABLE_MASK); asm(flag_val: flag_val) { flag flag_val; } @@ -115,7 +115,7 @@ pub fn disable_panic_on_overflow() -> u64 { pub fn enable_panic_on_overflow() { // Get the current value of the flags register and mask it, unsetting the // masked bit. Flags are inverted, so unset = on. - let flag_val = flags() & F_WRAPPING_ENABLE_MASK; + let flag_val = __and(flags(), F_WRAPPING_ENABLE_MASK); asm(flag_val: flag_val) { flag flag_val; } @@ -170,7 +170,7 @@ pub fn disable_panic_on_unsafe_math() -> u64 { // Get the current value of the flags register and mask it, setting the // masked bit. Flags are inverted, so set = off. - let flag_val = prior_flags | F_UNSAFEMATH_DISABLE_MASK; + let flag_val = __or(prior_flags, F_UNSAFEMATH_DISABLE_MASK); asm(flag_val: flag_val) { flag flag_val; } @@ -205,7 +205,7 @@ pub fn disable_panic_on_unsafe_math() -> u64 { pub fn enable_panic_on_unsafe_math() { // Get the current value of the flags register and mask it, unsetting the // masked bit. Flags are inverted, so unset = on. - let flag_val = flags() & F_UNSAFEMATH_ENABLE_MASK; + let flag_val = __and(flags(), F_UNSAFEMATH_ENABLE_MASK); asm(flag_val: flag_val) { flag flag_val; } @@ -229,7 +229,7 @@ pub fn enable_panic_on_unsafe_math() { /// } /// ``` pub fn panic_on_overflow_enabled() -> bool { - (flags() & F_WRAPPING_DISABLE_MASK) == 0 + __eq(__and(flags(), F_WRAPPING_DISABLE_MASK), 0) } /// Checks if the `panic-on-unsafe-math` flag is set in the FuelVM. @@ -250,5 +250,5 @@ pub fn panic_on_overflow_enabled() -> bool { /// } /// ``` pub fn panic_on_unsafe_math_enabled() -> bool { - (flags() & F_UNSAFEMATH_DISABLE_MASK) == 0 + __eq(__and(flags(), F_UNSAFEMATH_DISABLE_MASK), 0) } diff --git a/sway-lib-std/src/identity.sw b/sway-lib-std/src/identity.sw index 7c3b06bf5e9..c9fdcf24538 100644 --- a/sway-lib-std/src/identity.sw +++ b/sway-lib-std/src/identity.sw @@ -2,7 +2,7 @@ //! The use of this type allows for handling interactions with contracts and addresses in a unified manner. library; -use core::codec::*; +use ::codec::*; use ::assert::assert; use ::address::Address; use ::alias::SubId; @@ -10,6 +10,7 @@ use ::asset_id::AssetId; use ::contract_id::ContractId; use ::hash::{Hash, Hasher}; use ::option::Option::{self, *}; +use ::ops::Eq; /// The `Identity` type: either an `Address` or a `ContractId`. // ANCHOR: docs_identity @@ -19,7 +20,7 @@ pub enum Identity { } // ANCHOR_END: docs_identity -impl core::ops::Eq for Identity { +impl Eq for Identity { fn eq(self, other: Self) -> bool { match (self, other) { (Identity::Address(addr1), Identity::Address(addr2)) => addr1 == addr2, diff --git a/sway-lib-std/src/inputs.sw b/sway-lib-std/src/inputs.sw index f4db2869bb2..146d171b247 100644 --- a/sway-lib-std/src/inputs.sw +++ b/sway-lib-std/src/inputs.sw @@ -17,8 +17,11 @@ use ::tx::{ Transaction, tx_type, }; -use core::ops::Eq; +use ::ops::Eq; use ::revert::revert; +use ::primitive_conversions::u16::*; +use ::codec::*; +use ::raw_slice::*; // GTF Opcode const selectors pub const GTF_INPUT_TYPE = 0x200; @@ -281,8 +284,8 @@ where T: AbiDecode, { match input_type(index) { - Some(Input::Coin) => Some(core::codec::decode_predicate_data_by_index::(index)), - Some(Input::Message) => Some(core::codec::decode_predicate_data_by_index::(index)), + Some(Input::Coin) => Some(decode_predicate_data_by_index::(index)), + Some(Input::Message) => Some(decode_predicate_data_by_index::(index)), _ => None, } } diff --git a/sway-lib-std/src/lib.sw b/sway-lib-std/src/lib.sw index fee5ce151cf..b7a090d9b74 100644 --- a/sway-lib-std/src/lib.sw +++ b/sway-lib-std/src/lib.sw @@ -1,24 +1,32 @@ library; +pub mod registers; +pub mod flags; +pub mod r#str; +pub mod primitives; +pub mod ops; +pub mod raw_ptr; +pub mod raw_slice; +pub mod codec; +pub mod slice; pub mod constants; pub mod error_signals; pub mod logging; pub mod revert; -pub mod result; -pub mod option; pub mod assert; pub mod convert; pub mod intrinsics; -pub mod alloc; -pub mod registers; pub mod iterator; pub mod vec; pub mod bytes; -pub mod flags; -pub mod math; -pub mod u128; +pub mod alloc; +pub mod result; +pub mod option; +pub mod never; pub mod b512; +pub mod u128; pub mod primitive_conversions; +pub mod math; pub mod alias; pub mod hash; pub mod asset_id; diff --git a/sway-lib-std/src/logging.sw b/sway-lib-std/src/logging.sw index 900e6f1045e..a115537919e 100644 --- a/sway-lib-std/src/logging.sw +++ b/sway-lib-std/src/logging.sw @@ -1,6 +1,8 @@ //! Allows logging of arbitrary stack types, emitted as either `Log` or `Logd` receipts. library; +use ::codec::*; + /// Log any stack type. /// /// # Additional Information diff --git a/sway-lib-std/src/low_level_call.sw b/sway-lib-std/src/low_level_call.sw index 7ae93606f99..5102c5244a5 100644 --- a/sway-lib-std/src/low_level_call.sw +++ b/sway-lib-std/src/low_level_call.sw @@ -6,6 +6,7 @@ use ::assert::assert; use ::asset_id::AssetId; use ::bytes::Bytes; use ::contract_id::ContractId; +use ::codec::*; use ::option::Option; use ::revert::require; use ::vec::Vec; diff --git a/sway-lib-std/src/math.sw b/sway-lib-std/src/math.sw index 6ffd4071865..2e7a51386f5 100644 --- a/sway-lib-std/src/math.sw +++ b/sway-lib-std/src/math.sw @@ -11,6 +11,7 @@ use ::flags::{ set_flags, }; use ::registers::{flags, overflow}; +use ::primitive_conversions::{u16::*, u256::*, u32::*, u64::*, u8::*}; /// Calculates the square root. pub trait Root { @@ -393,123 +394,3 @@ impl Logarithm for u256 { result } } - -impl u8 { - /// Returns whether a `u8` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `u8` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let zero_u8 = u8::zero(); - /// assert(zero_u8.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self == 0u8 - } -} - -impl u16 { - /// Returns whether a `u16` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `u16` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let zero_u16 = u16::zero(); - /// assert(zero_u16.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self == 0u16 - } -} - -impl u32 { - /// Returns whether a `u32` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `u32` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let zero_u32 = u32::zero(); - /// assert(zero_u32.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self == 0u32 - } -} - -impl u64 { - /// Returns whether a `u64` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `u64` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let zero_u64 = u64::zero(); - /// assert(zero_u64.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self == 0u64 - } -} - -impl u256 { - /// Returns whether a `u256` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `u256` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let zero_u256 = u256::zero(); - /// assert(zero_u256.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self == 0x00u256 - } -} - -impl b256 { - /// Returns whether a `b256` is set to zero. - /// - /// # Returns - /// - /// * [bool] -> True if the `b256` is zero, otherwise false. - /// - /// # Examples - /// - /// ```sway - /// fn foo() { - /// let zero_b256 = b256::zero(); - /// assert(zero_b256.is_zero()); - /// } - /// ``` - pub fn is_zero(self) -> bool { - self == 0x0000000000000000000000000000000000000000000000000000000000000000 - } -} diff --git a/sway-lib-std/src/message.sw b/sway-lib-std/src/message.sw index 0d70bcac129..28b5db9e72f 100644 --- a/sway-lib-std/src/message.sw +++ b/sway-lib-std/src/message.sw @@ -5,6 +5,7 @@ use ::alloc::alloc_bytes; use ::bytes::Bytes; use ::outputs::{Output, output_count, output_type}; use ::revert::revert; +use ::ops::*; /// Sends a message `msg_data` to `recipient` with a `coins` amount of the base asset. /// diff --git a/sway-lib-core/src/never.sw b/sway-lib-std/src/never.sw similarity index 100% rename from sway-lib-core/src/never.sw rename to sway-lib-std/src/never.sw diff --git a/sway-lib-core/src/ops.sw b/sway-lib-std/src/ops.sw similarity index 91% rename from sway-lib-core/src/ops.sw rename to sway-lib-std/src/ops.sw index c49147bccae..250f32747e6 100644 --- a/sway-lib-core/src/ops.sw +++ b/sway-lib-std/src/ops.sw @@ -1,7 +1,8 @@ library; use ::primitives::*; -use ::slice::*; +use ::registers::flags; +use ::flags::panic_on_overflow_enabled; /// Trait for the addition of two values. pub trait Add { @@ -61,7 +62,7 @@ impl Add for u32 { let res = __add(self, other); // integer overflow if __gt(res, Self::max()) { - if panic_on_overflow_is_enabled() { + if panic_on_overflow_enabled() { __revert(0) } else { // overflow enabled @@ -79,7 +80,7 @@ impl Add for u16 { fn add(self, other: Self) -> Self { let res = __add(self, other); if __gt(res, Self::max()) { - if panic_on_overflow_is_enabled() { + if panic_on_overflow_enabled() { __revert(0) } else { // overflow enabled @@ -105,7 +106,7 @@ impl Add for u8 { input: u64 }; if __gt(res_u64, max_u8_u64) { - if panic_on_overflow_is_enabled() { + if panic_on_overflow_enabled() { __revert(0) } else { // overflow enabled @@ -250,7 +251,7 @@ impl Multiply for u32 { // constants (like Self::max() below) are also automatically promoted to u64 let res = __mul(self, other); if __gt(res, Self::max()) { - if panic_on_overflow_is_enabled() { + if panic_on_overflow_enabled() { // integer overflow __revert(0) } else { @@ -269,7 +270,7 @@ impl Multiply for u16 { fn multiply(self, other: Self) -> Self { let res = __mul(self, other); if __gt(res, Self::max()) { - if panic_on_overflow_is_enabled() { + if panic_on_overflow_enabled() { __revert(0) } else { __mod(res, __add(Self::max(), 1)) @@ -293,7 +294,7 @@ impl Multiply for u8 { input: u64 }; if __gt(res_u64, max_u8_u64) { - if panic_on_overflow_is_enabled() { + if panic_on_overflow_enabled() { __revert(0) } else { // overflow enabled @@ -1399,34 +1400,122 @@ impl Eq for str { } } -fn assert(v: bool) { - if !v { - __revert(0) +impl u8 { + /// Returns whether a `u8` is set to zero. + /// + /// # Returns + /// + /// * [bool] -> True if the `u8` is zero, otherwise false. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let zero_u8 = u8::zero(); + /// assert(zero_u8.is_zero()); + /// } + /// ``` + pub fn is_zero(self) -> bool { + self == 0u8 } } -#[test] -pub fn ok_str_eq() { - assert("" == ""); - assert("a" == "a"); +impl u16 { + /// Returns whether a `u16` is set to zero. + /// + /// # Returns + /// + /// * [bool] -> True if the `u16` is zero, otherwise false. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let zero_u16 = u16::zero(); + /// assert(zero_u16.is_zero()); + /// } + /// ``` + pub fn is_zero(self) -> bool { + self == 0u16 + } +} - assert("a" != ""); - assert("" != "a"); - assert("a" != "b"); +impl u32 { + /// Returns whether a `u32` is set to zero. + /// + /// # Returns + /// + /// * [bool] -> True if the `u32` is zero, otherwise false. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let zero_u32 = u32::zero(); + /// assert(zero_u32.is_zero()); + /// } + /// ``` + pub fn is_zero(self) -> bool { + self == 0u32 + } } -fn flags() -> u64 { - asm() { - flag +impl u64 { + /// Returns whether a `u64` is set to zero. + /// + /// # Returns + /// + /// * [bool] -> True if the `u64` is zero, otherwise false. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let zero_u64 = u64::zero(); + /// assert(zero_u64.is_zero()); + /// } + /// ``` + pub fn is_zero(self) -> bool { + self == 0u64 + } +} + +impl u256 { + /// Returns whether a `u256` is set to zero. + /// + /// # Returns + /// + /// * [bool] -> True if the `u256` is zero, otherwise false. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let zero_u256 = u256::zero(); + /// assert(zero_u256.is_zero()); + /// } + /// ``` + pub fn is_zero(self) -> bool { + self == 0x00u256 } } -fn panic_on_overflow_is_enabled() -> bool { - __eq( - __and( - flags(), - 0b00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000010, - ), - 0, - ) +impl b256 { + /// Returns whether a `b256` is set to zero. + /// + /// # Returns + /// + /// * [bool] -> True if the `b256` is zero, otherwise false. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let zero_b256 = b256::zero(); + /// assert(zero_b256.is_zero()); + /// } + /// ``` + pub fn is_zero(self) -> bool { + self == 0x0000000000000000000000000000000000000000000000000000000000000000 + } } diff --git a/sway-lib-std/src/option.sw b/sway-lib-std/src/option.sw index 882879cd3b6..db132bab6a9 100644 --- a/sway-lib-std/src/option.sw +++ b/sway-lib-std/src/option.sw @@ -77,6 +77,8 @@ library; use ::logging::log; use ::result::Result; use ::revert::revert; +use ::codec::AbiEncode; +use ::ops::*; // ANCHOR: docs_option /// A type that represents an optional value, either `Some(val)` or `None`. @@ -88,7 +90,7 @@ pub enum Option { } // ANCHOR_END: docs_option -impl core::ops::Eq for Option +impl Eq for Option where T: Eq, { diff --git a/sway-lib-std/src/outputs.sw b/sway-lib-std/src/outputs.sw index 527a94de2fc..754c8444b07 100644 --- a/sway-lib-std/src/outputs.sw +++ b/sway-lib-std/src/outputs.sw @@ -15,6 +15,9 @@ use ::tx::{ tx_type, }; use ::option::Option::{self, *}; +use ::ops::*; +use ::primitive_conversions::u16::*; +use ::raw_ptr::*; // GTF Opcode const selectors // @@ -275,7 +278,7 @@ pub fn output_asset_to(index: u64) -> Option
{ } } -impl core::ops::Eq for Output { +impl Eq for Output { fn eq(self, other: Self) -> bool { match (self, other) { (Output::Coin, Output::Coin) => true, diff --git a/sway-lib-std/src/prelude.sw b/sway-lib-std/src/prelude.sw index f422ba0f41b..ad6d6c73f17 100644 --- a/sway-lib-std/src/prelude.sw +++ b/sway-lib-std/src/prelude.sw @@ -38,3 +38,13 @@ pub use ::auth::msg_sender; // Math pub use ::math::*; + +// (Previously) core +pub use ::primitives::*; +pub use ::slice::*; +pub use ::ops::*; +pub use ::never::*; +pub use ::raw_ptr::*; +pub use ::raw_slice::*; +pub use ::codec::*; +pub use ::str::*; diff --git a/sway-lib-std/src/primitive_conversions/b256.sw b/sway-lib-std/src/primitive_conversions/b256.sw index 266bba0c9d8..3662019b0d5 100644 --- a/sway-lib-std/src/primitive_conversions/b256.sw +++ b/sway-lib-std/src/primitive_conversions/b256.sw @@ -3,9 +3,31 @@ library; use ::bytes::Bytes; use ::convert::{From, TryFrom}; use ::option::Option::{self, *}; -use ::u128::U128; use ::b512::B512; +impl b256 { + /// Converts a `b256` to a `u256`. + /// + /// # Returns + /// + /// * [u256] - The converted `b256` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val: b256 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20; + /// let result = val.as_u256(); + /// assert(result == 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20u256); + /// } + /// ``` + pub fn as_u256(self) -> u256 { + asm(input: self) { + input: u256 + } + } +} + impl TryFrom for b256 { fn try_from(b: Bytes) -> Option { if b.len() != 32 { @@ -70,34 +92,7 @@ impl From for b256 { /// } /// ``` fn from(num: u256) -> Self { - num.as_b256() - } -} - -impl From for b256 { - /// Converts a `U128` to a `b256`. - /// - /// # Arguments - /// - /// * `num`: [U128] - The `U128` to be converted. - /// - /// # Returns - /// - /// * [b256] - The `b256` representation of the `U128` value. - /// - /// # Examples - /// - /// ```sway - /// use std::u128::U128; - /// - /// fn foo() { - /// let u128_value = U128::from((18446744073709551615_u64, 18446744073709551615_u64)); - /// let b256_value = b256::from(u128_value); - /// } - /// ``` - fn from(num: U128) -> Self { - let input = (0u64, 0u64, num.upper(), num.lower()); - asm(input: input) { + asm(input: num) { input: b256 } } diff --git a/sway-lib-std/src/primitive_conversions/str.sw b/sway-lib-std/src/primitive_conversions/str.sw index 4ace1dd03a6..c2485b07446 100644 --- a/sway-lib-std/src/primitive_conversions/str.sw +++ b/sway-lib-std/src/primitive_conversions/str.sw @@ -1,6 +1,8 @@ library; use ::option::Option::{self, *}; +use ::str::*; +use ::ops::*; impl str { /// Attempts to convert the string slice into a string array. diff --git a/sway-lib-std/src/primitive_conversions/u16.sw b/sway-lib-std/src/primitive_conversions/u16.sw index 5a032306332..7e39f8b4f2d 100644 --- a/sway-lib-std/src/primitive_conversions/u16.sw +++ b/sway-lib-std/src/primitive_conversions/u16.sw @@ -2,9 +2,74 @@ library; use ::convert::{From, TryFrom}; use ::option::Option::{self, *}; -use ::u128::U128; +use ::ops::*; +use ::primitive_conversions::u8::*; impl u16 { + /// Extends a `u16` to a `u32`. + /// + /// # Returns + /// + /// * [u32] - The converted `u16` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 10u16; + /// let result = val.as_u32(); + /// assert(result == 10u32); + /// } + /// ``` + pub fn as_u32(self) -> u32 { + asm(input: self) { + input: u32 + } + } + + /// Extends a `u16` to a `u64`. + /// + /// # Returns + /// + /// * [u64] - The converted `u16` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 10u16; + /// let result = val.as_u64(); + /// assert(result == 10); + /// } + /// ``` + pub fn as_u64(self) -> u64 { + asm(input: self) { + input: u64 + } + } + + /// Extends a `u16` to a `u256`. + /// + /// # Returns + /// + /// * [u256] - The converted `u16` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2u16; + /// let result = val.as_u256(); + /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); + /// } + /// ``` + pub fn as_u256(self) -> u256 { + let input = (0u64, 0u64, 0u64, self.as_u64()); + asm(input: input) { + input: u256 + } + } + /// Attempts to convert the u16 value into a u8 value. /// /// # Additional Information @@ -103,13 +168,3 @@ impl TryFrom for u16 { } } } - -impl TryFrom for u16 { - fn try_from(u: U128) -> Option { - if u.upper() == 0 { - >::try_from(u.lower()) - } else { - None - } - } -} diff --git a/sway-lib-std/src/primitive_conversions/u256.sw b/sway-lib-std/src/primitive_conversions/u256.sw index b4d14755092..ba46ca1ad6e 100644 --- a/sway-lib-std/src/primitive_conversions/u256.sw +++ b/sway-lib-std/src/primitive_conversions/u256.sw @@ -2,8 +2,32 @@ library; use ::convert::{From, TryFrom}; use ::option::Option::{self, *}; -use ::u128::U128; use ::b512::B512; +use ::ops::*; +use ::primitive_conversions::{b256::*, u16::*, u32::*, u64::*, u8::*}; + +impl u256 { + /// Converts a `u256` to a `b256`. + /// + /// # Returns + /// + /// * [b256] - The converted `u256` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val: u256 = 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20u256; + /// let result = val.as_b256(); + /// assert(result == 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20); + /// } + /// ``` + pub fn as_b256(self) -> b256 { + asm(input: self) { + input: b256 + } + } +} impl TryFrom for u256 { /// Attempts conversion from a `B512` to a `u256`. @@ -160,35 +184,6 @@ impl From for u256 { } } -impl From for u256 { - /// Converts a `U128` to a `u256`. - /// - /// # Arguments - /// - /// * `num`: [U128] - The `U128` to be converted. - /// - /// # Returns - /// - /// * [u256] - The `u256` representation of the `U128` value. - /// - /// # Examples - /// - /// ```sway - /// use std::u128::U128; - /// - /// fn foo() { - /// let u128_value = U128::from((18446744073709551615_u64, 18446744073709551615_u64)); - /// let u256_value = u256::from(u128_value); - /// } - /// ``` - fn from(num: U128) -> Self { - let input = (0u64, 0u64, num.upper(), num.lower()); - asm(input: input) { - input: u256 - } - } -} - impl From<(u64, u64, u64, u64)> for u256 { /// Casts a tuple of 4 `u64` values to a `u256`. /// diff --git a/sway-lib-std/src/primitive_conversions/u32.sw b/sway-lib-std/src/primitive_conversions/u32.sw index 8ffa2ca2605..ab290f3f074 100644 --- a/sway-lib-std/src/primitive_conversions/u32.sw +++ b/sway-lib-std/src/primitive_conversions/u32.sw @@ -2,9 +2,53 @@ library; use ::convert::{From, TryFrom}; use ::option::Option::{self, *}; -use ::u128::U128; +use ::ops::*; +use ::primitive_conversions::{u16::*, u8::*}; impl u32 { + /// Extends a `u32` to a `u64`. + /// + /// # Returns + /// + /// * [u64] - The converted `u32` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 10u32; + /// let result = val.as_u64(); + /// assert(result == 10); + /// } + /// ``` + pub fn as_u64(self) -> u64 { + asm(input: self) { + input: u64 + } + } + + /// Extends a `u32` to a `u256`. + /// + /// # Returns + /// + /// * [u256] - The converted `u32` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2u32; + /// let result = val.as_u256(); + /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); + /// } + /// ``` + pub fn as_u256(self) -> u256 { + let input = (0u64, 0u64, 0u64, self.as_u64()); + asm(input: input) { + input: u256 + } + } + /// Attempts to convert the u32 value into a u8 value. /// /// # Additional Information @@ -145,13 +189,3 @@ impl TryFrom for u32 { } } } - -impl TryFrom for u32 { - fn try_from(u: U128) -> Option { - if u.upper() == 0 { - >::try_from(u.lower()) - } else { - None - } - } -} diff --git a/sway-lib-std/src/primitive_conversions/u64.sw b/sway-lib-std/src/primitive_conversions/u64.sw index 92267638a1d..460786af73a 100644 --- a/sway-lib-std/src/primitive_conversions/u64.sw +++ b/sway-lib-std/src/primitive_conversions/u64.sw @@ -2,9 +2,32 @@ library; use ::convert::{TryFrom, TryInto, *}; use ::option::Option::{self, *}; -use ::u128::U128; +use ::ops::*; +use ::primitive_conversions::{u16::*, u32::*, u8::*}; impl u64 { + /// Extends a `u64` to a `u256`. + /// + /// # Returns + /// + /// * [u256] - The converted `u64` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2; + /// let result = val.as_u256(); + /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); + /// } + /// ``` + pub fn as_u256(self) -> u256 { + let input = (0u64, 0u64, 0u64, self); + asm(input: input) { + input: u256 + } + } + /// Attempts to convert the u64 value into a u8 value. /// /// # Additional Information @@ -181,13 +204,3 @@ impl TryFrom for u64 { } } } - -impl TryFrom for u64 { - fn try_from(u: U128) -> Option { - if u.upper() == 0 { - Some(u.lower()) - } else { - None - } - } -} diff --git a/sway-lib-std/src/primitive_conversions/u8.sw b/sway-lib-std/src/primitive_conversions/u8.sw index 70f10614ae7..70041583a66 100644 --- a/sway-lib-std/src/primitive_conversions/u8.sw +++ b/sway-lib-std/src/primitive_conversions/u8.sw @@ -2,7 +2,94 @@ library; use ::convert::TryFrom; use ::option::Option::{self, *}; -use ::u128::U128; +use ::ops::*; + +impl u8 { + /// Extends a `u8` to a `u16`. + /// + /// # Returns + /// + /// * [u16] - The converted `u8` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2u8; + /// let result = val.as_u16(); + /// assert(result == 2u16); + /// } + /// ``` + pub fn as_u16(self) -> u16 { + asm(input: self) { + input: u16 + } + } + + /// Extends a `u8` to a `u32`. + /// + /// # Returns + /// + /// * [u32] - The converted `u8` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2u8; + /// let result = val.as_u32(); + /// assert(result == 2u32); + /// } + /// ``` + pub fn as_u32(self) -> u32 { + asm(input: self) { + input: u32 + } + } + + /// Extends a `u8` to a `u64`. + /// + /// # Returns + /// + /// * [u64] - The converted `u8` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2u8; + /// let result = val.as_u64(); + /// assert(result == 2); + /// } + /// ``` + pub fn as_u64(self) -> u64 { + asm(input: self) { + input: u64 + } + } + + /// Extends a `u8` to a `u256`. + /// + /// # Returns + /// + /// * [u256] - The converted `u8` value. + /// + /// # Examples + /// + /// ```sway + /// fn foo() { + /// let val = 2u8; + /// let result = val.as_u256(); + /// assert(result == 0x0000000000000000000000000000000000000000000000000000000000000002u256); + /// } + /// ``` + pub fn as_u256(self) -> u256 { + let input = (0u64, 0u64, 0u64, self.as_u64()); + asm(input: input) { + input: u256 + } + } +} impl TryFrom for u8 { fn try_from(u: u16) -> Option { @@ -59,13 +146,3 @@ impl TryFrom for u8 { } } } - -impl TryFrom for u8 { - fn try_from(u: U128) -> Option { - if u.upper() == 0 { - >::try_from(u.lower()) - } else { - None - } - } -} diff --git a/sway-lib-core/src/primitives.sw b/sway-lib-std/src/primitives.sw similarity index 100% rename from sway-lib-core/src/primitives.sw rename to sway-lib-std/src/primitives.sw diff --git a/sway-lib-core/src/raw_ptr.sw b/sway-lib-std/src/raw_ptr.sw similarity index 97% rename from sway-lib-core/src/raw_ptr.sw rename to sway-lib-std/src/raw_ptr.sw index 1b4eb513397..668d9039b8d 100644 --- a/sway-lib-core/src/raw_ptr.sw +++ b/sway-lib-std/src/raw_ptr.sw @@ -1,5 +1,7 @@ library; +use ::ops::*; + impl raw_ptr { /// Returns `true` if the pointer is null. /// @@ -21,7 +23,7 @@ impl raw_ptr { let null_ptr = asm() { zero: raw_ptr }; - __eq(self, null_ptr) + self == null_ptr } /// Calculates the offset from the pointer. @@ -97,7 +99,7 @@ impl raw_ptr { asm(ptr: self) { ptr: T } - } else if __eq(__size_of::(), 1) { + } else if __size_of::() == 1 { asm(ptr: self, val) { lb val ptr i0; val: T @@ -131,7 +133,7 @@ impl raw_ptr { /// } /// ``` pub fn copy_to(self, dst: Self, count: u64) { - let len = __mul(count, __size_of::()); + let len = count * __size_of::(); asm(dst: dst, src: self, len: len) { mcp dst src len; }; @@ -157,7 +159,7 @@ impl raw_ptr { asm(dst: self, src: val, count: __size_of_val(val)) { mcp dst src count; }; - } else if __eq(__size_of::(), 1) { + } else if __size_of::() == 1 { asm(ptr: self, val: val) { sb ptr val i0; }; diff --git a/sway-lib-core/src/raw_slice.sw b/sway-lib-std/src/raw_slice.sw similarity index 97% rename from sway-lib-core/src/raw_slice.sw rename to sway-lib-std/src/raw_slice.sw index 13bd0affb90..92092e070f9 100644 --- a/sway-lib-core/src/raw_slice.sw +++ b/sway-lib-std/src/raw_slice.sw @@ -93,7 +93,7 @@ impl raw_slice { /// } /// ``` pub fn from_parts(ptr: raw_ptr, count: u64) -> Self { - from_parts((ptr, __mul(count, __size_of::()))) + from_parts((ptr, count * __size_of::())) } /// Returns the pointer to the slice. @@ -136,7 +136,7 @@ impl raw_slice { /// } /// ``` pub fn len(self) -> u64 { - __div(into_parts(self).1, __size_of::()) + into_parts(self).1 / __size_of::() } /// Returns the number of elements in the slice when the elements are bytes. diff --git a/sway-lib-std/src/result.sw b/sway-lib-std/src/result.sw index 9b0532ee567..394eb2c79d4 100644 --- a/sway-lib-std/src/result.sw +++ b/sway-lib-std/src/result.sw @@ -57,6 +57,8 @@ library; use ::logging::log; use ::revert::revert; +use ::codec::AbiEncode; +use ::ops::*; // ANCHOR: docs_result /// `Result` is a type that represents either success (`Ok`) or failure (`Err`). diff --git a/sway-lib-std/src/revert.sw b/sway-lib-std/src/revert.sw index f53dd5378d2..67f2f698d9c 100644 --- a/sway-lib-std/src/revert.sw +++ b/sway-lib-std/src/revert.sw @@ -3,6 +3,8 @@ library; use ::logging::log; use ::error_signals::{FAILED_REQUIRE_SIGNAL, REVERT_WITH_LOG_SIGNAL}; +use ::codec::AbiEncode; +use ::never::*; /// Will either panic or revert with a given number depending on the context. /// diff --git a/sway-lib-core/src/slice.sw b/sway-lib-std/src/slice.sw similarity index 100% rename from sway-lib-core/src/slice.sw rename to sway-lib-std/src/slice.sw diff --git a/sway-lib-std/src/storage/storage_api.sw b/sway-lib-std/src/storage/storage_api.sw index 2431e4c6b3d..85504cdb7cc 100644 --- a/sway-lib-std/src/storage/storage_api.sw +++ b/sway-lib-std/src/storage/storage_api.sw @@ -2,6 +2,8 @@ library; use ::alloc::alloc; use ::option::Option::{self, *}; +use ::ops::*; +use ::primitive_conversions::{b256::*, u256::*, u64::*}; /// Stores a stack value in storage. Will not work for heap values. /// diff --git a/sway-lib-std/src/storage/storage_bytes.sw b/sway-lib-std/src/storage/storage_bytes.sw index e3a15f2cae2..4744e2c39e1 100644 --- a/sway-lib-std/src/storage/storage_bytes.sw +++ b/sway-lib-std/src/storage/storage_bytes.sw @@ -3,7 +3,7 @@ library; use ::bytes::Bytes; use ::option::Option::{self, *}; use ::storage::storable_slice::*; -use ::storage::storage_api::*; +use ::storage::{storage_api::*, storage_key::StorageKey}; /// A persistent storage type to store a collection of tightly packed bytes. pub struct StorageBytes {} diff --git a/sway-lib-std/src/storage/storage_key.sw b/sway-lib-std/src/storage/storage_key.sw index 96cfab4c5d4..f5f168897b4 100644 --- a/sway-lib-std/src/storage/storage_key.sw +++ b/sway-lib-std/src/storage/storage_key.sw @@ -3,6 +3,123 @@ library; use ::option::Option; use ::storage::storage_api::*; +/// Describes a location in storage. +/// +/// # Additional Information +/// +/// The location in storage is specified by the `b256` key of a particular storage slot and an +/// offset, in words, from the start of the storage slot at `key`. The parameter `T` is the type of +/// the data to be read from or written to at `offset`. +/// `field_id` is a unique identifier for the storage field being referred to, it is different even +/// for multiple zero sized fields that might live at the same location but +/// represent different storage constructs. +pub struct StorageKey { + /// The assigned location in storage. + slot: b256, + /// The assigned offset based on the data structure `T`. + offset: u64, + /// A unique identifier. + field_id: b256, +} + +impl StorageKey { + /// Create a new `StorageKey`. + /// + /// # Arguments + /// + /// * `slot`: [b256] - The assigned location in storage for the new `StorageKey`. + /// * `offset`: [u64] - The assigned offset based on the data structure `T` for the new `StorageKey`. + /// * `field_id`: [b256] - A unique identifier for the new `StorageKey`. + /// + /// # Returns + /// + /// * [StorageKey] - The newly created `StorageKey`. + /// + /// # Examples + /// + /// ```sway + /// use std::hash::sha256; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); + /// assert(my_key.slot() == b256::zero()); + /// } + /// ``` + pub fn new(slot: b256, offset: u64, field_id: b256) -> Self { + Self { + slot, + offset, + field_id, + } + } + + /// Returns the storage slot address. + /// + /// # Returns + /// + /// * [b256] - The address in storage that this storage slot points to. + /// + /// # Examples + /// + /// ```sway + /// use std::hash::sha256; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); + /// assert(my_key.slot() == b256::zero()); + /// } + /// ``` + pub fn slot(self) -> b256 { + self.slot + } + + /// Returns the offset on the storage slot. + /// + /// # Returns + /// + /// * [u64] - The offset in storage that this storage slot points to. + /// + /// # Examples + /// + /// ```sway + /// use std::hash::sha256; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); + /// assert(my_key.offset() == 0); + /// } + /// ``` + pub fn offset(self) -> u64 { + self.offset + } + + /// Returns the storage slot field id. + /// + /// # Additional Information + /// + /// The field id is a unique identifier for the storage field being referred to, it is different even + /// for multiple zero sized fields that might live at the same location but + /// represent different storage constructs. + /// + /// # Returns + /// + /// * [b256] - The field id for this storage slot. + /// + /// # Examples + /// + /// ```sway + /// use std::hash::sha256; + /// + /// fn foo() { + /// let my_key = StorageKey::::new(b256::zero(), 0, sha256(b256::zero())); + /// assert(my_key.field_id() == sha256(b256::zero())); + /// } + /// ``` + pub fn field_id(self) -> b256 { + self.field_id + } +} + impl StorageKey { /// Reads a value of type `T` starting at the location specified by `self`. If the value /// crosses the boundary of a storage slot, reading continues at the following slot. diff --git a/sway-lib-std/src/storage/storage_string.sw b/sway-lib-std/src/storage/storage_string.sw index c235b1ad96e..97a99ced10a 100644 --- a/sway-lib-std/src/storage/storage_string.sw +++ b/sway-lib-std/src/storage/storage_string.sw @@ -2,7 +2,7 @@ library; use ::bytes::Bytes; use ::option::Option::{self, *}; -use ::storage::storable_slice::*; +use ::storage::{storable_slice::*, storage_key::StorageKey}; use ::storage::storage_api::read; use ::string::String; diff --git a/sway-lib-core/src/str.sw b/sway-lib-std/src/str.sw similarity index 100% rename from sway-lib-core/src/str.sw rename to sway-lib-std/src/str.sw diff --git a/sway-lib-std/src/string.sw b/sway-lib-std/src/string.sw index b6015a756bc..45693c4548c 100644 --- a/sway-lib-std/src/string.sw +++ b/sway-lib-std/src/string.sw @@ -6,8 +6,12 @@ use ::bytes::*; use ::convert::*; use ::hash::{Hash, Hasher}; use ::option::Option; +use ::codec::*; +use ::ops::Eq; +use ::raw_slice::AsRawSlice; use ::clone::Clone; + /// A UTF-8 encoded growable string. It has ownership over its buffer. /// /// # Additional Information diff --git a/sway-lib-std/src/tx.sw b/sway-lib-std/src/tx.sw index 033b937ec50..409b75e3188 100644 --- a/sway-lib-std/src/tx.sw +++ b/sway-lib-std/src/tx.sw @@ -4,6 +4,7 @@ library; use ::revert::revert; use ::option::Option::{self, *}; use ::alloc::alloc_bytes; +use ::ops::*; // GTF Opcode const selectors // @@ -62,7 +63,7 @@ pub enum Transaction { Blob: (), } -impl core::ops::Eq for Transaction { +impl Eq for Transaction { fn eq(self, other: Self) -> bool { match (self, other) { (Transaction::Script, Transaction::Script) => true, diff --git a/sway-lib-std/src/u128.sw b/sway-lib-std/src/u128.sw index ef016cfe560..55937ee7b2a 100644 --- a/sway-lib-std/src/u128.sw +++ b/sway-lib-std/src/u128.sw @@ -2,7 +2,7 @@ library; use ::assert::assert; -use ::convert::{From, Into}; +use ::convert::{From, Into, TryFrom}; use ::flags::{ disable_panic_on_overflow, panic_on_overflow_enabled, @@ -13,6 +13,8 @@ use ::registers::{flags, overflow}; use ::math::*; use ::result::Result::{self, *}; use ::option::Option::{self, None, Some}; +use ::ops::*; +use ::codec::*; /// The 128-bit unsigned integer type. /// @@ -144,13 +146,13 @@ impl From for (u64, u64) { } } -impl core::ops::Eq for U128 { +impl Eq for U128 { fn eq(self, other: Self) -> bool { self.lower == other.lower && self.upper == other.upper } } -impl core::ops::Ord for U128 { +impl Ord for U128 { fn gt(self, other: Self) -> bool { self.upper > other.upper || self.upper == other.upper && self.lower > other.lower } @@ -160,7 +162,7 @@ impl core::ops::Ord for U128 { } } -impl core::ops::OrdEq for U128 {} +impl OrdEq for U128 {} impl u64 { /// Performs addition between two `u64` values, returning a `U128`. @@ -481,19 +483,19 @@ impl U128 { } } -impl core::ops::BitwiseAnd for U128 { +impl BitwiseAnd for U128 { fn binary_and(self, other: Self) -> Self { Self::from((self.upper & other.upper, self.lower & other.lower)) } } -impl core::ops::BitwiseOr for U128 { +impl BitwiseOr for U128 { fn binary_or(self, other: Self) -> Self { Self::from((self.upper | other.upper, self.lower | other.lower)) } } -impl core::ops::Shift for U128 { +impl Shift for U128 { fn lsh(self, rhs: u64) -> Self { // If shifting by at least the number of bits, then saturate with // zeroes. @@ -543,7 +545,7 @@ impl core::ops::Shift for U128 { } } -impl core::ops::Not for U128 { +impl Not for U128 { fn not(self) -> Self { Self { upper: !self.upper, @@ -552,7 +554,7 @@ impl core::ops::Not for U128 { } } -impl core::ops::Add for U128 { +impl Add for U128 { /// Add a `U128` to a `U128`. Reverts on overflow. fn add(self, other: Self) -> Self { let mut upper_128 = self.upper.overflowing_add(other.upper); @@ -582,7 +584,7 @@ impl core::ops::Add for U128 { } } -impl core::ops::Subtract for U128 { +impl Subtract for U128 { /// Subtract a `U128` from a `U128`. Reverts on underflow. fn subtract(self, other: Self) -> Self { // panic_on_overflow_enabled is also for underflow @@ -605,7 +607,7 @@ impl core::ops::Subtract for U128 { Self { upper, lower } } } -impl core::ops::Multiply for U128 { +impl Multiply for U128 { /// Multiply a `U128` with a `U128`. Reverts of overflow. fn multiply(self, other: Self) -> Self { // in case both of the `U128` upper parts are bigger than zero, @@ -628,7 +630,7 @@ impl core::ops::Multiply for U128 { } } -impl core::ops::Divide for U128 { +impl Divide for U128 { /// Divide a `U128` by a `U128`. Reverts if divisor is zero. fn divide(self, divisor: Self) -> Self { let zero = Self::from((0, 0)); @@ -668,7 +670,7 @@ impl core::ops::Divide for U128 { } } -impl core::ops::Mod for U128 { +impl Mod for U128 { fn modulo(self, other: Self) -> Self { assert(other != Self::zero()); @@ -876,7 +878,7 @@ impl Logarithm for U128 { } } -impl core::ops::TotalOrd for U128 { +impl TotalOrd for U128 { fn min(self, other: Self) -> Self { if self < other { self } else { other } } @@ -885,3 +887,101 @@ impl core::ops::TotalOrd for U128 { if self > other { self } else { other } } } + +impl TryFrom for u8 { + fn try_from(u: U128) -> Option { + if u.upper() == 0 { + >::try_from(u.lower()) + } else { + None + } + } +} + +impl TryFrom for u16 { + fn try_from(u: U128) -> Option { + if u.upper() == 0 { + >::try_from(u.lower()) + } else { + None + } + } +} + +impl TryFrom for u32 { + fn try_from(u: U128) -> Option { + if u.upper() == 0 { + >::try_from(u.lower()) + } else { + None + } + } +} + +impl TryFrom for u64 { + fn try_from(u: U128) -> Option { + if u.upper() == 0 { + Some(u.lower()) + } else { + None + } + } +} + +impl From for u256 { + /// Converts a `U128` to a `u256`. + /// + /// # Arguments + /// + /// * `num`: [U128] - The `U128` to be converted. + /// + /// # Returns + /// + /// * [u256] - The `u256` representation of the `U128` value. + /// + /// # Examples + /// + /// ```sway + /// use std::u128::U128; + /// + /// fn foo() { + /// let u128_value = U128::from((18446744073709551615_u64, 18446744073709551615_u64)); + /// let u256_value = u256::from(u128_value); + /// } + /// ``` + fn from(num: U128) -> Self { + let input = (0u64, 0u64, num.upper(), num.lower()); + asm(input: input) { + input: u256 + } + } +} + +impl From for b256 { + /// Converts a `U128` to a `b256`. + /// + /// # Arguments + /// + /// * `num`: [U128] - The `U128` to be converted. + /// + /// # Returns + /// + /// * [b256] - The `b256` representation of the `U128` value. + /// + /// # Examples + /// + /// ```sway + /// use std::u128::U128; + /// + /// fn foo() { + /// let u128_value = U128::from((18446744073709551615_u64, 18446744073709551615_u64)); + /// let b256_value = b256::from(u128_value); + /// } + /// ``` + fn from(num: U128) -> Self { + let input = (0u64, 0u64, num.upper(), num.lower()); + asm(input: input) { + input: b256 + } + } +} diff --git a/sway-lib-std/src/vec.sw b/sway-lib-std/src/vec.sw index 9956f6be182..48621c66ac9 100644 --- a/sway-lib-std/src/vec.sw +++ b/sway-lib-std/src/vec.sw @@ -6,6 +6,9 @@ use ::assert::assert; use ::option::Option::{self, *}; use ::convert::From; use ::iterator::*; +use ::codec::*; +use ::ops::*; +use ::raw_slice::*; use ::clone::Clone; struct RawVec { diff --git a/sway-lib-std/src/vm/evm/evm_address.sw b/sway-lib-std/src/vm/evm/evm_address.sw index f3b03e0692a..80920a4c5ce 100644 --- a/sway-lib-std/src/vm/evm/evm_address.sw +++ b/sway-lib-std/src/vm/evm/evm_address.sw @@ -4,6 +4,8 @@ library; use ::intrinsics::size_of_val; use ::convert::{From, Into, TryFrom}; use ::hash::*; +use ::ops::Eq; +use ::primitives::*; use ::bytes::Bytes; use ::option::Option::{self, *}; @@ -77,7 +79,7 @@ impl EvmAddress { } } -impl core::ops::Eq for EvmAddress { +impl Eq for EvmAddress { fn eq(self, other: Self) -> bool { self.bits == other.bits } diff --git a/sway-types/src/constants.rs b/sway-types/src/constants.rs index 3a9f01edc1b..d63d0654d00 100644 --- a/sway-types/src/constants.rs +++ b/sway-types/src/constants.rs @@ -68,7 +68,6 @@ pub const VALID_ATTRIBUTE_NAMES: &[&str] = &[ FALLBACK_ATTRIBUTE_NAME, ]; -pub const CORE: &str = "core"; pub const STD: &str = "std"; pub const PRELUDE: &str = "prelude"; pub const CONTRACT_ID: &str = "CONTRACT_ID"; diff --git a/test/src/in_language_tests/Forc.toml b/test/src/in_language_tests/Forc.toml index 2f399e112b0..b6154a3c974 100644 --- a/test/src/in_language_tests/Forc.toml +++ b/test/src/in_language_tests/Forc.toml @@ -50,4 +50,5 @@ members = [ "test_programs/primitive_conversions_u256_inline_tests", "test_programs/vm_evm_evm_address_inline_tests", "test_programs/vm_evm_ecr_inline_tests", + "test_programs/ops_inline_tests", ] diff --git a/test/src/in_language_tests/test_programs/ops_inline_tests/Forc.toml b/test/src/in_language_tests/test_programs/ops_inline_tests/Forc.toml new file mode 100644 index 00000000000..b9e67b715c2 --- /dev/null +++ b/test/src/in_language_tests/test_programs/ops_inline_tests/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "ops_inline_tests" + +[dependencies] +std = { path = "../../../../../sway-lib-std" } diff --git a/test/src/in_language_tests/test_programs/ops_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/ops_inline_tests/src/main.sw new file mode 100644 index 00000000000..b7ba1dbf655 --- /dev/null +++ b/test/src/in_language_tests/test_programs/ops_inline_tests/src/main.sw @@ -0,0 +1,11 @@ +library; + +#[test] +pub fn str_eq_test() { + assert("" == ""); + assert("a" == "a"); + + assert("a" != ""); + assert("" != "a"); + assert("a" != "b"); +} diff --git a/test/src/in_language_tests/test_programs/primitive_conversions_b256_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/primitive_conversions_b256_inline_tests/src/main.sw index 21fe0d19f71..c0d576179d3 100644 --- a/test/src/in_language_tests/test_programs/primitive_conversions_b256_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/primitive_conversions_b256_inline_tests/src/main.sw @@ -166,3 +166,12 @@ fn b256_into_tuple() { assert(b256_2 == 0x0000000000000001000000000000000200000000000000030000000000000004); assert(b256_3 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); } + +#[test] +fn test_b256_as_u256() { + let val = 0x0000000000000000000000000000000000000000000000000000000000000002; + let result = val.as_u256(); + assert( + result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, + ); +} diff --git a/test/src/in_language_tests/test_programs/primitive_conversions_u16_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/primitive_conversions_u16_inline_tests/src/main.sw index 6ac9fc8fb8a..4990c814efb 100644 --- a/test/src/in_language_tests/test_programs/primitive_conversions_u16_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/primitive_conversions_u16_inline_tests/src/main.sw @@ -127,3 +127,26 @@ fn u16_try_from_u128() { assert(u16_4.is_none()); } + +#[test] +fn test_u16_as_u64() { + let val = 2u16; + let result = val.as_u64(); + assert(result == 2); +} + +#[test] +fn test_u16_as_u32() { + let val = 2u16; + let result = val.as_u32(); + assert(result == 2u32); +} + +#[test] +fn test_u16_as_u256() { + let val = 2u16; + let result = val.as_u256(); + assert( + result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, + ); +} diff --git a/test/src/in_language_tests/test_programs/primitive_conversions_u32_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/primitive_conversions_u32_inline_tests/src/main.sw index 862cab88c91..294fc834701 100644 --- a/test/src/in_language_tests/test_programs/primitive_conversions_u32_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/primitive_conversions_u32_inline_tests/src/main.sw @@ -133,3 +133,19 @@ fn u32_try_from_u128() { assert(u32_4.is_none()); } + +#[test] +fn test_u32_as_u64() { + let val = 2u32; + let result = val.as_u64(); + assert(result == 2); +} + +#[test] +fn test_u32_as_u256() { + let val = 2u32; + let result = val.as_u256(); + assert( + result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, + ); +} diff --git a/test/src/in_language_tests/test_programs/primitive_conversions_u64_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/primitive_conversions_u64_inline_tests/src/main.sw index e82b953c1ab..ca737cacbc1 100644 --- a/test/src/in_language_tests/test_programs/primitive_conversions_u64_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/primitive_conversions_u64_inline_tests/src/main.sw @@ -139,3 +139,12 @@ fn u64_try_from_u128() { assert(u64_4.is_none()); } + +#[test] +fn u64_as_u256() { + let val = 2; + let result = val.as_u256(); + assert( + result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, + ); +} diff --git a/test/src/in_language_tests/test_programs/primitive_conversions_u8_inline_tests/src/main.sw b/test/src/in_language_tests/test_programs/primitive_conversions_u8_inline_tests/src/main.sw index 0fa64a82e6a..ff08c0180e1 100644 --- a/test/src/in_language_tests/test_programs/primitive_conversions_u8_inline_tests/src/main.sw +++ b/test/src/in_language_tests/test_programs/primitive_conversions_u8_inline_tests/src/main.sw @@ -121,3 +121,33 @@ fn u8_try_from_u128() { assert(u8_4.is_none()); } + +#[test] +fn test_u8_as_u64() { + let val = 2u8; + let result = val.as_u64(); + assert(result == 2); +} + +#[test] +fn test_u8_as_u32() { + let val = 2u8; + let result = val.as_u32(); + assert(result == 2u32); +} + +#[test] +fn test_u8_as_u16() { + let val = 2u8; + let result = val.as_u16(); + assert(result == 2u16); +} + +#[test] +fn test_u8_as_u256() { + let val = 2u8; + let result = val.as_u256(); + assert( + result == 0x0000000000000000000000000000000000000000000000000000000000000002u256, + ); +}