implicit_wrapping.adl
1 program implicit_wrapping.alpha { 2 // === Shared Structs === 3 4 struct Foo { 5 x: u8?, // optional field 6 } 7 8 struct Wrapper { 9 arr: [Foo?; 2], // array of optional structs 10 } 11 12 // === BASIC TYPE TESTS === 13 14 // 1. Return u8? → move logic to inline 15 inline basic_implicit_return_() -> u8? { 16 return 5u8; // implicitly wrapped 17 } 18 19 transition basic_implicit_return() -> u8 { 20 return basic_implicit_return_().unwrap(); 21 } 22 23 // 2. Optional input (inline is allowed) 24 inline takes_optional_u8(x: u8?) -> u8 { 25 return x.unwrap_or(100u8); 26 } 27 28 // 3. Optional argument passed → use inline 29 inline basic_implicit_argument_() -> u8 { 30 return takes_optional_u8(42u8); // implicitly wrapped 31 } 32 33 transition basic_implicit_argument() -> u8 { 34 return basic_implicit_argument_(); 35 } 36 37 // 4. Return u8? → move logic to inline 38 inline basic_implicit_ternary_(cond: bool) -> u8? { 39 let result: u8? = cond ? 10u8 : none; 40 return result; 41 } 42 43 transition basic_implicit_ternary(cond: bool) -> u8 { 44 return basic_implicit_ternary_(cond).unwrap(); 45 } 46 47 // 5. Optional reassignment only (return is concrete) → allowed 48 transition basic_implicit_reassignment() -> u8 { 49 let x: u8? = none; 50 x = 99u8; // implicitly wrapped 51 return x.unwrap(); 52 } 53 54 // === COMPLEX TYPE TESTS === 55 56 // 1. Return Wrapper? → move to inline 57 inline complex_implicit_return_() -> Wrapper? { 58 return Wrapper { 59 arr: [Foo { x: 8u8 }, none], 60 }; 61 } 62 63 transition complex_implicit_return() -> [u8; 2] { 64 let w = complex_implicit_return_().unwrap(); 65 return [w.arr[0].unwrap().x.unwrap(), w.arr[1].unwrap().x.unwrap()]; 66 } 67 68 // 2. Optional argument to inline → wrap call 69 inline takes_optional_wrapper(w: Wrapper?) -> u8 { 70 return w.unwrap().arr[0].unwrap().x.unwrap_or(0u8); 71 } 72 73 inline complex_implicit_argument_() -> u8 { 74 return takes_optional_wrapper(Wrapper { 75 arr: [Foo { x: none }, none], 76 }); 77 } 78 79 transition complex_implicit_argument() -> u8 { 80 return complex_implicit_argument_(); 81 } 82 83 // 3. Return Wrapper? → move to inline 84 inline complex_implicit_ternary_(cond: bool) -> Wrapper? { 85 let result: Wrapper? = cond 86 ? Wrapper { arr: [Foo { x: 99u8 }, none] } 87 : none; 88 return result; 89 } 90 91 transition complex_implicit_ternary(cond: bool) -> [u8; 2] { 92 let w = complex_implicit_ternary_(cond).unwrap(); 93 return [w.arr[0].unwrap().x.unwrap(), w.arr[1].unwrap().x.unwrap()]; 94 } 95 96 // 4. Optional reassignment only → allowed 97 transition complex_implicit_reassignment() -> u8 { 98 let w: Wrapper? = none; 99 w = Wrapper { arr: [Foo { x: 7u8 }, none] }; 100 return w.unwrap().arr[0].unwrap().x.unwrap(); 101 } 102 103 // 5. Return is concrete but input is optional → move to inline 104 inline complex_array_wrapping_() -> u8 { 105 let arr_opt: [Wrapper; 3]? = none; 106 arr_opt = [ 107 Wrapper { arr: [Foo { x: 1u8 }, none] }, 108 Wrapper { arr: [none, none] }, 109 Wrapper { arr: [Foo { x: 2u8 }, none] }, 110 ]; 111 return arr_opt.unwrap()[0].arr[0].unwrap().x.unwrap(); 112 } 113 114 transition complex_array_wrapping() -> u8 { 115 return complex_array_wrapping_(); 116 } 117 118 // 6. Same: optional input, concrete return → move to inline 119 inline complex_array_access_() -> u8 { 120 let arr_opt: [Wrapper; 3]? = [ 121 Wrapper { arr: [Foo { x: 10u8 }, none] }, 122 Wrapper { arr: [Foo { x: 20u8 }, none] }, 123 Wrapper { arr: [none, none] }, 124 ]; 125 let w = arr_opt.unwrap()[1]; 126 let f = w.arr[0].unwrap(); 127 return f.x.unwrap(); // should be 20 128 } 129 130 transition complex_array_access() -> u8 { 131 return complex_array_access_(); 132 } 133 }