Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for nested tuples #427

Closed
Y-Nak opened this issue May 29, 2021 · 4 comments
Closed

Add support for nested tuples #427

Y-Nak opened this issue May 29, 2021 · 4 comments

Comments

@Y-Nak
Copy link
Member

Y-Nak commented May 29, 2021

What is wrong?

contract Foo:
    def foo():
        x: (u256, (u256, u256)) = (0, (1, 2))

causes thread 'main' panicked at 'not yet implemented', compiler/src/lowering/names.rs:38:32

Backtrace
thread 'main' panicked at 'not yet implemented', compiler/src/lowering/names.rs:38:32
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:50:5
   3: fe_compiler::lowering::names::fixed_size_type_desc
             at ./compiler/src/lowering/names.rs:38:32
   4: fe_compiler::lowering::mappers::module::tuple_to_struct_def::{{closure}}
             at ./compiler/src/lowering/mappers/module.rs:43:62
   5: core::iter::adapters::map::map_fold::{{closure}}
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:82:28
   6: <core::iter::adapters::enumerate::Enumerate<I> as core::iter::traits::iterator::Iterator>::fold::enumerate::{{closure}}
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/enumerate.rs:104:27
   7: core::iter::traits::iterator::Iterator::fold
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2123:21
   8: <core::iter::adapters::enumerate::Enumerate<I> as core::iter::traits::iterator::Iterator>::fold
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/enumerate.rs:110:9
   9: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:122:9
  10: core::iter::traits::iterator::Iterator::for_each
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:775:9
  11: <alloc::vec::Vec<T,A> as alloc::vec::spec_extend::SpecExtend<T,I>>::spec_extend
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_extend.rs:42:17
  12: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter_nested.rs:53:9
  13: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter.rs:36:9
  14: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:2401:9
  15: core::iter::traits::iterator::Iterator::collect
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1764:9
  16: fe_compiler::lowering::mappers::module::tuple_to_struct_def
             at ./compiler/src/lowering/mappers/module.rs:37:18
  17: fe_compiler::lowering::mappers::module::module::{{closure}}
             at ./compiler/src/lowering/mappers/module.rs:28:32
  18: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:280:13
  19: core::option::Option<T>::map
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:487:29
  20: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::next
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:101:9
  21: alloc::vec::Vec<T,A>::extend_desugared
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:2496:35
  22: <alloc::vec::Vec<T,A> as alloc::vec::spec_extend::SpecExtend<T,I>>::spec_extend
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_extend.rs:18:9
  23: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter_nested.rs:37:9
  24: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter.rs:36:9
  25: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:2401:9
  26: core::iter::traits::iterator::Iterator::collect
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1764:9
  27: fe_compiler::lowering::mappers::module::module
             at ./compiler/src/lowering/mappers/module.rs:25:35
  28: fe_compiler::lowering::lower
             at ./compiler/src/lowering/mod.rs:12:5
  29: fe_compiler::compile
             at ./compiler/src/lib.rs:51:29
  30: fe::main
             at ./src/main.rs:179:33
  31: core::ops::function::FnOnce::call_once
             at /home/y_nak/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

You've hit an internal compiler error. This is a bug in the Fe compiler.
Fe is still under heavy development, and isn't yet ready for production use.

How can it be fixed

Lower tuples recursively.

@Y-Nak Y-Nak changed the title Allow nested tuples Add support for nested tuples May 29, 2021
@mjobuda
Copy link
Contributor

mjobuda commented Jun 19, 2021

could replicate this.
I did some experiments in lowering/names.rs.
The crash was in

pub fn fixed_size_type_desc(typ: &FixedSize) -> fe::TypeDesc {
    match typ {
...
...
FixedSize::Tuple(_) => todo!()

While not fully understanding Rust nor the way this compiler works but I implemented it somehow.
Now the behaviour is that nested Tuple like
x: (u256,(u256, u256)) = (0,(0,0))
crashes with an AnalyzerError ...

"tuple_u256_tuple_u256_u256 expects 1 argument, but 2 were provided"`

So this is what the lowering generated with my changes. I don't know whether this is the supposed result that the lowering should generate.
Maybe somebody with a better understanding of the supposed Fe compiler functionality can answer this.
The next nested tuple i tried is:
x: (u256,(u256, u256),(u256, u256)) = (0,(0,0),(0,0))
This crashed with:
"tuple_u256_tuple_u256_u256_tuple_u256_u256 expects 1 argument, but 3 were provided"`
Is this the right way Tuples are to be represented for YUL?

My implementaion of FixedSize::Tuple(_) => todo!()

:

FixedSize::Tuple(tuple) => fe::TypeDesc::Tuple {
            items: {
                let mut v1: Vec1<Node<fe::TypeDesc>> =
                    Vec1::new(fixed_size_type_desc(tuple.items.first()).into_node());
                for item in tuple.items.iter().skip(1) {
                    v1.push(fixed_size_type_desc(&item).into_node())
                }
                Vec1::from(v1)
            },

The full Backtraces of the mentioned nested Tuples:

(base) mmm@ttt:~/fe$ ./target/debug/fe --overwrite ./tests/fixtures/features/nested_tuple.fe 
thread 'main' panicked at 'failed to analyze lowered AST: AnalyzerError([Diagnostic { severity: Error, code: None, message: "feature not yet implemented", labels: [Label { style: Primary, file_id: SourceFileId(333005103741714625151580942366672813312), range: 0..0, message: "non-base type struct fields is not yet implemented" }], notes: [] }, Diagnostic { severity: Error, code: None, message: "`tuple_u256_tuple_u256_u256` expects 1 argument, but 2 were provided", labels: [Label { style: Primary, file_id: SourceFileId(333005103741714625151580942366672813312), range: 62..71, message: "expects 1 argument" }, Label { style: Secondary, file_id: SourceFileId(333005103741714625151580942366672813312), range: 63..64, message: "" }, Label { style: Secondary, file_id: SourceFileId(333005103741714625151580942366672813312), range: 65..70, message: "supplied 2 arguments" }], notes: [] }])', compiler/src/lib.rs:55:59
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

You've hit an internal compiler error. This is a bug in the Fe compiler.
Fe is still under heavy development, and isn't yet ready for production use.

If you would, please report this bug at the following URL:
  https://github.com/ethereum/fe/issues/new
(base) mmm@ttt:~/fe$ ./target/debug/fe --overwrite ./tests/fixtures/features/nested_tuple.fe 
thread 'main' panicked at 'failed to analyze lowered AST: AnalyzerError([Diagnostic { severity: Error, code: None, message: "feature not yet implemented", labels: [Label { style: Primary, file_id: SourceFileId(194361644908539828904080200297581464859), range: 0..0, message: "non-base type struct fields is not yet implemented" }], notes: [] }, Diagnostic { severity: Error, code: None, message: "feature not yet implemented", labels: [Label { style: Primary, file_id: SourceFileId(194361644908539828904080200297581464859), range: 0..0, message: "non-base type struct fields is not yet implemented" }], notes: [] }, Diagnostic { severity: Error, code: None, message: "`tuple_u256_tuple_u256_u256_tuple_u256_u256` expects 1 argument, but 3 were provided", labels: [Label { style: Primary, file_id: SourceFileId(194361644908539828904080200297581464859), range: 75..90, message: "expects 1 argument" }, Label { style: Secondary, file_id: SourceFileId(194361644908539828904080200297581464859), range: 76..77, message: "" }, Label { style: Secondary, file_id: SourceFileId(194361644908539828904080200297581464859), range: 78..83, message: "" }, Label { style: Secondary, file_id: SourceFileId(194361644908539828904080200297581464859), range: 84..89, message: "supplied 3 arguments" }], notes: [] }])', compiler/src/lib.rs:55:59
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

You've hit an internal compiler error. This is a bug in the Fe compiler.
Fe is still under heavy development, and isn't yet ready for production use.

If you would, please report this bug at the following URL:
  https://github.com/ethereum/fe/issues/new

@sbillig
Copy link
Collaborator

sbillig commented Jun 22, 2021

Hey @mjobuda, sorry, I didn't notice you were looking into this. I implemented the lowering part of this in #459, because I was doing some nearby tuple-related refactoring, and I couldn't help myself. The resulting lowered code still won't compile, because it has nested structs which aren't supported yet (which maybe you're already working on in #465 🤘)

Eg (u8, (u16, u32)) becomes

struct tuple_u16_u32_:
  item0: u16
  item1: u32

struct tuple_u8_tuple_u16_u32__:
  item0: u8
  item1: tuple_u16_u32_

@mjobuda
Copy link
Contributor

mjobuda commented Jun 24, 2021

@sbillig exactly, in order to have nested tuples, nested structs must work(that's how I understand it after I implemented the strings in the struct fileds as part of #465 ).
Did I understand it right that in #459 you have implemented the lowering of the left side of expressions like:
x: (u16,(u8, u256)) = (1,(2,3))
?
And what is missing to get nested tuples to work is lowering the right side and getting the nested structs to work?

@Y-Nak
Copy link
Member Author

Y-Nak commented Feb 8, 2022

Resolved in #459 and #642

@Y-Nak Y-Nak closed this as completed Feb 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants