From 4651a6763fa4414857a929f06edac803328974f6 Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 29 Jul 2022 17:34:45 +0700 Subject: [PATCH 01/11] reject zero type when declare event fields --- crates/analyzer/src/db/queries/events.rs | 12 +++++++++- crates/analyzer/src/namespace/types.rs | 11 +++++++++ crates/analyzer/tests/errors.rs | 1 + ...ors__invalid_type_in_event_zero_sized.snap | 23 +++++++++++++++++++ .../invalid_type_in_event_zero_sized.fe | 11 +++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap create mode 100644 crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe diff --git a/crates/analyzer/src/db/queries/events.rs b/crates/analyzer/src/db/queries/events.rs index fd7a4548b4..896d211129 100644 --- a/crates/analyzer/src/db/queries/events.rs +++ b/crates/analyzer/src/db/queries/events.rs @@ -40,7 +40,17 @@ pub fn event_type(db: &dyn AnalyzerDb, event: EventId) -> Analysis Ok(typ), + typ if typ.has_fixed_size(scope.db()) => { + if !typ.is_zero_size(scope.db()) { + return Ok(typ) + } else { + return Err(TypeError::new(scope.error( + "event field type must have a non-zero types", + typ_node.span, + "this type can't be used as an event field", + ))) + } + } _ => Err(TypeError::new(scope.error( "event field type must have a fixed size", typ_node.span, diff --git a/crates/analyzer/src/namespace/types.rs b/crates/analyzer/src/namespace/types.rs index 36f75d37a4..0f74cdc90c 100644 --- a/crates/analyzer/src/namespace/types.rs +++ b/crates/analyzer/src/namespace/types.rs @@ -84,6 +84,9 @@ impl TypeId { pub fn is_base(&self, db: &dyn AnalyzerDb) -> bool { self.typ(db).is_base() } + pub fn is_zero_size(&self, db: &dyn AnalyzerDb) -> bool { + self.typ(db).is_zero_size(db) + } pub fn is_bool(&self, db: &dyn AnalyzerDb) -> bool { matches!(self.typ(db), Type::Base(Base::Bool)) } @@ -494,6 +497,14 @@ impl Type { false } + pub fn is_zero_size(&self, db: &dyn AnalyzerDb) -> bool { + match &self { + Type::Base(Base::Unit) => true, + Type::Contract(inner) => inner.fields(db).is_empty(), + Type::Struct(inner) => inner.fields(db).is_empty(), + _ => false + } + } /// Creates an instance of bool. pub fn bool() -> Self { Type::Base(Base::Bool) diff --git a/crates/analyzer/tests/errors.rs b/crates/analyzer/tests/errors.rs index 6720b5f308..0f254ddf69 100644 --- a/crates/analyzer/tests/errors.rs +++ b/crates/analyzer/tests/errors.rs @@ -255,6 +255,7 @@ test_file! { external_call_type_error } test_file! { external_call_wrong_number_of_params } test_file! { contract_function_with_generic_params } test_file! { indexed_event } +test_file! { invalid_type_in_event_zero_sized } test_file! { invalid_compiler_version } test_file! { invalid_block_field } test_file! { invalid_chain_field } diff --git a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap new file mode 100644 index 0000000000..61a94e8ad8 --- /dev/null +++ b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap @@ -0,0 +1,23 @@ +--- +source: crates/analyzer/tests/errors.rs +expression: "error_string(&path, test_files::fixture(path))" +--- +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:8:8 + │ +8 │ x: () + │ ^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:9:8 + │ +9 │ y: EmptyStruct + │ ^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:10:8 + │ +10 │ z: EmptyContract + │ ^^^^^^^^^^^^^ this type can't be used as an event field + + diff --git a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe new file mode 100644 index 0000000000..a9f6eb881f --- /dev/null +++ b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe @@ -0,0 +1,11 @@ +contract EmptyContract { +} + +struct EmptyStruct { +} + +event Event { + x: () + y: EmptyStruct + z: EmptyContract +} From b44d65dd03e44c3902e8c8621306be9535a25550 Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 29 Jul 2022 17:41:34 +0700 Subject: [PATCH 02/11] fix --- crates/analyzer/src/db/queries/events.rs | 4 ++-- crates/analyzer/src/namespace/types.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/analyzer/src/db/queries/events.rs b/crates/analyzer/src/db/queries/events.rs index 896d211129..c107a16586 100644 --- a/crates/analyzer/src/db/queries/events.rs +++ b/crates/analyzer/src/db/queries/events.rs @@ -42,9 +42,9 @@ pub fn event_type(db: &dyn AnalyzerDb, event: EventId) -> Analysis { if !typ.is_zero_size(scope.db()) { - return Ok(typ) + Ok(typ) } else { - return Err(TypeError::new(scope.error( + Err(TypeError::new(scope.error( "event field type must have a non-zero types", typ_node.span, "this type can't be used as an event field", diff --git a/crates/analyzer/src/namespace/types.rs b/crates/analyzer/src/namespace/types.rs index 0f74cdc90c..28526e1e2a 100644 --- a/crates/analyzer/src/namespace/types.rs +++ b/crates/analyzer/src/namespace/types.rs @@ -502,7 +502,7 @@ impl Type { Type::Base(Base::Unit) => true, Type::Contract(inner) => inner.fields(db).is_empty(), Type::Struct(inner) => inner.fields(db).is_empty(), - _ => false + _ => false, } } /// Creates an instance of bool. From b589fc863d3af454e81bca20cc7b4a68236aff8b Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 29 Jul 2022 22:56:56 +0700 Subject: [PATCH 03/11] only check zero size types on event idx field --- crates/analyzer/src/db/queries/events.rs | 6 +++--- ...rors__invalid_type_in_event_zero_sized.snap | 18 +++++++++--------- .../invalid_type_in_event_zero_sized.fe | 7 ++++--- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/crates/analyzer/src/db/queries/events.rs b/crates/analyzer/src/db/queries/events.rs index c107a16586..85a9719c0d 100644 --- a/crates/analyzer/src/db/queries/events.rs +++ b/crates/analyzer/src/db/queries/events.rs @@ -41,14 +41,14 @@ pub fn event_type(db: &dyn AnalyzerDb, event: EventId) -> Analysis { - if !typ.is_zero_size(scope.db()) { - Ok(typ) - } else { + if *is_idx && typ.is_zero_size(scope.db()) { Err(TypeError::new(scope.error( "event field type must have a non-zero types", typ_node.span, "this type can't be used as an event field", ))) + } else { + Ok(typ) } } _ => Err(TypeError::new(scope.error( diff --git a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap index 61a94e8ad8..4934619a06 100644 --- a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap +++ b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap @@ -3,21 +3,21 @@ source: crates/analyzer/tests/errors.rs expression: "error_string(&path, test_files::fixture(path))" --- error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:8:8 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:8:12 │ -8 │ x: () - │ ^^ this type can't be used as an event field +8 │ idx x: () + │ ^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:9:8 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:9:12 │ -9 │ y: EmptyStruct - │ ^^^^^^^^^^^ this type can't be used as an event field +9 │ idx y: EmptyStruct + │ ^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:10:8 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:10:12 │ -10 │ z: EmptyContract - │ ^^^^^^^^^^^^^ this type can't be used as an event field +10 │ idx z: EmptyContract + │ ^^^^^^^^^^^^^ this type can't be used as an event field diff --git a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe index a9f6eb881f..b6b32deb75 100644 --- a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe +++ b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe @@ -5,7 +5,8 @@ struct EmptyStruct { } event Event { - x: () - y: EmptyStruct - z: EmptyContract + idx x: () + idx y: EmptyStruct + idx z: EmptyContract + v: () } From a1f11d0edb58cfb3293371c01c5af390046556c6 Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Sun, 7 Aug 2022 15:06:03 +0700 Subject: [PATCH 04/11] wip --- crates/analyzer/src/namespace/types.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/analyzer/src/namespace/types.rs b/crates/analyzer/src/namespace/types.rs index 28526e1e2a..653eba3ccd 100644 --- a/crates/analyzer/src/namespace/types.rs +++ b/crates/analyzer/src/namespace/types.rs @@ -85,7 +85,7 @@ impl TypeId { self.typ(db).is_base() } pub fn is_zero_size(&self, db: &dyn AnalyzerDb) -> bool { - self.typ(db).is_zero_size(db) + self.typ(db).is_zero_size() } pub fn is_bool(&self, db: &dyn AnalyzerDb) -> bool { matches!(self.typ(db), Type::Base(Base::Bool)) @@ -497,11 +497,9 @@ impl Type { false } - pub fn is_zero_size(&self, db: &dyn AnalyzerDb) -> bool { + pub fn is_zero_size(&self) -> bool { match &self { Type::Base(Base::Unit) => true, - Type::Contract(inner) => inner.fields(db).is_empty(), - Type::Struct(inner) => inner.fields(db).is_empty(), _ => false, } } From 851c7b0766afea4a752c2b1cd2eefe8bac436444 Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 12 Aug 2022 02:03:29 +0700 Subject: [PATCH 05/11] create is_zero_sized query in salsa --- crates/analyzer/src/db.rs | 3 + crates/analyzer/src/db/queries/events.rs | 2 +- crates/analyzer/src/db/queries/types.rs | 49 ++++++++++- crates/analyzer/src/namespace/types.rs | 12 +-- ...ors__invalid_type_in_event_zero_sized.snap | 82 ++++++++++++++++--- .../invalid_type_in_event_zero_sized.fe | 55 +++++++++++-- 6 files changed, 174 insertions(+), 29 deletions(-) diff --git a/crates/analyzer/src/db.rs b/crates/analyzer/src/db.rs index a0ece832c7..e81f1d8a07 100644 --- a/crates/analyzer/src/db.rs +++ b/crates/analyzer/src/db.rs @@ -195,6 +195,9 @@ pub trait AnalyzerDb: SourceDb + Upcast + UpcastMut #[salsa::invoke(queries::types::type_alias_type)] #[salsa::cycle(queries::types::type_alias_type_cycle)] fn type_alias_type(&self, id: TypeAliasId) -> Analysis>; + #[salsa::invoke(queries::types::is_zero_sized)] + #[salsa::cycle(queries::types::is_zero_sized_cycle)] + fn is_zero_sized(&self, ty: TypeId) -> bool; } #[salsa::database(AnalyzerDbStorage, SourceDbStorage)] diff --git a/crates/analyzer/src/db/queries/events.rs b/crates/analyzer/src/db/queries/events.rs index 85a9719c0d..1b3ec853ab 100644 --- a/crates/analyzer/src/db/queries/events.rs +++ b/crates/analyzer/src/db/queries/events.rs @@ -41,7 +41,7 @@ pub fn event_type(db: &dyn AnalyzerDb, event: EventId) -> Analysis { - if *is_idx && typ.is_zero_size(scope.db()) { + if *is_idx && typ.is_zero_sized(db) { Err(TypeError::new(scope.error( "event field type must have a non-zero types", typ_node.span, diff --git a/crates/analyzer/src/db/queries/types.rs b/crates/analyzer/src/db/queries/types.rs index 91bfb35619..661b7878b3 100644 --- a/crates/analyzer/src/db/queries/types.rs +++ b/crates/analyzer/src/db/queries/types.rs @@ -7,7 +7,7 @@ use crate::db::Analysis; use crate::errors::TypeError; use crate::namespace::items::{FunctionSigId, ImplId, TraitId, TypeAliasId}; use crate::namespace::scopes::ItemScope; -use crate::namespace::types::{self, TypeId}; +use crate::namespace::types::{self, TypeId, Array, Tuple, Type, FeString, Base}; use crate::traversal::types::type_desc; use crate::AnalyzerDb; @@ -69,3 +69,50 @@ pub fn type_alias_type_cycle( Analysis::new(err, context.diagnostics.take().into()) } + +pub fn is_zero_sized(db: &dyn AnalyzerDb, ty: types::TypeId) -> bool { + let typ = db.lookup_intern_type(ty); + match typ { + Type::Base(base) => matches!(base, Base::Unit), + Type::Array(Array { size, inner }) => size == 0 || inner.is_zero_sized(db), + Type::Tuple(Tuple { items }) => { + for item in items.into_iter() { + if !db.is_zero_sized(*item) { + return false; + } + } + return true; + } + Type::String(FeString { max_size }) => max_size == 0, + Type::Struct(struct_id) => { + for field_type_id in db.struct_all_fields(struct_id).into_iter() { + // assume all type is correct. + let field_type = db.struct_field_type(*field_type_id).value.unwrap(); + if !(field_type).is_zero_sized(db) { + return false; + } + } + return true; + } + Type::Contract(contract_id) => { + for field_type_id in db.contract_all_fields(contract_id).into_iter() { + let field_type = db.contract_field_type(*field_type_id).value.unwrap(); + if !(field_type).is_zero_sized(db) { + return false; + } + } + return true; + } + Type::Generic(_) | Type::Map(_) | Type::SelfContract(_) => false, + } +} + + +// because we already catch this error so this should be empty +pub fn is_zero_sized_cycle( + _db: &dyn AnalyzerDb, + _cycle: &[String], + _ty: &types::TypeId, +) -> bool { + true +} diff --git a/crates/analyzer/src/namespace/types.rs b/crates/analyzer/src/namespace/types.rs index 653eba3ccd..ac625531dd 100644 --- a/crates/analyzer/src/namespace/types.rs +++ b/crates/analyzer/src/namespace/types.rs @@ -84,8 +84,8 @@ impl TypeId { pub fn is_base(&self, db: &dyn AnalyzerDb) -> bool { self.typ(db).is_base() } - pub fn is_zero_size(&self, db: &dyn AnalyzerDb) -> bool { - self.typ(db).is_zero_size() + pub fn is_zero_sized(&self, db: &dyn AnalyzerDb) -> bool { + db.is_zero_sized(*self) } pub fn is_bool(&self, db: &dyn AnalyzerDb) -> bool { matches!(self.typ(db), Type::Base(Base::Bool)) @@ -496,13 +496,7 @@ impl Type { } false } - - pub fn is_zero_size(&self) -> bool { - match &self { - Type::Base(Base::Unit) => true, - _ => false, - } - } + /// Creates an instance of bool. pub fn bool() -> Self { Type::Base(Base::Bool) diff --git a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap index 4934619a06..56834cc459 100644 --- a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap +++ b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap @@ -2,22 +2,82 @@ source: crates/analyzer/tests/errors.rs expression: "error_string(&path, test_files::fixture(path))" --- +error: feature not yet implemented: contract types aren't yet supported as struct fields + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:14:5 + │ +14 │ y: EmptyContract + │ ^^^^^^^^^^^^^^^^ not yet implemented + +error: recursive struct `Foo` + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:17:8 + │ +17 │ struct Foo { + │ ^^^ struct `Foo` has infinite size due to recursive definition + +error: recursive struct `Baz` + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:21:8 + │ +21 │ struct Baz { + │ ^^^ struct `Baz` has infinite size due to recursive definition + error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:8:12 - │ -8 │ idx x: () - │ ^^ this type can't be used as an event field + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:27:13 + │ +27 │ idx a : () + │ ^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:9:12 - │ -9 │ idx y: EmptyStruct - │ ^^^^^^^^^^^ this type can't be used as an event field + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:28:13 + │ +28 │ idx b : EmptyContract + │ ^^^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:29:13 + │ +29 │ idx c : EmptyStruct + │ ^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:34:12 + │ +34 │ idx b: ((), EmptyContract, EmptyStruct) + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:35:12 + │ +35 │ idx c: Array + │ ^^^^^^^^^^^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:39:12 + │ +39 │ idx a: Array<(), 0> + │ ^^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:40:12 + │ +40 │ idx b: Array + │ ^^^^^^^^^^^^^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:44:12 + │ +44 │ idx a: Array<(), 0> + │ ^^^^^^^^^^^^ this type can't be used as an event field + +error: event field type must have a non-zero types + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:45:12 + │ +45 │ idx b: AnotherEmpty + │ ^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:10:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:52:12 │ -10 │ idx z: EmptyContract - │ ^^^^^^^^^^^^^ this type can't be used as an event field +52 │ idx f: Foo + │ ^^^ this type can't be used as an event field diff --git a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe index b6b32deb75..52806ba41c 100644 --- a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe +++ b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe @@ -1,12 +1,53 @@ -contract EmptyContract { +struct EmptyStruct {} +contract EmptyContract {} + +struct UnEmptyStruct { + v: u32 +} + +contract UnEmptyContract { + u: u256 +} + +struct AnotherEmpty { + x: EmptyStruct + y: EmptyContract +} + +struct Foo { + x: Baz } -struct EmptyStruct { +struct Baz { + x: Foo } -event Event { - idx x: () - idx y: EmptyStruct - idx z: EmptyContract - v: () + +event FirstCase { + idx a : () + idx b : EmptyContract + idx c : EmptyStruct } + +event SecondCase { + idx a: u256 + idx b: ((), EmptyContract, EmptyStruct) + idx c: Array +} + +event ThirdCase { + idx a: Array<(), 0> + idx b: Array +} + +event FifthCase { + idx a: Array<(), 0> + idx b: AnotherEmpty + idx c: Array +} + +event SixthCase { + idx d: UnEmptyStruct + idx e: ((), UnEmptyStruct) + idx f: Foo +} \ No newline at end of file From 5aa025496fa0d5255b03f433d9b69e9b31d05d81 Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 12 Aug 2022 02:05:47 +0700 Subject: [PATCH 06/11] fix --- crates/analyzer/src/db/queries/types.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/analyzer/src/db/queries/types.rs b/crates/analyzer/src/db/queries/types.rs index 661b7878b3..2b90b98fcf 100644 --- a/crates/analyzer/src/db/queries/types.rs +++ b/crates/analyzer/src/db/queries/types.rs @@ -76,32 +76,32 @@ pub fn is_zero_sized(db: &dyn AnalyzerDb, ty: types::TypeId) -> bool { Type::Base(base) => matches!(base, Base::Unit), Type::Array(Array { size, inner }) => size == 0 || inner.is_zero_sized(db), Type::Tuple(Tuple { items }) => { - for item in items.into_iter() { + for item in items.iter() { if !db.is_zero_sized(*item) { return false; } } - return true; + true } Type::String(FeString { max_size }) => max_size == 0, Type::Struct(struct_id) => { - for field_type_id in db.struct_all_fields(struct_id).into_iter() { + for field_type_id in db.struct_all_fields(struct_id).iter() { // assume all type is correct. let field_type = db.struct_field_type(*field_type_id).value.unwrap(); if !(field_type).is_zero_sized(db) { return false; } } - return true; + true } Type::Contract(contract_id) => { - for field_type_id in db.contract_all_fields(contract_id).into_iter() { + for field_type_id in db.contract_all_fields(contract_id).iter() { let field_type = db.contract_field_type(*field_type_id).value.unwrap(); if !(field_type).is_zero_sized(db) { return false; } } - return true; + true } Type::Generic(_) | Type::Map(_) | Type::SelfContract(_) => false, } From 3e5f7a527cb7d88e3222c2e34dc21c694fd2f8ad Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 12 Aug 2022 02:08:16 +0700 Subject: [PATCH 07/11] rustfmt --- crates/analyzer/src/db/queries/types.rs | 9 ++------- crates/analyzer/src/namespace/types.rs | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/analyzer/src/db/queries/types.rs b/crates/analyzer/src/db/queries/types.rs index 2b90b98fcf..4332803d71 100644 --- a/crates/analyzer/src/db/queries/types.rs +++ b/crates/analyzer/src/db/queries/types.rs @@ -7,7 +7,7 @@ use crate::db::Analysis; use crate::errors::TypeError; use crate::namespace::items::{FunctionSigId, ImplId, TraitId, TypeAliasId}; use crate::namespace::scopes::ItemScope; -use crate::namespace::types::{self, TypeId, Array, Tuple, Type, FeString, Base}; +use crate::namespace::types::{self, Array, Base, FeString, Tuple, Type, TypeId}; use crate::traversal::types::type_desc; use crate::AnalyzerDb; @@ -107,12 +107,7 @@ pub fn is_zero_sized(db: &dyn AnalyzerDb, ty: types::TypeId) -> bool { } } - // because we already catch this error so this should be empty -pub fn is_zero_sized_cycle( - _db: &dyn AnalyzerDb, - _cycle: &[String], - _ty: &types::TypeId, -) -> bool { +pub fn is_zero_sized_cycle(_db: &dyn AnalyzerDb, _cycle: &[String], _ty: &types::TypeId) -> bool { true } diff --git a/crates/analyzer/src/namespace/types.rs b/crates/analyzer/src/namespace/types.rs index ac625531dd..cae3a37f5e 100644 --- a/crates/analyzer/src/namespace/types.rs +++ b/crates/analyzer/src/namespace/types.rs @@ -496,7 +496,7 @@ impl Type { } false } - + /// Creates an instance of bool. pub fn bool() -> Self { Type::Base(Base::Bool) From e271b56c631e7f9a3950af5aaa2d2808dc62aa7e Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Fri, 12 Aug 2022 02:29:30 +0700 Subject: [PATCH 08/11] contract field in event always have size --- crates/analyzer/src/db/queries/types.rs | 11 +--- ...ors__invalid_type_in_event_zero_sized.snap | 58 ++++++++----------- .../invalid_type_in_event_zero_sized.fe | 11 +--- 3 files changed, 27 insertions(+), 53 deletions(-) diff --git a/crates/analyzer/src/db/queries/types.rs b/crates/analyzer/src/db/queries/types.rs index 4332803d71..9f2e8310a6 100644 --- a/crates/analyzer/src/db/queries/types.rs +++ b/crates/analyzer/src/db/queries/types.rs @@ -94,16 +94,7 @@ pub fn is_zero_sized(db: &dyn AnalyzerDb, ty: types::TypeId) -> bool { } true } - Type::Contract(contract_id) => { - for field_type_id in db.contract_all_fields(contract_id).iter() { - let field_type = db.contract_field_type(*field_type_id).value.unwrap(); - if !(field_type).is_zero_sized(db) { - return false; - } - } - true - } - Type::Generic(_) | Type::Map(_) | Type::SelfContract(_) => false, + Type::Generic(_) | Type::Map(_) | Type::SelfContract(_) | Type::Contract(_) => false, } } diff --git a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap index 56834cc459..f7bd924e59 100644 --- a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap +++ b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap @@ -2,82 +2,70 @@ source: crates/analyzer/tests/errors.rs expression: "error_string(&path, test_files::fixture(path))" --- -error: feature not yet implemented: contract types aren't yet supported as struct fields - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:14:5 - │ -14 │ y: EmptyContract - │ ^^^^^^^^^^^^^^^^ not yet implemented - error: recursive struct `Foo` - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:17:8 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:12:8 │ -17 │ struct Foo { +12 │ struct Foo { │ ^^^ struct `Foo` has infinite size due to recursive definition error: recursive struct `Baz` - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:21:8 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:16:8 │ -21 │ struct Baz { +16 │ struct Baz { │ ^^^ struct `Baz` has infinite size due to recursive definition error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:27:13 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:22:13 │ -27 │ idx a : () +22 │ idx a : () │ ^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:28:13 - │ -28 │ idx b : EmptyContract - │ ^^^^^^^^^^^^^ this type can't be used as an event field - -error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:29:13 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:24:13 │ -29 │ idx c : EmptyStruct +24 │ idx c : EmptyStruct │ ^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:34:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:29:12 │ -34 │ idx b: ((), EmptyContract, EmptyStruct) - │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this type can't be used as an event field +29 │ idx b: ((), EmptyStruct) + │ ^^^^^^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:35:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:30:12 │ -35 │ idx c: Array +30 │ idx c: Array │ ^^^^^^^^^^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:39:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:34:12 │ -39 │ idx a: Array<(), 0> +34 │ idx a: Array<(), 0> │ ^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:40:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:35:12 │ -40 │ idx b: Array +35 │ idx b: Array │ ^^^^^^^^^^^^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:44:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:39:12 │ -44 │ idx a: Array<(), 0> +39 │ idx a: Array<(), 0> │ ^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:45:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:40:12 │ -45 │ idx b: AnotherEmpty +40 │ idx b: AnotherEmpty │ ^^^^^^^^^^^^ this type can't be used as an event field error: event field type must have a non-zero types - ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:52:12 + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:47:12 │ -52 │ idx f: Foo +47 │ idx f: Foo │ ^^^ this type can't be used as an event field diff --git a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe index 52806ba41c..bffb4f74c7 100644 --- a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe +++ b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe @@ -1,17 +1,12 @@ struct EmptyStruct {} -contract EmptyContract {} +contract Contract {} struct UnEmptyStruct { v: u32 } -contract UnEmptyContract { - u: u256 -} - struct AnotherEmpty { x: EmptyStruct - y: EmptyContract } struct Foo { @@ -25,13 +20,13 @@ struct Baz { event FirstCase { idx a : () - idx b : EmptyContract + idx b : Contract idx c : EmptyStruct } event SecondCase { idx a: u256 - idx b: ((), EmptyContract, EmptyStruct) + idx b: ((), EmptyStruct) idx c: Array } From 1db7920789ca0d349ee621fd36fa45d6cb686034 Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Sat, 13 Aug 2022 00:48:50 +0700 Subject: [PATCH 09/11] throw error when use invalid type in event --- crates/analyzer/src/db/queries/events.rs | 44 ++++++++++++------- ...ors__invalid_type_in_event_zero_sized.snap | 6 +++ .../invalid_type_in_event_zero_sized.fe | 5 +++ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/crates/analyzer/src/db/queries/events.rs b/crates/analyzer/src/db/queries/events.rs index 1b3ec853ab..21db167fd5 100644 --- a/crates/analyzer/src/db/queries/events.rs +++ b/crates/analyzer/src/db/queries/events.rs @@ -39,24 +39,34 @@ pub fn event_type(db: &dyn AnalyzerDb, event: EventId) -> Analysis { - if *is_idx && typ.is_zero_sized(db) { - Err(TypeError::new(scope.error( - "event field type must have a non-zero types", + let typ = + type_desc(&mut scope, typ_node).and_then(|typ| match db.lookup_intern_type(typ) { + types::Type::Generic(_) + | types::Type::Map(_) + | types::Type::SelfContract(_) => Err(TypeError::new(scope.error( + "event field type is invalid", + typ_node.span, + "this type can't be used as an event field", + ))), + _ => match typ { + typ if typ.has_fixed_size(scope.db()) => { + if *is_idx && typ.is_zero_sized(db) { + Err(TypeError::new(scope.error( + "event field type must have a non-zero types", + typ_node.span, + "this type can't be used as an event field", + ))) + } else { + Ok(typ) + } + } + _ => Err(TypeError::new(scope.error( + "event field type must have a fixed size", typ_node.span, - "this type can't be used as an event field", - ))) - } else { - Ok(typ) - } - } - _ => Err(TypeError::new(scope.error( - "event field type must have a fixed size", - typ_node.span, - "this can't be used as an event field", - ))), - }); + "this can't be used as an event field", + ))), + }, + }); // If we've already seen the max number of indexed fields, // ignore the `idx` qualifier on this one. We'll emit an error below. diff --git a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap index f7bd924e59..856f2c0e71 100644 --- a/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap +++ b/crates/analyzer/tests/snapshots/errors__invalid_type_in_event_zero_sized.snap @@ -68,4 +68,10 @@ error: event field type must have a non-zero types 47 │ idx f: Foo │ ^^^ this type can't be used as an event field +error: event field type is invalid + ┌─ compile_errors/invalid_type_in_event_zero_sized.fe:52:8 + │ +52 │ b: Map + │ ^^^^^^^^^^^^^^ this type can't be used as an event field + diff --git a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe index bffb4f74c7..d62f75c02d 100644 --- a/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe +++ b/crates/test-files/fixtures/compile_errors/invalid_type_in_event_zero_sized.fe @@ -45,4 +45,9 @@ event SixthCase { idx d: UnEmptyStruct idx e: ((), UnEmptyStruct) idx f: Foo +} + +event SeventhCase { + idx a: u256 + b: Map } \ No newline at end of file From 382d3a0d5c9331c0fbd4fea0aa1db460b6ac31ee Mon Sep 17 00:00:00 2001 From: Vu Vo Date: Sat, 13 Aug 2022 01:26:49 +0700 Subject: [PATCH 10/11] magic --- crates/common/src/panic.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/common/src/panic.rs b/crates/common/src/panic.rs index eccfbd8a7c..83736b1e09 100644 --- a/crates/common/src/panic.rs +++ b/crates/common/src/panic.rs @@ -1,13 +1,13 @@ use once_cell::sync::Lazy; use std::panic; +type PanicHook = dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static; const BUG_REPORT_URL: &str = "https://github.com/ethereum/fe/issues/new"; -static DEFAULT_PANIC_HOOK: Lazy) + Sync + Send + 'static>> = - Lazy::new(|| { - let hook = panic::take_hook(); - panic::set_hook(Box::new(report_ice)); - hook - }); +static DEFAULT_PANIC_HOOK: Lazy> = Lazy::new(|| { + let hook = panic::take_hook(); + panic::set_hook(Box::new(report_ice)); + hook +}); pub fn install_panic_hook() { Lazy::force(&DEFAULT_PANIC_HOOK); From 9131fce4a6b0857f0ee4b3ceeecfda25e283156a Mon Sep 17 00:00:00 2001 From: Vu Date: Fri, 2 Sep 2022 23:04:26 +0700 Subject: [PATCH 11/11] Update crates/analyzer/src/db/queries/events.rs Co-authored-by: Yoshitomo Nakanishi --- crates/analyzer/src/db/queries/events.rs | 44 +++++++++--------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/crates/analyzer/src/db/queries/events.rs b/crates/analyzer/src/db/queries/events.rs index 21db167fd5..529f32941c 100644 --- a/crates/analyzer/src/db/queries/events.rs +++ b/crates/analyzer/src/db/queries/events.rs @@ -39,34 +39,24 @@ pub fn event_type(db: &dyn AnalyzerDb, event: EventId) -> Analysis Err(TypeError::new(scope.error( - "event field type is invalid", - typ_node.span, - "this type can't be used as an event field", - ))), - _ => match typ { - typ if typ.has_fixed_size(scope.db()) => { - if *is_idx && typ.is_zero_sized(db) { - Err(TypeError::new(scope.error( - "event field type must have a non-zero types", - typ_node.span, - "this type can't be used as an event field", - ))) - } else { - Ok(typ) - } - } - _ => Err(TypeError::new(scope.error( - "event field type must have a fixed size", + let typ = type_desc(&mut scope, typ_node).and_then(|typ| match typ { + typ if typ.has_fixed_size(scope.db()) => { + if *is_idx && typ.is_zero_sized(db) { + Err(TypeError::new(scope.error( + "expected a non zero sized type for an indexed event field", typ_node.span, - "this can't be used as an event field", - ))), - }, - }); + "this must be a non zero sized type", + ))) + } else { + Ok(typ) + } + } + _ => Err(TypeError::new(scope.error( + "event field type must have a fixed size", + typ_node.span, + "this can't be used as an event field", + ))), + }) // If we've already seen the max number of indexed fields, // ignore the `idx` qualifier on this one. We'll emit an error below.