Provide the fully fixed code
[{
	"resource": "/C:/Users/Lukas/source/repos/discovery/src/disassembler.rs",
	"owner": "rustc",
	"code": {
		"value": "Click for full compiler diagnostic",
		"target": {
			"$mid": 1,
			"external": "rust-analyzer-diagnostics-view:/diagnostic%20message%20%5B0%5D?0#file%3A%2F%2F%2Fc%253A%2FUsers%2FLukas%2Fsource%2Frepos%2Fdiscovery%2Fsrc%2Fdisassembler.rs",
			"path": "/diagnostic message [0]",
			"scheme": "rust-analyzer-diagnostics-view",
			"query": "0",
			"fragment": "file:///c%3A/Users/Lukas/source/repos/discovery/src/disassembler.rs"
		}
	},
	"severity": 8,
	"message": "cannot borrow `*self` as mutable because it is also borrowed as immutable\nmutable borrow occurs here",
	"source": "rustc",
	"startLineNumber": 104,
	"startColumn": 9,
	"endLineNumber": 104,
	"endColumn": 52,
	"relatedInformation": [
		{
			"startLineNumber": 89,
			"startColumn": 28,
			"endLineNumber": 89,
			"endColumn": 35,
			"message": "immutable borrow occurs here",
			"resource": "/c:/Users/Lukas/source/repos/discovery/src/disassembler.rs"
		},
		{
			"startLineNumber": 107,
			"startColumn": 5,
			"endLineNumber": 107,
			"endColumn": 6,
			"message": "immutable borrow might be used here, when `instructions` is dropped and runs the `Drop` code for type `Instructions`",
			"resource": "/c:/Users/Lukas/source/repos/discovery/src/disassembler.rs"
		}
	]
}]

use capstone::{arch::x86::{ArchMode::Mode32, ArchSyntax::Intel}, prelude::*};
use goblin::pe::PE;
use goblin::error::Error;
use std::fs::File;
use std::io::Read;
use crate::pe_parser::PEInfo;
use std::collections::HashMap;

#[derive(Clone)]
pub struct InstructionInfo {
    pub address: u64,
    pub mnemonic: String,
    pub op_str: String,
}

pub struct Disassembler {
    cs: Capstone,
    function_ranges: HashMap<String, std::ops::Range<usize>>,
}

impl Disassembler {
    pub fn new() -> Self {
        let cs = Capstone::new()
            .x86()
            .mode(Mode32)
            .syntax(Intel)
            .detail(true)
            .build()
            .expect("Failed to initialize Capstone");

        Self {
            cs,
            function_ranges: HashMap::new(),
        }
    }

    
    fn detect_functions(&mut self, instructions: &[InstructionInfo], pe_info: &PEInfo) {
        self.function_ranges.clear();
        let mut func_starts = Vec::new();

        // Use exported functions as starting points
        for func in &pe_info.functions {
            if let Some(addr) = pe_info.function_addresses.get(func) {
                func_starts.push(*addr);
            }
        }

        // Map address to instruction index
        let addr_to_idx: HashMap<u64, usize> = instructions.iter()
            .enumerate()
            .map(|(idx, instr)| (instr.address, idx))
            .collect();

        // Build function ranges
        for func in &pe_info.functions {
            if let Some(&start_addr) = pe_info.function_addresses.get(func) {
                if let Some(&start_idx) = addr_to_idx.get(&start_addr) {
                    // For simplicity, assume functions are contiguous blocks ending with 'ret'
                    let mut end_idx = start_idx;
                    for idx in start_idx..instructions.len() {
                        if instructions[idx].mnemonic == "ret" {
                            end_idx = idx;
                            break;
                        }
                    }
                    self.function_ranges.insert(func.clone(), start_idx..end_idx+1);
                }
            }
        }
    }

    pub fn disassemble_pe(&mut self, file_path: &str, pe_info: &PEInfo) -> Result<Vec<InstructionInfo>, Error> {
        let mut file = File::open(file_path)?;
        let mut buffer = Vec::new();
        file.read_to_end(&mut buffer)?;

        let pe = PE::parse(&buffer)?;

        let section = pe.sections.iter()
            .find(|s| s.name().unwrap_or("") == ".text")
            .ok_or_else(|| Error::Malformed("No .text section found".to_string()))?;

        let addr = section.virtual_address as u64 + pe.image_base as u64;
        let size = section.virtual_size.min(section.size_of_raw_data) as usize;
        let offset = section.pointer_to_raw_data as usize;
        let code = &buffer[offset..offset+size];

        let instructions = self.cs.disasm_all(code, addr)
            .map_err(|e| Error::Malformed(format!("Disassembly error: {}", e)))?;

        let mut insn_infos = Vec::new();
        for i in instructions.iter() {
            let instr_info = InstructionInfo {
                address: i.address(),
                mnemonic: i.mnemonic().unwrap_or("").to_string(),
                op_str: i.op_str().unwrap_or("").to_string(),
            };
            insn_infos.push(instr_info);
        }

        
        // Detect functions
        self.detect_functions(&insn_infos, pe_info);

        Ok(insn_infos)
    }

    pub fn get_function_range(&self, function_name: &str) -> Option<std::ops::Range<usize>> {
        self.function_ranges.get(function_name).cloned()
    }
}