Add: windows mvp - transparent bugs not fixed

This commit is contained in:
DaZuo0122
2026-02-12 22:58:33 +08:00
commit 61825f647d
147 changed files with 28498 additions and 0 deletions

View File

@@ -0,0 +1,265 @@
# Common Ownership Errors & Fixes
## E0382: Use of Moved Value
### Error Pattern
```rust
let s = String::from("hello");
let s2 = s; // s moved here
println!("{}", s); // ERROR: value borrowed after move
```
### Fix Options
**Option 1: Clone (if ownership not needed)**
```rust
let s = String::from("hello");
let s2 = s.clone(); // s is cloned
println!("{}", s); // OK: s still valid
```
**Option 2: Borrow (if modification not needed)**
```rust
let s = String::from("hello");
let s2 = &s; // borrow, not move
println!("{}", s); // OK
println!("{}", s2); // OK
```
**Option 3: Use Rc/Arc (for shared ownership)**
```rust
use std::rc::Rc;
let s = Rc::new(String::from("hello"));
let s2 = Rc::clone(&s); // shared ownership
println!("{}", s); // OK
println!("{}", s2); // OK
```
---
## E0597: Borrowed Value Does Not Live Long Enough
### Error Pattern
```rust
fn get_str() -> &str {
let s = String::from("hello");
&s // ERROR: s dropped here, but reference returned
}
```
### Fix Options
**Option 1: Return owned value**
```rust
fn get_str() -> String {
String::from("hello") // return owned value
}
```
**Option 2: Use 'static lifetime**
```rust
fn get_str() -> &'static str {
"hello" // string literal has 'static lifetime
}
```
**Option 3: Accept reference parameter**
```rust
fn get_str<'a>(s: &'a str) -> &'a str {
s // return reference with same lifetime as input
}
```
---
## E0499: Cannot Borrow as Mutable More Than Once
### Error Pattern
```rust
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s; // ERROR: second mutable borrow
println!("{}, {}", r1, r2);
```
### Fix Options
**Option 1: Sequential borrows**
```rust
let mut s = String::from("hello");
{
let r1 = &mut s;
r1.push_str(" world");
} // r1 goes out of scope
let r2 = &mut s; // OK: r1 no longer exists
```
**Option 2: Use RefCell for interior mutability**
```rust
use std::cell::RefCell;
let s = RefCell::new(String::from("hello"));
let mut r1 = s.borrow_mut();
// drop r1 before borrowing again
drop(r1);
let mut r2 = s.borrow_mut();
```
---
## E0502: Cannot Borrow as Mutable While Immutable Borrow Exists
### Error Pattern
```rust
let mut v = vec![1, 2, 3];
let first = &v[0]; // immutable borrow
v.push(4); // ERROR: mutable borrow while immutable exists
println!("{}", first);
```
### Fix Options
**Option 1: Finish using immutable borrow first**
```rust
let mut v = vec![1, 2, 3];
let first = v[0]; // copy value, not borrow
v.push(4); // OK
println!("{}", first); // OK: using copied value
```
**Option 2: Clone before mutating**
```rust
let mut v = vec![1, 2, 3];
let first = v[0].clone(); // if T: Clone
v.push(4);
println!("{}", first);
```
---
## E0507: Cannot Move Out of Borrowed Content
### Error Pattern
```rust
fn take_string(s: &String) {
let moved = *s; // ERROR: cannot move out of borrowed content
}
```
### Fix Options
**Option 1: Clone**
```rust
fn take_string(s: &String) {
let cloned = s.clone();
}
```
**Option 2: Take ownership in function signature**
```rust
fn take_string(s: String) { // take ownership
let moved = s;
}
```
**Option 3: Use mem::take for Option/Default types**
```rust
fn take_from_option(opt: &mut Option<String>) -> Option<String> {
std::mem::take(opt) // replaces with None, returns owned value
}
```
---
## E0515: Return Local Reference
### Error Pattern
```rust
fn create_string() -> &String {
let s = String::from("hello");
&s // ERROR: cannot return reference to local variable
}
```
### Fix Options
**Option 1: Return owned value**
```rust
fn create_string() -> String {
String::from("hello")
}
```
**Option 2: Use static/const**
```rust
fn get_static_str() -> &'static str {
"hello"
}
```
---
## E0716: Temporary Value Dropped While Borrowed
### Error Pattern
```rust
let r: &str = &String::from("hello"); // ERROR: temporary dropped
println!("{}", r);
```
### Fix Options
**Option 1: Bind to variable first**
```rust
let s = String::from("hello");
let r: &str = &s;
println!("{}", r);
```
**Option 2: Use let binding with reference**
```rust
let r: &str = {
let s = String::from("hello");
// s.as_str() // ERROR: still temporary
Box::leak(s.into_boxed_str()) // extreme: leak for 'static
};
```
---
## Pattern: Loop Ownership Issues
### Error Pattern
```rust
let strings = vec![String::from("a"), String::from("b")];
for s in strings {
println!("{}", s);
}
// ERROR: strings moved into loop
println!("{:?}", strings);
```
### Fix Options
**Option 1: Iterate by reference**
```rust
let strings = vec![String::from("a"), String::from("b")];
for s in &strings {
println!("{}", s);
}
println!("{:?}", strings); // OK
```
**Option 2: Use iter()**
```rust
for s in strings.iter() {
println!("{}", s);
}
```
**Option 3: Clone if needed**
```rust
for s in strings.clone() {
// consumes cloned vec
}
println!("{:?}", strings); // original still available
```

View File

@@ -0,0 +1,229 @@
# Lifetime Patterns
## Basic Lifetime Annotation
### When Required
```rust
// ERROR: missing lifetime specifier
fn longest(x: &str, y: &str) -> &str {
if x.len() > y.len() { x } else { y }
}
// FIX: explicit lifetime
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
```
### Lifetime Elision Rules
1. Each input reference gets its own lifetime
2. If one input lifetime, output uses same
3. If `&self` or `&mut self`, output uses self's lifetime
```rust
// These are equivalent (elision applies):
fn first_word(s: &str) -> &str { ... }
fn first_word<'a>(s: &'a str) -> &'a str { ... }
// Method with self (elision applies):
impl MyStruct {
fn get_ref(&self) -> &str { ... }
// Equivalent to:
fn get_ref<'a>(&'a self) -> &'a str { ... }
}
```
---
## Struct Lifetimes
### Struct Holding References
```rust
// Struct must declare lifetime for references
struct Excerpt<'a> {
part: &'a str,
}
impl<'a> Excerpt<'a> {
fn level(&self) -> i32 { 3 }
// Return reference tied to self's lifetime
fn get_part(&self) -> &str {
self.part
}
}
```
### Multiple Lifetimes in Struct
```rust
struct Multi<'a, 'b> {
x: &'a str,
y: &'b str,
}
// Use when references may have different lifetimes
fn make_multi<'a, 'b>(x: &'a str, y: &'b str) -> Multi<'a, 'b> {
Multi { x, y }
}
```
---
## 'static Lifetime
### When to Use
```rust
// String literals are 'static
let s: &'static str = "hello";
// Owned data can be leaked to 'static
let leaked: &'static str = Box::leak(String::from("hello").into_boxed_str());
// Thread spawn requires 'static or move
std::thread::spawn(move || {
// closure owns data, satisfies 'static
});
```
### Avoid Overusing 'static
```rust
// BAD: requires 'static unnecessarily
fn process(s: &'static str) { ... }
// GOOD: use generic lifetime
fn process<'a>(s: &'a str) { ... }
// or
fn process(s: &str) { ... } // lifetime elision
```
---
## Higher-Ranked Trait Bounds (HRTB)
### for<'a> Syntax
```rust
// Function that works with any lifetime
fn apply_to_ref<F>(f: F)
where
F: for<'a> Fn(&'a str) -> &'a str,
{
let s = String::from("hello");
let result = f(&s);
println!("{}", result);
}
```
### Common Use: Closure Bounds
```rust
// Closure that borrows any lifetime
fn filter_refs<F>(items: &[&str], pred: F) -> Vec<&str>
where
F: for<'a> Fn(&'a str) -> bool,
{
items.iter().copied().filter(|s| pred(s)).collect()
}
```
---
## Lifetime Bounds
### 'a: 'b (Outlives)
```rust
// 'a must live at least as long as 'b
fn coerce<'a, 'b>(x: &'a str) -> &'b str
where
'a: 'b,
{
x
}
```
### T: 'a (Type Outlives Lifetime)
```rust
// T must live at least as long as 'a
struct Wrapper<'a, T: 'a> {
value: &'a T,
}
// Common pattern with trait objects
fn use_trait<'a, T: MyTrait + 'a>(t: &'a T) { ... }
```
---
## Common Lifetime Mistakes
### Mistake 1: Returning Reference to Local
```rust
// WRONG
fn dangle() -> &String {
let s = String::from("hello");
&s // s dropped, reference invalid
}
// RIGHT
fn no_dangle() -> String {
String::from("hello")
}
```
### Mistake 2: Conflicting Lifetimes
```rust
// WRONG: might return reference to y which has shorter lifetime
fn wrong<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
y // ERROR: 'b might not live as long as 'a
}
// RIGHT: use same lifetime or add bound
fn right<'a>(x: &'a str, y: &'a str) -> &'a str {
y // OK: both have lifetime 'a
}
```
### Mistake 3: Struct Outlives Reference
```rust
// WRONG: s might outlive the string it references
let r;
{
let s = String::from("hello");
r = Excerpt { part: &s }; // ERROR
}
println!("{}", r.part); // s already dropped
// RIGHT: ensure source outlives struct
let s = String::from("hello");
let r = Excerpt { part: &s };
println!("{}", r.part); // OK: s still in scope
```
---
## Subtyping and Variance
### Covariance
```rust
// &'a T is covariant in 'a
// Can use &'long where &'short expected
fn example<'short, 'long: 'short>(long_ref: &'long str) {
let short_ref: &'short str = long_ref; // OK: covariance
}
```
### Invariance
```rust
// &'a mut T is invariant in 'a
fn example<'a, 'b>(x: &'a mut &'b str, y: &'b str) {
*x = y; // ERROR if 'a and 'b are different
}
```
### Practical Impact
```rust
// This works due to covariance
fn accept_any<'a>(s: &'a str) { ... }
let s = String::from("hello");
let long_lived: &str = &s;
accept_any(long_lived); // 'long coerces to 'short
```