/ tests / tests / compiler / option / implicit_wrapping.adl
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  }