Skip to content

Commit

Permalink
Merge 4e725c2 into df5d194
Browse files Browse the repository at this point in the history
  • Loading branch information
xunilrj authored Aug 26, 2024
2 parents df5d194 + 4e725c2 commit 5021abe
Show file tree
Hide file tree
Showing 17 changed files with 482 additions and 49 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ forc-plugins/forc-debug/tests/**/Forc.lock
# Generated files in example directories
examples/**/*/Forc.lock
docs/reference/src/code/examples/**/*/Forc.lock

# Insta files
*.snap.new
63 changes: 62 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions sway-core/src/language/ty/declaration/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,15 +572,16 @@ impl TyFunctionSig {
}

pub fn is_concrete(&self, engines: &Engines) -> bool {
self.return_type.is_concrete(engines, IncludeNumeric::No)
self.return_type
.is_concrete(engines, TreatNumericAs::Concrete)
&& self
.parameters
.iter()
.all(|p| p.is_concrete(engines, IncludeNumeric::No))
.all(|p| p.is_concrete(engines, TreatNumericAs::Concrete))
&& self
.type_parameters
.iter()
.all(|p| p.is_concrete(engines, IncludeNumeric::No))
.all(|p| p.is_concrete(engines, TreatNumericAs::Concrete))
}

/// Returns a String representing the function.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ fn type_check_encode_append(
};

// only supported types
if item_type.is_concrete(engines, IncludeNumeric::Yes) {
if item_type.is_concrete(engines, TreatNumericAs::Abstract) {
match &*engines.te().get(item_type) {
TypeInfo::Boolean
| TypeInfo::UnsignedInteger(IntegerBits::Eight)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::{
use ast_node::declaration::{insert_supertraits_into_namespace, SupertraitOf};
use either::Either;
use indexmap::IndexMap;
use itertools::Itertools;
use rustc_hash::FxHashSet;
use std::collections::{HashMap, VecDeque};
use sway_ast::intrinsics::Intrinsic;
Expand Down Expand Up @@ -1858,7 +1859,36 @@ impl ty::TyExpression {
})
.collect();

let elem_type = typed_contents[0].return_type;
// choose the best type to be the array elem type
use itertools::FoldWhile::{Continue, Done};
let elem_type = typed_contents
.iter()
.fold_while(None, |last, current| match last {
None => Continue(Some(current.return_type)),
Some(last) => {
if last.is_concrete(engines, TreatNumericAs::Abstract) {
return Done(Some(last));
}

if current
.return_type
.is_concrete(engines, TreatNumericAs::Abstract)
{
return Done(Some(current.return_type));
}

let last_info = ctx.engines().te().get(last);
let current_info = ctx.engines().te().get(current.return_type);
match (&*last_info, &*current_info) {
(TypeInfo::Numeric, TypeInfo::UnsignedInteger(_)) => {
Done(Some(current.return_type))
}
_ => Continue(Some(last)),
}
}
})
.into_inner();
let elem_type = elem_type.unwrap_or_else(|| typed_contents[0].return_type);

let array_count = typed_contents.len();
Ok(ty::TyExpression {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub(crate) fn type_check_method_application(
x.return_type
.extract_inner_types(engines, IncludeSelf::Yes)
.iter()
.any(|x| !x.is_concrete(engines, IncludeNumeric::Yes))
.any(|x| !x.is_concrete(engines, TreatNumericAs::Abstract))
})
.unwrap_or_default();
let needs_second_pass = has_errors || is_not_concrete;
Expand Down
52 changes: 29 additions & 23 deletions sway-core/src/type_system/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub enum IncludeSelf {
No,
}

pub enum IncludeNumeric {
Yes,
No,
pub enum TreatNumericAs {
Abstract,
Concrete,
}

/// A identifier to uniquely refer to our type terms
Expand Down Expand Up @@ -461,27 +461,33 @@ impl TypeId {
}))
}

pub(crate) fn is_concrete(&self, engines: &Engines, include_numeric: IncludeNumeric) -> bool {
pub(crate) fn is_concrete(
&self,
engines: &Engines,
numeric_non_concrete: TreatNumericAs,
) -> bool {
let nested_types = (*self).extract_nested_types(engines);
!nested_types.into_iter().any(|x| match include_numeric {
IncludeNumeric::Yes => matches!(
x,
TypeInfo::UnknownGeneric { .. }
| TypeInfo::Custom { .. }
| TypeInfo::Placeholder(..)
| TypeInfo::TraitType { .. }
| TypeInfo::TypeParam(..)
| TypeInfo::Numeric
),
IncludeNumeric::No => matches!(
x,
TypeInfo::UnknownGeneric { .. }
| TypeInfo::Custom { .. }
| TypeInfo::Placeholder(..)
| TypeInfo::TraitType { .. }
| TypeInfo::TypeParam(..)
),
})
!nested_types
.into_iter()
.any(|x| match numeric_non_concrete {
TreatNumericAs::Abstract => matches!(
x,
TypeInfo::UnknownGeneric { .. }
| TypeInfo::Custom { .. }
| TypeInfo::Placeholder(..)
| TypeInfo::TraitType { .. }
| TypeInfo::TypeParam(..)
| TypeInfo::Numeric
),
TreatNumericAs::Concrete => matches!(
x,
TypeInfo::UnknownGeneric { .. }
| TypeInfo::Custom { .. }
| TypeInfo::Placeholder(..)
| TypeInfo::TraitType { .. }
| TypeInfo::TypeParam(..)
),
})
}

/// `check_type_parameter_bounds` does two types of checks. Lets use the example below for demonstrating the two checks:
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/type_system/priv_prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ pub use super::{
type_parameter::TypeParameter,
},
engine::TypeEngine,
id::{IncludeNumeric, IncludeSelf, TypeId},
id::{IncludeSelf, TreatNumericAs, TypeId},
info::{AbiEncodeSizeHint, AbiName, TypeInfo, TypeSourceInfo},
};
9 changes: 9 additions & 0 deletions test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ forc-tracing = { path = "../forc-tracing" }
fuel-vm = { workspace = true, features = ["random"] }
futures = "0.3.24"
gag = "1.0"
glob = "0.3.1"
hex = "0.4.3"
insta = "1.39.0"
libtest-mimic = "0.7.3"
miden = "0.3.0"
prettydiff = "0.6"
rand = "0.8"
Expand All @@ -35,3 +38,9 @@ textwrap = "0.16.0"
tokio = "1.12"
toml = { version = "0.7", features = ["parse"] }
tracing = "0.1"
vte = "0.13.0"

[[test]]
name = "tests"
path = "tests/tests.rs"
harness = false
15 changes: 15 additions & 0 deletions test/src/e2e_vm_tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
In order to minimize compilation time of individual tests, strive to reduce dependencies in tests.

To achieve that, follow these guidelines:

- Use `implicit-std = false` if dependency on `core` is not needed. This is often possible when testing `should_pass/language` features.
- If the dependency on `core` is not needed, instead of using the project type `script`, that will, because of the encoding, depend on `core`, try using `library` instead.
- Do not use `std` just to conveniently get an arbitrary type or trait. E.g., if a test requires an arbitrary type or trait, go with `struct Dummy {}` or `trait Trait {}` instead of importing `Option` or `Hash`.
Expand Down Expand Up @@ -87,3 +88,17 @@ SWAY_TEST_VERBOSE=true cargo run [pattern]
```

from the `sway/test` directory.

# Snapshot tests

When an "e2e" test has a file named `snapshot.toml` it will run as `cargo insta` snapshot tests.
These tests can be run as normal: `cargo r -p test`, and in two new ways:

```
> cargo t -p test
> cargo insta test
```

Snapshots can be reviewed using normal "cargo insta" workflow (see [insta.rs](https://insta.rs/)).

For the moment, there is no configuration for `snapshot.toml`, so they are just empty files.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
script;

fn main() {
// u8
let _a = 0x100;
Vec::<u8>::new().push(_a);

Expand All @@ -15,4 +14,20 @@ fn main() {

// Array
let a = [1, 2, "hello"];

// Array - different numerics
let a = [1, 2u8, 3u16, 4u32, 5u64];

// Array - unspecified generic structs
let a = [None, Some(1), Some(1u8)];
let _b: Option<u16> = a[1];

// Wrong cast
let a = [8, 256u16, 8u8];
let b: u32 = a[2];
}

fn insufficient_type_check(arg: u64) -> [u32;2] {
let res = [1u32, arg];
res
}
Loading

0 comments on commit 5021abe

Please sign in to comment.