| ... | ... | @@ -1223,6 +1223,40 @@ pub const DeclGen = struct { |
| 1223 | 1223 | }); |
| 1224 | 1224 | return result_id; |
| 1225 | 1225 | }, |
| 1226 | .opt => { |
| 1227 | const payload_ty = ty.optionalChild(mod); |
| 1228 | const maybe_payload_val = val.optionalValue(mod); |
| 1229 | |
| 1230 | if (!payload_ty.hasRuntimeBits(mod)) { |
| 1231 | return try self.constBool(maybe_payload_val != null, .indirect); |
| 1232 | } else if (ty.optionalReprIsPayload(mod)) { |
| 1233 | // Optional representation is a nullable pointer or slice. |
| 1234 | if (maybe_payload_val) |payload_val| { |
| 1235 | return try self.constant(payload_ty, payload_val, .indirect); |
| 1236 | } else { |
| 1237 | const ptr_ty_ref = try self.resolveType(ty, .indirect); |
| 1238 | return self.spv.constNull(ptr_ty_ref); |
| 1239 | } |
| 1240 | } |
| 1241 | |
| 1242 | // Optional representation is a structure. |
| 1243 | // { Payload, Bool } |
| 1244 | |
| 1245 | const payload_id = if (maybe_payload_val) |payload_val| |
| 1246 | try self.constant(payload_ty, payload_val, .indirect) |
| 1247 | else |
| 1248 | try self.spv.constUndef(try self.resolveType(payload_ty, .indirect)); |
| 1249 | |
| 1250 | const has_pl_id = try self.constBool(maybe_payload_val != null, .indirect); |
| 1251 | |
| 1252 | const result_id = self.spv.allocId(); |
| 1253 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ |
| 1254 | .id_result_type = self.typeId(result_ty_ref), |
| 1255 | .id_result = result_id, |
| 1256 | .constituents = &.{ payload_id, has_pl_id }, |
| 1257 | }); |
| 1258 | return result_id; |
| 1259 | }, |
| 1226 | 1260 | // TODO: We can handle most pointers here (decl refs etc), because now they emit an extra |
| 1227 | 1261 | // OpVariable that is not really required. |
| 1228 | 1262 | else => { |