Skip to content

Commit 7c45b56

Browse files
committed
limitations
1 parent 5792312 commit 7c45b56

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

module/core/former/limitations.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Former Macro: Architectural Limitations Analysis
2+
3+
This document provides a systematic analysis of the 4 fundamental limitations preventing certain tests from being enabled in the Former crate. Each limitation is **experimentally verified** and characterized using the Target Type Classification framework from the specification.
4+
5+
## Target Type Classification Context
6+
7+
According to the Former specification, the macro operates on two fundamental **Target Type Categories**:
8+
- **Structs** - Regular Rust structs with named fields
9+
- **Enums** - Rust enums with variants, subdivided by **Variant Structure Types** (Unit, Tuple, Named)
10+
11+
Each limitation affects these target types differently, as detailed in the analysis below.
12+
13+
## 1. Generic Enum Parsing Limitation ✅ TESTED
14+
15+
### Limitation Characteristics
16+
- **Scope**: Enum Target Type Category only (Structs unaffected)
17+
- **Severity**: Complete blocking - no generic enums supported
18+
- **Behavioral Categories Affected**: All enum formers (Unit/Tuple/Named Variant Formers)
19+
- **Variant Structure Types Affected**: All (Unit, Tuple, Named variants)
20+
- **Root Cause**: Macro parser architecture limitation
21+
- **Workaround Availability**: Full (concrete type replacement)
22+
- **Future Compatibility**: Possible (requires major rewrite)
23+
24+
**What it means**: The macro cannot parse generic parameter syntax in enum declarations.
25+
26+
### ❌ This Breaks:
27+
```rust
28+
#[derive(Former)]
29+
pub enum GenericEnum<T> { // <-- The <T> part breaks the macro
30+
Variant(T),
31+
}
32+
```
33+
**Verified Error**: `expected '::' found '>'` - macro parser fails on generic syntax
34+
35+
### ✅ This Works:
36+
```rust
37+
#[derive(Former)]
38+
pub enum ConcreteEnum { // <-- No <T>, so it works
39+
Variant(String),
40+
}
41+
// Usage: ConcreteEnum::variant()._0("hello".to_string()).form()
42+
```
43+
44+
**The Technical Choice**: Simple token-based parser vs Full AST parser with generics
45+
46+
**Trade-off Details**:
47+
- **Current approach**: Fast compilation, simple implementation
48+
- **Alternative approach**: Slow compilation, complex parser supporting generics
49+
- **Implementation cost**: Complete macro rewrite with full Rust AST parsing
50+
- **Performance impact**: Significant compilation time increase
51+
52+
**Can Both Be Combined?** 🟡 **PARTIALLY**
53+
- Technically possible but requires rewriting the entire macro parser
54+
- Would need full Rust AST parsing instead of simple token matching
55+
- Trade-off: Fast builds vs Generic enum support
56+
57+
---
58+
59+
## 2. Lifetime Constraint Limitation ✅ VERIFIED IN CODE
60+
61+
### Limitation Characteristics
62+
- **Scope**: Both Target Type Categories (Structs and Enums)
63+
- **Severity**: Fundamental blocking - no lifetime parameters supported
64+
- **Behavioral Categories Affected**: All Former types with lifetime parameters
65+
- **Variant Structure Types Affected**: N/A (applies to type-level generics)
66+
- **Root Cause**: Rust language constraint (trait objects + lifetimes)
67+
- **Workaround Availability**: Partial (owned data only)
68+
- **Future Compatibility**: Impossible (fundamental Rust limitation)
69+
70+
**What it means**: Rust's memory safety rules fundamentally prevent borrowed data in Former storage due to trait object lifetime requirements.
71+
72+
### ❌ This Breaks:
73+
```rust
74+
// From parametrized_dyn_manual.rs:210 - real example
75+
impl<'callback> StoragePreform for StylesFormerStorage<'callback> {
76+
fn preform(self) -> Self::Preformed {
77+
// ERROR E0521: borrowed data escapes outside of method
78+
(&PhantomData::<&'callback dyn FilterCol>).maybe_default()
79+
// `'callback` must outlive `'static`
80+
}
81+
}
82+
```
83+
84+
### ✅ This Works:
85+
```rust
86+
#[derive(Former)]
87+
pub struct OwnedStruct {
88+
owned_data: String, // <-- Owned data is fine
89+
numbers: Vec<i32>, // <-- Owned collections work
90+
static_ref: &'static str // <-- Static references work
91+
}
92+
```
93+
94+
**The Technical Choice**: Trait object compatibility with memory safety vs Complex lifetime support
95+
96+
**Trade-off Details**:
97+
- **Current approach**: Memory safety + trait objects work reliably
98+
- **Alternative approach**: Complex lifetime tracking in all generated code
99+
- **Fundamental constraint**: Trait objects require `'static` bounds for type erasure
100+
- **Rust limitation**: Cannot allow borrowed data to escape method boundaries
101+
102+
**Can Both Be Combined?** 🔴 **NO**
103+
- This is a hard Rust language constraint, not our design choice
104+
- Trait objects fundamentally require `'static` bounds
105+
- Even perfect implementation cannot overcome Rust's type system rules
106+
107+
---
108+
109+
## 3. Trait Conflict Limitation ✅ TESTED
110+
111+
### Limitation Characteristics
112+
- **Scope**: Enum Target Type Category only (multi-variant enums)
113+
- **Severity**: Selective blocking - single-variant enums work fine
114+
- **Behavioral Categories Affected**: Mixed enum scenarios (Complex Scenario Formers)
115+
- **Variant Structure Types Affected**: All when combined in single enum
116+
- **Root Cause**: Duplicate trait implementation generation
117+
- **Workaround Availability**: Full (single variant per enum)
118+
- **Future Compatibility**: Possible (requires complex deduplication logic)
119+
120+
**What it means**: The macro generates conflicting trait implementations when multiple enum variants require the same traits.
121+
122+
### ❌ This Breaks:
123+
```rust
124+
#[derive(Former)]
125+
pub enum MultiVariantEnum {
126+
VariantA { field: String }, // <-- Each variant tries to
127+
VariantB { other: i32 }, // <-- generate the same traits
128+
VariantC, // <-- causing conflicts
129+
}
130+
```
131+
**Verified Error E0119**: `conflicting implementations of trait EntityToStorage`
132+
133+
### ✅ This Works:
134+
```rust
135+
#[derive(Former)]
136+
pub enum SingleVariantEnum {
137+
OnlyVariant { field: String }, // <-- One variant = no conflicts
138+
}
139+
// Usage: SingleVariantEnum::only_variant().field("test".to_string()).form()
140+
```
141+
142+
**The Technical Choice**: Simple per-enum trait generation vs Complex trait deduplication
143+
144+
**Trade-off Details**:
145+
- **Current approach**: Simple code generation, one trait impl per enum
146+
- **Alternative approach**: Sophisticated trait deduplication with variant-specific logic
147+
- **Implementation complexity**: Exponential increase in generated code complexity
148+
- **Maintenance burden**: Much harder to debug and maintain complex generation
149+
150+
**Can Both Be Combined?** 🟡 **YES, BUT VERY COMPLEX**
151+
- Technically possible with sophisticated trait merging logic
152+
- Requires tracking implementations across all variants
153+
- Major increase in macro complexity and maintenance burden
154+
- Cost/benefit analysis favors current simple approach
155+
156+
---
157+
158+
## Comprehensive Limitations Matrix
159+
160+
| Limitation | Target Type Scope | Severity Level | Behavioral Categories | Future Fix | Workaround | Decision Impact |
161+
|------------|------------------|----------------|----------------------|-----------|------------|----------------|
162+
| **Generic Parsing** | Enums only | Complete blocking | All enum formers | 🟡 Possible (major rewrite) | ✅ Concrete types | High - affects API design |
163+
| **Lifetime Constraints** | Structs + Enums | Fundamental blocking | All with lifetimes | 🔴 Impossible (Rust constraint) | 🟡 Owned data only | Critical - shapes data patterns |
164+
| **Trait Conflicts** | Multi-variant enums | Selective blocking | Complex scenarios | 🟡 Possible (complex logic) | ✅ Single variants | Medium - affects enum design |
165+
166+
### Key Decision-Making Insights
167+
168+
**Architectural Impact Ranking**:
169+
1. **Lifetime Constraints** - Most critical, shapes fundamental data patterns
170+
2. **Generic Parsing** - High impact on API flexibility and user experience
171+
3. **Trait Conflicts** - Medium impact, affects complex enum design strategies
172+
4. **Compile-fail Tests** - Low impact, testing methodology only
173+
174+
**Workaround Effectiveness**:
175+
-**Full workarounds available**: Generic Parsing, Trait Conflicts
176+
- 🟡 **Partial workarounds**: Lifetime Constraints (owned data patterns)
177+
-**No workarounds needed**: Compile-fail Tests (working as intended)
178+
179+
**Engineering Trade-offs**:
180+
- **Generic Parsing**: Simple parser vs Universal enum support
181+
- **Lifetime Constraints**: Memory safety vs Flexible borrowing patterns
182+
- **Trait Conflicts**: Simple generation vs Complex multi-variant enums
183+
- **Compile-fail Tests**: Error validation vs Maximum passing test count

0 commit comments

Comments
 (0)