/ tests / tests / compiler / option / in_modules.adl
in_modules.adl
  1  program in_modules.alpha {
  2      // === BASIC TYPE TESTS ===
  3  
  4      // 1. Return u8? → move to inline, unwrap in transition
  5      inline basic_implicit_return_() -> u8? {
  6          return 5u8; // implicitly wrapped
  7      }
  8  
  9      transition basic_implicit_return() -> u8 {
 10          return basic_implicit_return_().unwrap();
 11      }
 12  
 13      // 2. Optional input (inline is OK)
 14      inline takes_optional_u8(x: u8?) -> u8 {
 15          return x.unwrap_or(100u8);
 16      }
 17  
 18      // 3. Implicit optional argument → use inline
 19      inline basic_implicit_argument_() -> u8 {
 20          return takes_optional_u8(42u8); // implicitly wrapped
 21      }
 22  
 23      transition basic_implicit_argument() -> u8 {
 24          return basic_implicit_argument_();
 25      }
 26  
 27      // 4. Return u8? → unwrap
 28      inline basic_implicit_ternary_(cond: bool) -> u8? {
 29          let result: u8? = cond ? 10u8 : none;
 30          return result;
 31      }
 32  
 33      transition basic_implicit_ternary(cond: bool) -> u8 {
 34          return basic_implicit_ternary_(cond).unwrap();
 35      }
 36  
 37      // 5. Only optional reassignment — OK
 38      transition basic_implicit_reassignment() -> u8 {
 39          let x: u8? = none;
 40          x = 99u8;
 41          return x.unwrap();
 42      }
 43  
 44      // === COMPLEX TYPE TESTS ===
 45  
 46      // 1. Return dep::Wrapper? → unwrap fully to [u8; 2]
 47      inline complex_implicit_return_() -> [u8?; 2] {
 48          let wrapper_opt: dep::Wrapper? = dep::Wrapper {
 49              arr: [dep::inner::Foo { x: 8u8 }, none],
 50          };
 51          let wrapper = wrapper_opt.unwrap();
 52          return [
 53              wrapper.arr[0].unwrap().x,
 54              wrapper.arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
 55          ];
 56      }
 57  
 58      transition complex_implicit_return() -> [u8; 2] {
 59          let xs = complex_implicit_return_();
 60          return [xs[0].unwrap(), xs[1].unwrap_or(0u8)];
 61      }
 62  
 63      // 2. Optional arg → already inline
 64      inline takes_optional_wrapper(w: dep::Wrapper?) -> u8 {
 65          return w.unwrap().arr[0].unwrap().x.unwrap_or(0u8);
 66      }
 67  
 68      inline complex_implicit_argument_() -> u8 {
 69          return takes_optional_wrapper(dep::Wrapper {
 70              arr: [dep::inner::Foo { x: none }, none],
 71          });
 72      }
 73  
 74      transition complex_implicit_argument() -> u8 {
 75          return complex_implicit_argument_();
 76      }
 77  
 78      // 3. Return dep::Wrapper? → unwrap fully to [u8; 2]
 79      inline complex_implicit_ternary_(cond: bool) -> [u8?; 2] {
 80          let wrapper_opt: dep::Wrapper? = cond
 81              ? dep::Wrapper { arr: [dep::inner::Foo { x: 99u8 }, none] }
 82              : none;
 83          let wrapper = wrapper_opt.unwrap();
 84          return [
 85              wrapper.arr[0].unwrap().x,
 86              wrapper.arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
 87          ];
 88      }
 89  
 90      transition complex_implicit_ternary(cond: bool) -> [u8; 2] {
 91          let xs = complex_implicit_ternary_(cond);
 92          return [xs[0].unwrap_or(0u8), xs[1].unwrap_or(0u8)];
 93      }
 94  
 95      // 4. Optional reassignment only — allowed
 96      transition complex_implicit_reassignment() -> u8 {
 97          let w: dep::Wrapper? = none;
 98          w = dep::Wrapper { arr: [dep::inner::Foo { x: 7u8 }, none] };
 99          return w.unwrap().arr[0].unwrap().x.unwrap();
100      }
101  
102      // 5. [dep::Wrapper; 3]? → unwrap all the way to [[u8; 2]; 3]
103      inline complex_array_wrapping_() -> [[u8?; 2]; 3] {
104          let arr_opt: [dep::Wrapper; 3]? = none;
105          let arr = arr_opt.unwrap();
106  
107          return [
108              [
109                  arr[0].arr[0].unwrap().x,
110                  arr[0].arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
111              ],
112              [
113                  arr[1].arr[0].unwrap_or(dep::inner::Foo { x: none }).x,
114                  arr[1].arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
115              ],
116              [
117                  arr[2].arr[0].unwrap().x,
118                  arr[2].arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
119              ],
120          ];
121      }
122  
123      transition complex_array_wrapping() -> u8 {
124          let arr = complex_array_wrapping_();
125          return arr[0][0].unwrap_or(0u8); // only return one value
126      }
127  
128      // 6. Deeper access into optional array — unwrap fully
129      inline complex_array_access_() -> [[u8?; 2]; 3] {
130          let arr_opt: [dep::Wrapper; 3]? = [
131              dep::Wrapper { arr: [dep::inner::Foo { x: 10u8 }, none] },
132              dep::Wrapper { arr: [dep::inner::Foo { x: 20u8 }, none] },
133              dep::Wrapper { arr: [none, none] },
134          ];
135          let arr = arr_opt.unwrap();
136          return [
137              [
138                  arr[0].arr[0].unwrap().x,
139                  arr[0].arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
140              ],
141              [
142                  arr[1].arr[0].unwrap().x,
143                  arr[1].arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
144              ],
145              [
146                  arr[2].arr[0].unwrap_or(dep::inner::Foo { x: none }).x,
147                  arr[2].arr[1].unwrap_or(dep::inner::Foo { x: none }).x,
148              ],
149          ];
150      }
151  
152      transition complex_array_access() -> u8 {
153          let arr = complex_array_access_();
154          return arr[1][0].unwrap(); // should be 20
155      }
156  }
157  
158  
159  // --- Next Module: dep.leo --- //
160  
161  struct Wrapper {
162      arr: [inner::Foo?; 2], // array of optional structs
163  }
164  
165  // --- Next Module: dep/inner.leo --- //
166  
167  struct Foo {
168      x: u8?, // optional field
169  }