File size: 22,189 Bytes
9763ffa
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e96c0d4
9763ffa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
[
    {
        "id": 1,
        "title": "Broken CLI Argument Parser",
        "difficulty": "Easy",
        "description": "Fix a command-line tool that parses user input to determine file operations (read, write, append). The implementation uses enums and pattern matching but contains: Mismatched types in enum variants, Incomplete match arms, Incorrect handling of optional arguments. The parser must compile and correctly interpret valid command-line inputs like: 'read file.txt' -> FileOp::Read('file.txt'), 'write file.txt content' -> FileOp::Write('file.txt', Some('content')), 'append file.txt' -> FileOp::Append('file.txt')",
        "header_section": "#[derive(Debug, PartialEq)]\nenum FileOp {\n    Read(String),\n    Write(String, Option<String>),\n    Append(String),\n}\n\nfn parse_command(input: &str) -> Option<FileOp> {\n    let parts: Vec<&str> = input.split_whitespace().collect();\n    \n    match parts.get(0) {\n        Some(&\"read\") => {\n            let filename = parts.get(1)?;\n            FileOp::Read(filename.to_string())  // BUG: Missing Some()\n        }\n        Some(&\"write\") => {\n            let filename = parts.get(1)?;\n            let content = parts.get(2).map(|s| s.to_string());\n            Some(FileOp::Write(filename.to_string(), content))\n        }\n        Some(&\"append\") => {\n            let filename = parts.get(1)?;\n            // BUG: Missing return statement\n        }\n        _ => None,\n    }\n}\n\nfn main() {\n    println!(\"CLI Parser Test\");\n}",
        "tests": [
            {
                "name": "parse_read_command",
                "input_code": "parse_command(\"read file.txt\")",
                "expected_output": "Some\\(FileOp::Read\\(\"file\\.txt\"\\)\\)",
                "should_compile": false,
                "test_assertion": "assert_eq!(parse_command(\"read file.txt\"), Some(FileOp::Read(\"file.txt\".to_string())))"
            },
            {
                "name": "parse_write_command",
                "input_code": "parse_command(\"write file.txt hello\")",
                "expected_output": "Some\\(FileOp::Write\\(\"file\\.txt\", Some\\(\"hello\"\\)\\)\\)",
                "should_compile": false,
                "test_assertion": "assert_eq!(parse_command(\"write file.txt hello\"), Some(FileOp::Write(\"file.txt\".to_string(), Some(\"hello\".to_string()))))"
            },
            {
                "name": "parse_append_command",
                "input_code": "parse_command(\"append file.txt\")",
                "expected_output": "Some\\(FileOp::Append\\(\"file\\.txt\"\\)\\)",
                "should_compile": false,
                "test_assertion": "assert_eq!(parse_command(\"append file.txt\"), Some(FileOp::Append(\"file.txt\".to_string())))"
            }
        ],
        "performance_baseline_ms": 10.0
    },
    {
        "id": 2,
        "title": "Conflicting Borrows in Collection Processing",
        "difficulty": "Easy\u2192Medium",
        "description": "Fix a function that processes a vector of strings while conditionally modifying elements and storing references for later use. The implementation mixes mutable and immutable borrows within the same scope, causing borrow checker conflicts. Requirements: Iterate through vector of strings, Store uppercase versions in a results vector, Handle optional transformations without borrowing conflicts, Must compile and execute without panics",
        "header_section": "fn process_strings(strings: &mut Vec<String>) -> Vec<String> {\n    let mut results = Vec::new();\n    \n    for s in strings {\n        // BUG: Cannot borrow as mutable while immutable borrow is active\n        let upper = s.to_uppercase();\n        s.push_str(\"_processed\");  // Mutable borrow\n        results.push(upper);\n    }\n    \n    results\n}\n\nfn main() {\n    println!(\"String processing\");\n}",
        "tests": [
            {
                "name": "process_single_string",
                "input_code": "let mut v = vec![\"hello\".to_string()]; process_strings(&mut v);",
                "should_compile": false,
                "test_assertion": "assert_eq!(process_strings(&mut vec![\"hello\".to_string()]), vec![\"HELLO\".to_string()])"
            },
            {
                "name": "process_multiple_strings",
                "input_code": "let mut v = vec![\"a\".to_string(), \"b\".to_string()]; process_strings(&mut v);",
                "should_compile": false,
                "test_assertion": "assert_eq!(process_strings(&mut vec![\"a\".to_string(), \"b\".to_string()]), vec![\"A\".to_string(), \"B\".to_string()])"
            }
        ],
        "performance_baseline_ms": 50.0
    },
    {
        "id": 3,
        "title": "Invalid Lifetime Annotations in Text API",
        "difficulty": "Medium",
        "description": "Fix a text-processing utility that accepts multiple string slices and returns a reference derived from them. The function either fails to compile or produces incorrect lifetime relationships, risking references that outlive their input data. Requirements: Function must accept multiple &str parameters, Return a &str derived from the inputs, Properly annotate lifetimes, Must be safe (no dangling references)",
        "header_section": "// BUG: Invalid lifetime annotations - which lifetime should the return type use?\nfn longest_text<'a>(s1: &'a str, s2: &'a str) -> &'a str {\n    if s1.len() > s2.len() {\n        s1\n    } else {\n        s2\n    }\n}\n\n// BUG: This function has a lifetime issue\nfn find_first_word(s: &str) -> &str {\n    let bytes = s.as_bytes();\n    for (i, &byte) in bytes.iter().enumerate() {\n        if byte == b' ' {\n            return &s[0..i];\n        }\n    }\n    &s[..]\n}\n\nfn main() {\n    println!(\"Lifetime test\");\n}",
        "tests": [
            {
                "name": "longest_text_basic",
                "input_code": "longest_text(\"abc\", \"de\")",
                "expected_output": "\"abc\"",
                "should_compile": true,
                "test_assertion": "assert_eq!(longest_text(\"abc\", \"de\"), \"abc\")"
            },
            {
                "name": "find_first_word_with_space",
                "input_code": "find_first_word(\"hello world\")",
                "expected_output": "\"hello\"",
                "should_compile": true,
                "test_assertion": "assert_eq!(find_first_word(\"hello world\"), \"hello\")"
            },
            {
                "name": "find_first_word_no_space",
                "input_code": "find_first_word(\"hello\")",
                "expected_output": "\"hello\"",
                "should_compile": true,
                "test_assertion": "assert_eq!(find_first_word(\"hello\"), \"hello\")"
            }
        ],
        "performance_baseline_ms": 10.0
    },
    {
        "id": 4,
        "title": "Business Logic Producing Incorrect Results",
        "difficulty": "Medium",
        "description": "Fix a module implementing order validation logic including pricing, discounts, and boundary conditions. The code compiles but produces incorrect outputs for edge cases such as: Zero values, Overlapping discounts, Large numeric inputs, Negative prices. Requirements: Calculate order total correctly, Apply discounts properly (no double-counting), Handle edge cases (zero items, negative values), Be mathematically sound",
        "header_section": "#[derive(Debug, Clone)]\nstruct Order {\n    quantity: i32,\n    unit_price: f64,\n    discount_percent: f64,\n}\n\nimpl Order {\n    fn new(quantity: i32, unit_price: f64) -> Self {\n        Order {\n            quantity,\n            unit_price,\n            discount_percent: 0.0,\n        }\n    }\n\n    fn with_discount(mut self, discount: f64) -> Self {\n        self.discount_percent = discount;\n        self\n    }\n\n    fn calculate_total(&self) -> f64 {\n        let subtotal = self.quantity as f64 * self.unit_price;\n        // BUG: Incorrect discount calculation\n        let discount = subtotal * (self.discount_percent / 100.0);\n        subtotal - discount  // Missing rounding/validation\n    }\n}\n\nfn main() {\n    println!(\"Order test\");\n}",
        "tests": [
            {
                "name": "simple_order",
                "input_code": "Order::new(10, 5.0).calculate_total()",
                "expected_output": "50\\.0",
                "should_compile": true,
                "test_assertion": "assert_eq!(Order::new(10, 5.0).calculate_total(), 50.0)"
            },
            {
                "name": "order_with_discount",
                "input_code": "Order::new(10, 5.0).with_discount(10.0).calculate_total()",
                "expected_output": "45\\.0",
                "should_compile": true,
                "test_assertion": "assert_eq!(Order::new(10, 5.0).with_discount(10.0).calculate_total(), 45.0)"
            },
            {
                "name": "zero_quantity",
                "input_code": "Order::new(0, 5.0).calculate_total()",
                "expected_output": "0\\.0",
                "should_compile": true,
                "test_assertion": "assert_eq!(Order::new(0, 5.0).calculate_total(), 0.0)"
            }
        ],
        "performance_baseline_ms": 10.0
    },
    {
        "id": 5,
        "title": "Corrupted Singly Linked List",
        "difficulty": "Medium\u2192Hard",
        "description": "Fix a custom singly linked list that supports insertion, deletion, and traversal. The implementation incorrectly manages node ownership and pointer transitions, resulting in: Lost nodes, Inconsistent traversal output, Occasional runtime panics. Requirements: Insert elements at head, Delete elements correctly, Traverse without panics, No memory leaks or lost data",
        "header_section": "use std::ptr;\n\n#[derive(Debug)]\nstruct Node<T> {\n    value: T,\n    next: Option<Box<Node<T>>>,\n}\n\n#[derive(Debug)]\nstruct LinkedList<T> {\n    head: Option<Box<Node<T>>>,\n}\n\nimpl<T> LinkedList<T> {\n    fn new() -> Self {\n        LinkedList { head: None }\n    }\n\n    fn insert(&mut self, value: T) {\n        let new_node = Box::new(Node {\n            value,\n            next: None,  // BUG: Should move self.head into next\n        });\n        self.head = Some(new_node);\n    }\n\n    fn len(&self) -> usize {\n        let mut count = 0;\n        let mut current = &self.head;\n        while let Some(node) = current {\n            count += 1;\n            current = &node.next;  // Correct, but insert is broken\n        }\n        count\n    }\n}\n\nfn main() {\n    println!(\"LinkedList test\");\n}",
        "tests": [
            {
                "name": "insert_single_element",
                "input_code": "let mut ll = LinkedList::new(); ll.insert(5); ll.len()",
                "expected_output": "1",
                "should_compile": true,
                "test_assertion": "let mut ll = LinkedList::new(); ll.insert(5); assert_eq!(ll.len(), 1)"
            },
            {
                "name": "insert_multiple_elements",
                "input_code": "let mut ll = LinkedList::new(); ll.insert(1); ll.insert(2); ll.insert(3); ll.len()",
                "expected_output": "3",
                "should_compile": true,
                "test_assertion": "let mut ll = LinkedList::new(); ll.insert(1); ll.insert(2); ll.insert(3); assert_eq!(ll.len(), 3)"
            }
        ],
        "performance_baseline_ms": 20.0
    },
    {
        "id": 6,
        "title": "Deadlock in Multi-threaded Worker System",
        "difficulty": "Hard",
        "description": "Fix a worker system using multiple threads to process jobs from a shared queue protected by synchronization primitives. Under certain workloads, threads block indefinitely due to: Improper lock acquisition order, Shared state handling issues, Missing signal/wake mechanisms. Requirements: Spawn N worker threads, Process jobs from shared queue without deadlock, Handle shutdown gracefully, No panics under load",
        "header_section": "use std::sync::{Arc, Mutex, mpsc};\nuse std::thread;\n\nfn worker_system(num_workers: usize, jobs: Vec<i32>) -> Vec<i32> {\n    let (tx, rx) = mpsc::channel();\n    let rx = Arc::new(Mutex::new(rx));\n    let results = Arc::new(Mutex::new(Vec::new()));\n    \n    let mut handles = vec![];\n    \n    for _ in 0..num_workers {\n        let rx = Arc::clone(&rx);\n        let results = Arc::clone(&results);\n        \n        let handle = thread::spawn(move || {\n            loop {\n                // BUG: Lock acquired but never released before trying to acquire results lock\n                let receiver = rx.lock().unwrap();\n                match receiver.try_recv() {\n                    Ok(job) => {\n                        let result = job * 2;\n                        // BUG: Tries to lock results while still holding rx lock - DEADLOCK\n                        results.lock().unwrap().push(result);\n                    }\n                    Err(_) => break,\n                }\n            }\n        });\n        handles.push(handle);\n    }\n    \n    for job in jobs {\n        let _ = tx.send(job);  // Ignore send errors\n    }\n    drop(tx);\n    \n    for handle in handles {\n        let _ = handle.join();\n    }\n    \n    Arc::try_unwrap(results)\n        .unwrap()\n        .into_inner()\n        .unwrap()\n}\n\nfn main() {\n    println!(\"Worker system test\");\n}",
        "tests": [
            {
                "name": "single_worker_single_job",
                "input_code": "worker_system(1, vec![5])",
                "expected_output": "vec!\\[10\\]",
                "should_compile": true,
                "test_assertion": "assert_eq!(worker_system(1, vec![5]), vec![10])"
            },
            {
                "name": "multiple_workers",
                "input_code": "worker_system(2, vec![1, 2, 3])",
                "expected_output": "vec!\\[(2|4|6)\\].*vec!\\[(2|4|6)\\].*vec!\\[(2|4|6)\\]",
                "should_compile": true,
                "test_assertion": "let mut result = worker_system(2, vec![1, 2, 3]); result.sort(); assert_eq!(result, vec![2, 4, 6])"
            }
        ],
        "performance_baseline_ms": 500.0
    },
    {
        "id": 7,
        "title": "Async Function with Borrowing Conflicts",
        "difficulty": "Hard",
        "description": "Fix an asynchronous function that processes input data and performs non-blocking operations while returning references tied to the input. The implementation violates borrowing constraints in an async context, leading to: Compilation errors when using references across await points, Invalid reference usage. Requirements: Accept &str input, Perform async operation, Return derived reference, Must be sound and compile",
        "header_section": "use std::pin::Pin;\nuse std::future::Future;\n\n// BUG: Cannot return reference that outlives await point\nasync fn process_async(input: &str) -> &str {\n    // Simulating async work\n    // tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;\n    \n    // BUG: input reference cannot be returned from async context like this\n    input\n}\n\n// Better approach: return owned data or 'static reference\nfn process_sync(input: &str) -> String {\n    input.to_uppercase()\n}\n\nfn main() {\n    println!(\"Async test\");\n}",
        "tests": [
            {
                "name": "process_sync_basic",
                "input_code": "process_sync(\"hello\")",
                "expected_output": "\"HELLO\"",
                "should_compile": true,
                "test_assertion": "assert_eq!(process_sync(\"hello\"), \"HELLO\")"
            },
            {
                "name": "process_sync_uppercase",
                "input_code": "process_sync(\"Hello World\")",
                "expected_output": "\"HELLO WORLD\"",
                "should_compile": true,
                "test_assertion": "assert_eq!(process_sync(\"Hello World\"), \"HELLO WORLD\")"
            }
        ],
        "performance_baseline_ms": 50.0
    },
    {
        "id": 8,
        "title": "Unsafe FFI Integration Causing Crashes",
        "difficulty": "Hard",
        "description": "Fix Rust code that interfaces with an external C library using raw pointers. The implementation incorrectly handles: Pointer ownership, Memory allocation and deallocation, Undefined behavior risks. Requirements: Safely wrap C library calls, Properly manage memory (allocate/deallocate), No undefined behavior, Handle errors gracefully",
        "header_section": "extern \"C\" {\n    fn malloc(size: usize) -> *mut u8;\n    fn free(ptr: *mut u8);\n}\n\nfn allocate_and_init(size: usize) -> Vec<u8> {\n    unsafe {\n        let ptr = malloc(size);\n        // BUG: No null check - ptr could be null\n        // BUG: Memory not initialized before use\n        let slice = std::slice::from_raw_parts_mut(ptr, size);\n        \n        // Copy to vec and free\n        let vec = slice.to_vec();\n        free(ptr);  // BUG: Freeing memory still referenced in vec\n        vec\n    }\n}\n\nfn main() {\n    println!(\"FFI test\");\n}",
        "tests": [
            {
                "name": "allocate_small_buffer",
                "input_code": "allocate_and_init(10).len()",
                "expected_output": "10",
                "should_compile": false,
                "test_assertion": "assert_eq!(allocate_and_init(10).len(), 10)"
            }
        ],
        "performance_baseline_ms": 100.0
    },
    {
        "id": 9,
        "title": "Inefficient Data Processing Pipeline",
        "difficulty": "Hard",
        "description": "Fix a data pipeline that reads large datasets, applies transformations, and aggregates results. While functionally correct, the implementation has: Excessive memory allocations, Redundant iterations, Inefficient data copying. Requirements: Process data efficiently, Minimize allocations and copies, Use iterators when possible, Produce correct results with better performance",
        "header_section": "fn process_data(numbers: Vec<i32>) -> i32 {\n    // BUG: Multiple unnecessary allocations and iterations\n    \n    // First pass: filter evens (allocates new vector)\n    let evens: Vec<i32> = numbers.iter()\n        .filter(|n| n % 2 == 0)\n        .copied()\n        .collect();\n    \n    // Second pass: double values (allocates another vector)\n    let doubled: Vec<i32> = evens.iter()\n        .map(|n| n * 2)\n        .collect();\n    \n    // Third pass: sum (unnecessary iteration)\n    let sum: i32 = doubled.iter().sum();\n    \n    // Fourth pass: filter again (redundant)\n    let final_sum: i32 = doubled.iter()\n        .filter(|n| n % 4 == 0)\n        .sum();\n    \n    final_sum\n}\n\nfn main() {\n    println!(\"Efficiency test\");\n}",
        "tests": [
            {
                "name": "simple_pipeline",
                "input_code": "process_data(vec![1, 2, 3, 4, 5, 6])",
                "expected_output": "16",
                "should_compile": true,
                "test_assertion": "assert_eq!(process_data(vec![1, 2, 3, 4, 5, 6]), 16)"
            },
            {
                "name": "all_odd_numbers",
                "input_code": "process_data(vec![1, 3, 5, 7])",
                "expected_output": "0",
                "should_compile": true,
                "test_assertion": "assert_eq!(process_data(vec![1, 3, 5, 7]), 0)"
            }
        ],
        "performance_baseline_ms": 50.0
    },
    {
        "id": 10,
        "title": "Reference-counted Cache with Memory Leak",
        "difficulty": "Hard+",
        "description": "Fix a caching system using reference-counted pointers to share data across components. The design creates cyclic references between cached objects, preventing memory from being released and causing memory usage to grow over time. Requirements: Implement caching without memory leaks, Break circular reference patterns, Use Rc/Arc correctly with Weak pointers when needed, Memory should be released when cache is cleared",
        "header_section": "use std::rc::Rc;\nuse std::cell::RefCell;\n\n#[derive(Debug)]\nstruct CacheNode<T> {\n    key: String,\n    value: T,\n    // BUG: This creates a cycle that prevents garbage collection\n    related: RefCell<Option<Rc<CacheNode<T>>>>,\n}\n\n#[derive(Debug)]\nstruct Cache<T> {\n    items: RefCell<Vec<Rc<CacheNode<T>>>>,\n}\n\nimpl<T: Clone> Cache<T> {\n    fn new() -> Self {\n        Cache {\n            items: RefCell::new(Vec::new()),\n        }\n    }\n\n    fn insert(&self, key: String, value: T) {\n        let node = Rc::new(CacheNode {\n            key,\n            value,\n            related: RefCell::new(None),\n        });\n        \n        // BUG: Creating cyclic references\n        if let Some(last) = self.items.borrow().last() {\n            // Rc to Rc creates a cycle\n            if let Ok(mut r) = last.related.try_borrow_mut() {\n                *r = Some(Rc::clone(&node));  // Cycle here!\n            }\n        }\n        \n        self.items.borrow_mut().push(node);\n    }\n}\n\nfn main() {\n    println!(\"Cache test\");\n}",
        "tests": [
            {
                "name": "cache_insert_single",
                "input_code": "let c = Cache::new(); c.insert(\"key\".to_string(), \"value\".to_string()); c.items.borrow().len()",
                "expected_output": "1",
                "should_compile": true,
                "test_assertion": "let c = Cache::new(); c.insert(\"key\".to_string(), \"value\".to_string()); assert_eq!(c.items.borrow().len(), 1)"
            },
            {
                "name": "cache_insert_multiple",
                "input_code": "let c = Cache::new(); c.insert(\"k1\".to_string(), \"v1\".to_string()); c.insert(\"k2\".to_string(), \"v2\".to_string()); c.items.borrow().len()",
                "expected_output": "2",
                "should_compile": true,
                "test_assertion": "let c = Cache::new(); c.insert(\"k1\".to_string(), \"v1\".to_string()); c.insert(\"k2\".to_string(), \"v2\".to_string()); assert_eq!(c.items.borrow().len(), 2)"
            }
        ],
        "performance_baseline_ms": 100.0
    }
]