resolution example
Guide for resolution example
Complete Resolution Example: SelectSpellEvent Type Mismatch
Overview
This document provides a complete, real-world example of resolving the duplicate
SelectSpellEvent compilation error and related issues. It demonstrates the systematic debugging workflow that successfully fixed all compilation errors in the magic system.Initial Error Report
error[E0308]: mismatched types
--> src/systems/ui/mod.rs:402:46
|
395 | spell_book_ui::render_magic_tab(
| ------------------------------- arguments to this function are incorrect
...
402 | &mut select_spell_writer,
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `systems::magic::SelectSpellEvent`,
| found `systems::skills::magic::SelectSpellEvent`Additional errors:
- Unused import
ItemIdininteractions.rs - Unnecessary parentheses in
ui/mod.rssystem registration - Missing
spell_dbargument inrender_magic_tabcall - Corrupted
ui_main_layoutfunction signature
Resolution Steps
Step 1: Identify Root Cause
Analysis: Two
SelectSpellEvent structs exist in different modules:src/systems/magic/mod.rs(line 64) - NEW magic systemsrc/systems/skills/magic.rs(line 83) - OLD skill-based magic
Decision: Use
systems::magic::SelectSpellEvent as the canonical version since it's part of the new dedicated magic module.Step 2: Fix Type Mismatch in UI
File:
src/systems/ui/mod.rsChange (line 245):
// Before
mut select_spell_writer: EventWriter<crate::systems::skills::magic::SelectSpellEvent>,
// After
mut select_spell_writer: EventWriter<crate::systems::magic::SelectSpellEvent>,Rationale: UI should use the new magic system's event type.
Step 3: Implement Missing Event Handler
Problem: The new
systems::magic module defined SelectSpellEvent but didn't have a handler for it.File:
src/systems/magic/cast_system.rsAdded imports (line 2):
use crate::systems::magic::{
SpellDatabase, CastSpellEvent, SpawnProjectileEvent, MantrasJson,
ActiveSpell, SelectSpellEvent // Added these two
};Added handler (appended to end of file):
pub fn handle_spell_selection(
mut commands: Commands,
mut events: EventReader<SelectSpellEvent>,
) {
for event in events.read() {
if let Some(spell_id) = &event.spell_id {
commands.entity(event.caster).insert(ActiveSpell {
spell_id: spell_id.clone(),
autocast: true,
last_cast_time: 0.0,
});
info!("Selected spell: {}", spell_id);
} else {
commands.entity(event.caster).remove::<ActiveSpell>();
info!("Cleared active spell");
}
}
}Step 4: Register New System
File:
src/systems/magic/mod.rsChange (line 105-106):
// Before
.add_systems(Update, (
cast_system::cast_spell_system,
projectile::magic_projectile_movement,
projectile::projectile_collision,
));
// After
.add_systems(Update, (
cast_system::cast_spell_system,
projectile::magic_projectile_movement,
projectile::projectile_collision,
cast_system::handle_spell_selection, // Added
));Step 5: Fix Lint Warnings
File:
src/systems/ui/mod.rsChange (line 84):
// Before
.add_systems(Update, (ui_main_layout))
// After
.add_systems(Update, ui_main_layout)File:
src/systems/player/interactions.rsChange (line 4):
// Before
use crate::systems::player::inventory::{UseItemEvent, ItemId};
// After
use crate::systems::player::inventory::{UseItemEvent};Step 6: Restore Corrupted Code
Problem: During editing,
ui_main_layout function signature was corrupted.File:
src/systems/ui/mod.rsRestored
UiParams struct (line 223):pub struct UiParams<'w, 's> {
pub ui_assets: Res<'w, UiAssets>,
pub interactables: Query<'w, 's, &'static crate::systems::api::Interactable>,
pub player_q: Query<'w, 's, (Entity, &'static crate::systems::player::skills::Skills, Option<&'static crate::systems::skills::magic::ActiveSpell>), With<crate::systems::player::Player>>,
pub skills_q: Query<'w, 's, &'static crate::systems::player::skills::Skills>,
pub inventory_q: Query<'w, 's, &'static crate::systems::player::inventory::Inventory>,
pub equipment_q: Query<'w, 's, &'static crate::systems::player::inventory::Equipment>,
pub skills_data: Res<'w, crate::systems::data::SkillsData>,
pub spell_db: Res<'w, crate::systems::magic::SpellDatabase>, // Added missing field
}Restored function signature (lines 238-247):
fn ui_main_layout(
mut contexts: EguiContexts,
mut ui_state: ResMut<UiState>,
mut combat_style_writer: EventWriter<CombatStyleEvent>,
editor_state: Option<Res<crate::systems::editor::EditorState>>,
mut last_interaction: Local<String>,
mut interaction_reader: EventReader<InteractionEvent>,
params: UiParams,
mut plugin_ui_state: ResMut<PluginUiState>,
mut use_item_writer: EventWriter<crate::systems::player::inventory::UseItemEvent>,
mut unequip_writer: EventWriter<crate::systems::player::equipment::UnequipItemEvent>,
// Magic UI params
mut spell_book_state: ResMut<spell_book_ui::SpellBookState>,
mut select_spell_writer: EventWriter<crate::systems::magic::SelectSpellEvent>,
mut cast_spell_writer: EventWriter<crate::systems::magic::CastSpellEvent>,
mut coconut_ui_state: ResMut<coconut_stacking_ui::CoconutUIState>,
) {
let ui_assets = params.ui_assets;
let interactables = params.interactables;
let player_q = params.player_q;
let skills_q = params.skills_q;
let inventory_q = params.inventory_q;
let equipment_q = params.equipment_q;
let skills_data = params.skills_data;
// ... rest of functionStep 7: Add Missing Argument
File:
src/systems/ui/mod.rsChange (lines 394-405):
// Before
spell_book_ui::render_magic_tab(
ui,
&mut spell_book_state,
&skills_data,
player_entity,
skills,
active_spell,
&mut select_spell_writer,
&mut cast_spell_writer,
&mut coconut_ui_state
);
// After
spell_book_ui::render_magic_tab(
ui,
&mut spell_book_state,
&skills_data,
player_entity,
skills,
active_spell,
&mut select_spell_writer,
&mut cast_spell_writer,
&mut coconut_ui_state,
¶ms.spell_db // Added missing argument
);Verification
After all fixes:
cargo checkResult: Compilation successful (with only minor warnings about unused variables, which are non-blocking).
Key Lessons
1. Systematic Approach
- Read error messages carefully
- Fix one error at a time
- Run
cargo checkafter each fix - Don't assume errors are independent
2. Type System Strictness
- Rust treats identically-named structs in different modules as completely different types
- Always verify import paths match the intended module
3. Event Handler Completeness
- Defining an event is not enough - you must also:
- Implement a handler system
- Register the system in the plugin
- Ensure the event writer uses the correct type
4. Code Corruption Recovery
- When function signatures get corrupted, check:
- All parameters are present
- Opening and closing braces match
- SystemParam structs have all required fields
5. Missing Arguments
- When adding new fields to structs, update ALL call sites
- Use compiler error messages to find missing arguments
- The compiler's "help:" suggestions are usually correct
Files Modified
src/systems/ui/mod.rs- Fixed event type, removed lint warnings, restored signature, added argumentsrc/systems/magic/cast_system.rs- Added imports andhandle_spell_selectionfunctionsrc/systems/magic/mod.rs- Registered new systemsrc/systems/player/interactions.rs- Removed unused import
Time to Resolution
- Initial error identification: ~5 minutes
- Root cause analysis: ~10 minutes
- Implementing fixes: ~15 minutes
- Debugging corrupted code: ~10 minutes
- Final verification: ~5 minutes
Total: ~45 minutes
Prevention for Future
- Before creating new events: Search for existing definitions
grep -r "struct SelectSpellEvent" src/ - When refactoring modules: Delete old definitions immediately after moving code
- When adding struct fields: Use IDE "Find Usages" to locate all call sites
- Before committing: Run
cargo checkto catch issues early
Related Documentation
compilation_errors.md: Error patterns and solutionsduplicate_event_definitions.md: Deep dive into module conflictslessons_learned.md: General implementation insights