Self referential struct crashes nargo process
Closed this issue · 4 comments
grasshopper47 commented
Aim
To create a self referential struct in a slice member
struct SelfReferential
{
prop : [SelfReferential]
}
and use it in a test
#[test]
unconstrained
fn test_self_referential()
{
let self_ref = SelfReferential { prop : [] };
}
Expected Behavior
Should work as intended.
Bug
Nargo process crashes during test execution
Testing test_self_referential...
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
To Reproduce
- Create file with code above
- Run
nargo test
Installation Method
Binary
Nargo Version
0.19.2+d7f919dcc001080ed24616ebbc37426ef7ac7638
Additional Context
No response
Would you like to submit a PR for this Issue?
No
Support Needs
No response
Deleted user commented
Backtrace:
[hello] Running 1 test functions
[hello] Testing test_self_referential... Stack Overflow:
0: backtrace_on_stack_overflow::handle_sigsegv
at /home/work/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-on-stack-overflow-0.3.0/src/lib.rs:94:40
1: wasmer_vm::trap::traphandlers::trap_handler
at /home/work/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasmer-vm-4.2.3/src/trap/traphandlers.rs:288:17
2: <unknown>
3: alloc::vec::Vec<T,A>::len
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/alloc/src/vec/mod.rs:2050:9
noirc_frontend::hir_def::types::StructType::get_fields
at noir/compiler/noirc_frontend/src/hir_def/types.rs:234:20
4: noirc_frontend::monomorphization::Monomorphizer::convert_type
at noir/compiler/noirc_frontend/src/monomorphization/mod.rs:748:30
5: noirc_frontend::monomorphization::Monomorphizer::convert_type
at noir/compiler/noirc_frontend/src/monomorphization/mod.rs:696:40
6: noirc_frontend::monomorphization::Monomorphizer::convert_type::{{closure}}
at noir/compiler/noirc_frontend/src/monomorphization/mod.rs:749:58
core::iter::adapters::map::map_fold::{{closure}}
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/adapters/map.rs:84:28
core::iter::traits::iterator::Iterator::fold
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/traits/iterator.rs:2481:21
<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/adapters/map.rs:124:9
7: core::iter::traits::iterator::Iterator::for_each
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/traits/iterator.rs:856:9
alloc::vec::Vec<T,A>::extend_trusted
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/alloc/src/vec/mod.rs:2843:17
<alloc::vec::Vec<T,A> as alloc::vec::spec_extend::SpecExtend<T,I>>::spec_extend
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/alloc/src/vec/spec_extend.rs:26:9
<alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/alloc/src/vec/spec_from_iter_nested.rs:62:9
8: alloc::vec::in_place_collect::<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/alloc/src/vec/in_place_collect.rs:167:20
<alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/alloc/src/vec/mod.rs:2711:9
core::iter::traits::iterator::Iterator::collect
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/traits/iterator.rs:1895:9
iter_extended::vecmap
at noir/compiler/utils/iter-extended/src/lib.rs:14:5
noirc_frontend::monomorphization::Monomorphizer::convert_type
at noir/compiler/noirc_frontend/src/monomorphization/mod.rs:749:30
9: noirc_frontend::monomorphization::Monomorphizer::convert_type
at noir/compiler/noirc_frontend/src/monomorphization/mod.rs:696:40
10: noirc_frontend::monomorphization::Monomorphizer::convert_type::{{closure}}
at noir/compiler/noirc_frontend/src/monomorphization/mod.rs:749:58
core::iter::adapters::map::map_fold::{{closure}}
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/adapters/map.rs:84:28
core::iter::traits::iterator::Iterator::fold
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/traits/iterator.rs:2481:21
<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
at /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/iter/adapters/map.rs:124:9
jfecher commented
We'll need a test in the frontend to prevent constructing recursive types. This can be done when defining a new struct type.
michaeljklein commented
Current approach:
resolve_struct_fields
in theresolver
callsresolve_type -> resolve_type_inner(Named(..)) -> resolve_named_type ..
- Check the
current_item
somewhere aroundresolve_named_type
, which I believe would be the in-resolution struct that's self-referential.
michaeljklein commented
The given test case is currently failing with:
error: Nested slices are not supported
┌─ /Users/michaelklein/Coding/rust/noir/test_programs/compile_failure/self_referential_struct/src/main.nr:1:1
│
1 │ ╭ struct SelfReferential
2 │ │ {
3 │ │ prop : [SelfReferential]
4 │ │ }
│ ╰─' Try to use a constant sized array instead
│
Using the following results in a stack overflow:
struct SelfReferential
{
prop : Option<SelfReferential>
}
#[test]
unconstrained
fn test_self_referential()
{
let self_ref = SelfReferential { prop : Option::none() };
}