amethyst/legion

Question: How to make a mutable query inside a query?

swwind opened this issue · 5 comments

Here is a minimal example, I have two components which is Monster { damage: u32 } and Player { health: u32 }. Every game tick, every Monster will attack every Player. I wrote the example code as blow.

extern crate legion;

use legion::*;
use legion::world::SubWorld;

struct Monster { damage: u32 }
struct Player { health: u32 }

#[system(for_each)]
fn calculate_damage(world: &mut SubWorld, monster: &Monster) {
  for player in <&mut Player>::query().iter_mut(world) {
    player.health -= monster.damage;
  }
}

fn main() {
  let mut world = World::default();

  world.push((Player { health: 114 },));
  world.push((Player { health: 514 },));
  world.push((Monster { damage: 19 },));
  world.push((Monster { damage: 19 },));

  let mut schedule = Schedule::builder()
    .add_system(calculate_damage_system())
    .build();

  let mut resources = Resources::default();

  schedule.execute(&mut world, &mut resources);
}

However, the code doesn't seem to work.

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: AccessDenied', /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:345:65
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
RUST_BACKTRACE=1 cargo run
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: AccessDenied', /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:345:65
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::option::expect_none_failed
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/option.rs:1329:5
   3: core::result::Result<T,E>::unwrap
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1037:23
   4: legion::internals::query::Query<V,F>::iter_chunks_unchecked
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:345:24
   5: legion::internals::query::Query<V,F>::iter_unchecked
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:489:9
   6: legion::internals::query::Query<V,F>::iter_mut
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:516:18
   7: legion_test::calculate_damage
             at ./src/main.rs:11:17
   8: legion_test::calculate_damage_system::{{closure}}::{{closure}}
             at ./src/main.rs:9:1
   9: legion::internals::query::Query<V,F>::for_each_unchecked
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:685:17
  10: legion::internals::query::Query<V,F>::for_each_mut
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:718:18
  11: legion_test::calculate_damage_system::{{closure}}
             at ./src/main.rs:9:1
  12: <F as legion::internals::systems::system::SystemFn<R,Q>>::run
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/system.rs:222:9
  13: <legion::internals::systems::system::System<R,Q,F> as legion::internals::systems::schedule::Runnable>::run_unsafe
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/system.rs:193:9
  14: legion::internals::systems::schedule::Executor::run_systems
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/schedule.rs:322:21
  15: legion::internals::systems::schedule::Schedule::execute::{{closure}}::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/schedule.rs:554:28
  16: rayon_core::join::join::call::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/join/mod.rs:102:18
  17: rayon_core::join::join_context::call_a::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/join/mod.rs:124:17
  18: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  19: std::panicking::try::do_call
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  20: __rust_try
  21: std::panicking::try
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  22: std::panic::catch_unwind
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  23: rayon_core::unwind::halt_unwinding
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/unwind.rs:17:5
  24: rayon_core::join::join_context::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/join/mod.rs:141:24
  25: rayon_core::registry::Registry::in_worker_cold::{{closure}}::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:465:21
  26: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::call::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/job.rs:113:21
  27: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  28: std::panicking::try::do_call
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  29: __rust_try
  30: std::panicking::try
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  31: std::panic::catch_unwind
             at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  32: rayon_core::unwind::halt_unwinding
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/unwind.rs:17:5
  33: <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/job.rs:119:38
  34: rayon_core::job::JobRef::execute
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/job.rs:59:9
  35: rayon_core::registry::WorkerThread::execute
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:749:9
  36: rayon_core::registry::WorkerThread::wait_until_cold
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:726:17
  37: rayon_core::registry::WorkerThread::wait_until
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:700:13
  38: rayon_core::registry::main_loop
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:833:5
  39: rayon_core::registry::ThreadBuilder::run
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:55:18
  40: <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}
             at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:100:20
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
RUST_BACKTRACE=full cargo run
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: AccessDenied', /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:345:65
stack backtrace:
   0:     0x5625c21a18a0 - std::backtrace_rs::backtrace::libunwind::trace::h63b7a90188ab5fb3
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/../../backtrace/src/backtrace/libunwind.rs:90:5
   1:     0x5625c21a18a0 - std::backtrace_rs::backtrace::trace_unsynchronized::h80aefbf9b851eca7
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5625c21a18a0 - std::sys_common::backtrace::_print_fmt::hbef05ae4237a4d72
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x5625c21a18a0 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h28abce2fdb9884c2
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/sys_common/backtrace.rs:46:22
   4:     0x5625c21b8e8f - core::fmt::write::h3b84512577ca38a8
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/fmt/mod.rs:1092:17
   5:     0x5625c219fc82 - std::io::Write::write_fmt::h465f8feea02e2aa1
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/io/mod.rs:1572:15
   6:     0x5625c21a38d5 - std::sys_common::backtrace::_print::h525280ee0d29bdde
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/sys_common/backtrace.rs:49:5
   7:     0x5625c21a38d5 - std::sys_common::backtrace::print::h1f0f5b9f3ef8fb78
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/sys_common/backtrace.rs:36:9
   8:     0x5625c21a38d5 - std::panicking::default_hook::{{closure}}::ha5838f6faa4a5a8f
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:208:50
   9:     0x5625c21a3383 - std::panicking::default_hook::hfb9fe98acb0dcb3b
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:225:9
  10:     0x5625c21a3edd - std::panicking::rust_panic_with_hook::hb89f5f19036e6af8
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:591:17
  11:     0x5625c21a3a77 - std::panicking::begin_panic_handler::{{closure}}::h119e7951427f41da
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:497:13
  12:     0x5625c21a1d5c - std::sys_common::backtrace::__rust_end_short_backtrace::hce386c44bf47a128
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/sys_common/backtrace.rs:141:18
  13:     0x5625c21a39d9 - rust_begin_unwind
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:493:5
  14:     0x5625c2068391 - core::panicking::panic_fmt::h2242888e8769cd33
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:92:14
  15:     0x5625c2068283 - core::option::expect_none_failed::hb1edf11f73e63728
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/option.rs:1329:5
  16:     0x5625c20afda2 - core::result::Result<T,E>::unwrap::h9f218d8433561596
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1037:23
  17:     0x5625c2072e74 - legion::internals::query::Query<V,F>::iter_chunks_unchecked::h1d226789389baef4
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:345:24
  18:     0x5625c2072a5b - legion::internals::query::Query<V,F>::iter_unchecked::hf7d46d7dd2ed2f23
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:489:9
  19:     0x5625c20737da - legion::internals::query::Query<V,F>::iter_mut::hd82c9398eb1716da
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:516:18
  20:     0x5625c2074018 - legion_test::calculate_damage::h97df263307b92877
                               at /home/swwind/Repository/legion-test/src/main.rs:11:17
  21:     0x5625c2073e76 - legion_test::calculate_damage_system::{{closure}}::{{closure}}::h52b714717d2e83ef
                               at /home/swwind/Repository/legion-test/src/main.rs:9:1
  22:     0x5625c2072d62 - legion::internals::query::Query<V,F>::for_each_unchecked::h0c84352243f25f01
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:685:17
  23:     0x5625c2071c07 - legion::internals::query::Query<V,F>::for_each_mut::h1d8c813491a550ab
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/query/mod.rs:718:18
  24:     0x5625c2073f52 - legion_test::calculate_damage_system::{{closure}}::h9b54ab42b51c547b
                               at /home/swwind/Repository/legion-test/src/main.rs:9:1
  25:     0x5625c2073888 - <F as legion::internals::systems::system::SystemFn<R,Q>>::run::h7b0ca16ebe7df57c
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/system.rs:222:9
  26:     0x5625c208f6c9 - <legion::internals::systems::system::System<R,Q,F> as legion::internals::systems::schedule::Runnable>::run_unsafe::h742b1517654bde45
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/system.rs:193:9
  27:     0x5625c20d0292 - legion::internals::systems::schedule::Executor::run_systems::ha4cc9c5fe4e033fb
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/schedule.rs:322:21
  28:     0x5625c20d122e - legion::internals::systems::schedule::Schedule::execute::{{closure}}::{{closure}}::hd1c8df0cf8870a8d
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/systems/schedule.rs:554:28
  29:     0x5625c20e23f1 - rayon_core::join::join::call::{{closure}}::h04e69e2378d53f36
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/join/mod.rs:102:18
  30:     0x5625c20e1e33 - rayon_core::join::join_context::call_a::{{closure}}::haacf008a64b0a77b
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/join/mod.rs:124:17
  31:     0x5625c20b2062 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h8b3d218e10b4fcc9
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  32:     0x5625c20db694 - std::panicking::try::do_call::h570b832d014d5c5a
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  33:     0x5625c20dfa2d - __rust_try
  34:     0x5625c20db3c0 - std::panicking::try::hf808e163003562a8
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  35:     0x5625c20b4772 - std::panic::catch_unwind::h02eb69c9cc32814a
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  36:     0x5625c20c66da - rayon_core::unwind::halt_unwinding::h1fb3124abbc2cdd1
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/unwind.rs:17:5
  37:     0x5625c20e1758 - rayon_core::join::join_context::{{closure}}::h9239d45365db92a4
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/join/mod.rs:141:24
  38:     0x5625c20ef4df - rayon_core::registry::Registry::in_worker_cold::{{closure}}::{{closure}}::h135ba00699deb49d
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:465:21
  39:     0x5625c20ba1b7 - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::call::{{closure}}::h5b52fbb9376ab2eb
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/job.rs:113:21
  40:     0x5625c20b2159 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::hc7076e8b068555a2
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  41:     0x5625c20db63a - std::panicking::try::do_call::h3ec29b605d7ee99a
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  42:     0x5625c20dfa2d - __rust_try
  43:     0x5625c20dab6a - std::panicking::try::h8e2453d9544e5a8b
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  44:     0x5625c20b48b9 - std::panic::catch_unwind::h580253a1673a0bcc
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  45:     0x5625c20c6a47 - rayon_core::unwind::halt_unwinding::hdbcf2a4ba6575d3a
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/unwind.rs:17:5
  46:     0x5625c20b9df2 - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::hdf19f7b319495ba3
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/job.rs:119:38
  47:     0x5625c21482ee - rayon_core::job::JobRef::execute::he708629b917e5820
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/job.rs:59:9
  48:     0x5625c21169ca - rayon_core::registry::WorkerThread::execute::h85c9f42ad8c6d3fb
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:749:9
  49:     0x5625c21166d4 - rayon_core::registry::WorkerThread::wait_until_cold::h100b9a95f5d57b7d
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:726:17
  50:     0x5625c2116419 - rayon_core::registry::WorkerThread::wait_until::h0f9509c7bb9bc5dc
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:700:13
  51:     0x5625c21171b8 - rayon_core::registry::main_loop::h6baeec2910183858
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:833:5
  52:     0x5625c2113d0d - rayon_core::registry::ThreadBuilder::run::h7ed51b0576d5886c
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:55:18
  53:     0x5625c211427d - <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}::ha61cf297d4e7c19a
                               at /home/swwind/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.9.1/src/registry.rs:100:20
  54:     0x5625c2145da0 - std::sys_common::backtrace::__rust_begin_short_backtrace::hbd3677042a68ba32
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:125:18
  55:     0x5625c21600bd - std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}}::he9dadfa1cb1636c4
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:474:17
  56:     0x5625c212a351 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h194ead026be08e02
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:344:9
  57:     0x5625c214317c - std::panicking::try::do_call::h642bbf7091ecc9db
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:379:40
  58:     0x5625c214586d - __rust_try
  59:     0x5625c2142f77 - std::panicking::try::hb0d87c51cd05cbe3
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:343:19
  60:     0x5625c212da31 - std::panic::catch_unwind::h2c0591b2f33ae739
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:431:14
  61:     0x5625c215f401 - std::thread::Builder::spawn_unchecked::{{closure}}::h465f41dc3ff363da
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:473:30
  62:     0x5625c2119fff - core::ops::function::FnOnce::call_once{{vtable.shim}}::he68c75d6d10843c7
                               at /home/swwind/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
  63:     0x5625c21a623a - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::hc444a77f8dd8d825
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/alloc/src/boxed.rs:1546:9
  64:     0x5625c21a623a - <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once::h8b68a0a9a2093dfc
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/alloc/src/boxed.rs:1546:9
  65:     0x5625c21a623a - std::sys::unix::thread::Thread::new::thread_start::hb95464447f61f48d
                               at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/sys/unix/thread.rs:71:17
  66:     0x7f697ae10299 - start_thread
  67:     0x7f697abed053 - clone
  68:                0x0 - <unknown>

If I make the query myself, I found the code works iff both two queries are immutable.

for monster in <&Monster>::query().iter(&world) {
  for player in <&Player>::query().iter(&world) {
    println!("make {} damage to {}", monster.damage, player.health);
  }
}

And if I change the second query into &mut Player, the code doesn't compile since I can't borrow world as mutable while borrowing as immutable.

for monster in <&Monster>::query().iter(&world) {
  for player in <&mut Player>::query().iter_mut(&mut world) {
    player.health -= monster.damage;
  }
}
   |
32 | for monster in <&Monster>::query().iter(&world) {
   |                --------------------------------
   |                |                        |
   |                |                        immutable borrow occurs here
   |                immutable borrow later used here
33 |   for player in <&mut Player>::query().iter_mut(&mut world) {
   |                                                 ^^^^^^^^^^ mutable borrow occurs here

How can I solve this problem? Heartfelt thanks.

All right, I got my solution.

@swwind could you please share your solution here?

@zedrian

Since we can't make a mutable query inside a query, we can only make them separately.

In my example case, I just cloned the result of <&Monster>::query into a vector, and then we can make a mutable query to Player and use my stored Monster data.

#[derive(Clone)]
struct Monster { damage: u32 }
struct Player { health: u32 }

#[system]
#[read_component(Monster)]
#[write_component(Player)]
fn calculate_damage(world: &mut SubWorld) {
  let monsters: Vec<_> = <&Monster>::query().iter(world).cloned().collect();

  for player in <&mut Player>::query().iter_mut(world) {
    for monster in &monsters {
      player.health -= monster.damage;
    }
  }
}

Oh, I see. Thank you for the info!

@zedrian

Also you can use world.split_for_query if you are trying to make for-loops among two different components.

#[system]
#[read_component(Monster)]
#[write_component(Player)]
fn calculate_damage(world: &mut SubWorld) {
  let mut monster_query = <&Monster>::query();
  let mut player_query = <&mut Player>::query();
  // split the world apart
  let (monster_world, mut player_world) = world.split_for_query(&monster_query);

  for monster in monster_query.iter(&monster_world) {
    for player in player_query.iter_mut(&mut player_world) {
      player.health -= monster.damage;
      println!("player {} attacked {}", player.health, monster.damage);
    }
  }
}

However, if you are trying to make for-loop among the same component, this may fails.

Have fun. :P