| ... | ... | @@ -16945,10 +16945,11 @@ fn coerce( |
| 16945 | 16945 | |
| 16946 | 16946 | const arena = sema.arena; |
| 16947 | 16947 | const target = sema.mod.getTarget(); |
| 16948 | const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst); |
| 16948 | 16949 | |
| 16949 | 16950 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| 16950 | 16951 | if (in_memory_result == .ok) { |
| 16951 | | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { |
| 16952 | if (maybe_inst_val) |val| { |
| 16952 | 16953 | // Keep the comptime Value representation; take the new type. |
| 16953 | 16954 | return sema.addConstant(dest_ty, val); |
| 16954 | 16955 | } |
| ... | ... | @@ -16956,16 +16957,15 @@ fn coerce( |
| 16956 | 16957 | return block.addBitCast(dest_ty, inst); |
| 16957 | 16958 | } |
| 16958 | 16959 | |
| 16959 | | // undefined to anything |
| 16960 | | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { |
| 16961 | | if (val.isUndef() or inst_ty.zigTypeTag() == .Undefined) { |
| 16962 | | return sema.addConstant(dest_ty, val); |
| 16963 | | } |
| 16964 | | } |
| 16965 | | assert(inst_ty.zigTypeTag() != .Undefined); |
| 16960 | const is_undef = if (maybe_inst_val) |val| val.isUndef() else false; |
| 16966 | 16961 | |
| 16967 | 16962 | switch (dest_ty.zigTypeTag()) { |
| 16968 | 16963 | .Optional => { |
| 16964 | // undefined sets the optional bit also to undefined. |
| 16965 | if (is_undef) { |
| 16966 | return sema.addConstUndef(dest_ty); |
| 16967 | } |
| 16968 | |
| 16969 | 16969 | // null to ?T |
| 16970 | 16970 | if (inst_ty.zigTypeTag() == .Null) { |
| 16971 | 16971 | return sema.addConstant(dest_ty, Value.@"null"); |
| ... | ... | @@ -17167,8 +17167,8 @@ fn coerce( |
| 17167 | 17167 | } |
| 17168 | 17168 | }, |
| 17169 | 17169 | .Many => p: { |
| 17170 | if (!inst_ty.isSlice()) break :p; |
| 17170 | 17171 | const inst_info = inst_ty.ptrInfo().data; |
| 17171 | | if (inst_info.size != .Slice) break :p; |
| 17172 | 17172 | |
| 17173 | 17173 | switch (try sema.coerceInMemoryAllowed( |
| 17174 | 17174 | block, |
| ... | ... | @@ -17191,9 +17191,6 @@ fn coerce( |
| 17191 | 17191 | return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src); |
| 17192 | 17192 | }, |
| 17193 | 17193 | } |
| 17194 | | |
| 17195 | | // This will give an extra hint on top of what the bottom of this func would provide. |
| 17196 | | try sema.checkPtrOperand(block, dest_ty_src, inst_ty); |
| 17197 | 17194 | }, |
| 17198 | 17195 | .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) { |
| 17199 | 17196 | .Float, .ComptimeFloat => float: { |
| ... | ... | @@ -17230,6 +17227,9 @@ fn coerce( |
| 17230 | 17227 | return block.addTyOp(.intcast, dest_ty, inst); |
| 17231 | 17228 | } |
| 17232 | 17229 | }, |
| 17230 | .Undefined => { |
| 17231 | return sema.addConstUndef(dest_ty); |
| 17232 | }, |
| 17233 | 17233 | else => {}, |
| 17234 | 17234 | }, |
| 17235 | 17235 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { |
| ... | ... | @@ -17275,6 +17275,9 @@ fn coerce( |
| 17275 | 17275 | //} |
| 17276 | 17276 | return try sema.addConstant(dest_ty, result_val); |
| 17277 | 17277 | }, |
| 17278 | .Undefined => { |
| 17279 | return sema.addConstUndef(dest_ty); |
| 17280 | }, |
| 17278 | 17281 | else => {}, |
| 17279 | 17282 | }, |
| 17280 | 17283 | .Enum => switch (inst_ty.zigTypeTag()) { |
| ... | ... | @@ -17313,11 +17316,14 @@ fn coerce( |
| 17313 | 17316 | return sema.unionToTag(block, dest_ty, inst, inst_src); |
| 17314 | 17317 | } |
| 17315 | 17318 | }, |
| 17319 | .Undefined => { |
| 17320 | return sema.addConstUndef(dest_ty); |
| 17321 | }, |
| 17316 | 17322 | else => {}, |
| 17317 | 17323 | }, |
| 17318 | 17324 | .ErrorUnion => switch (inst_ty.zigTypeTag()) { |
| 17319 | 17325 | .ErrorUnion => { |
| 17320 | | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |inst_val| { |
| 17326 | if (maybe_inst_val) |inst_val| { |
| 17321 | 17327 | switch (inst_val.tag()) { |
| 17322 | 17328 | .undef => return sema.addConstUndef(dest_ty), |
| 17323 | 17329 | .eu_payload => { |
| ... | ... | @@ -17341,7 +17347,15 @@ fn coerce( |
| 17341 | 17347 | // E to E!T |
| 17342 | 17348 | return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src); |
| 17343 | 17349 | }, |
| 17350 | .Undefined => { |
| 17351 | return sema.addConstUndef(dest_ty); |
| 17352 | }, |
| 17344 | 17353 | else => { |
| 17354 | // undefined sets the error code also to undefined. |
| 17355 | if (is_undef) { |
| 17356 | return sema.addConstUndef(dest_ty); |
| 17357 | } |
| 17358 | |
| 17345 | 17359 | // T to E!T |
| 17346 | 17360 | return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src); |
| 17347 | 17361 | }, |
| ... | ... | @@ -17353,6 +17367,9 @@ fn coerce( |
| 17353 | 17367 | return sema.coerceAnonStructToUnion(block, dest_ty, dest_ty_src, inst, inst_src); |
| 17354 | 17368 | } |
| 17355 | 17369 | }, |
| 17370 | .Undefined => { |
| 17371 | return sema.addConstUndef(dest_ty); |
| 17372 | }, |
| 17356 | 17373 | else => {}, |
| 17357 | 17374 | }, |
| 17358 | 17375 | .Array => switch (inst_ty.zigTypeTag()) { |
| ... | ... | @@ -17365,10 +17382,16 @@ fn coerce( |
| 17365 | 17382 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); |
| 17366 | 17383 | } |
| 17367 | 17384 | }, |
| 17385 | .Undefined => { |
| 17386 | return sema.addConstUndef(dest_ty); |
| 17387 | }, |
| 17368 | 17388 | else => {}, |
| 17369 | 17389 | }, |
| 17370 | 17390 | .Vector => switch (inst_ty.zigTypeTag()) { |
| 17371 | 17391 | .Array, .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src), |
| 17392 | .Undefined => { |
| 17393 | return sema.addConstUndef(dest_ty); |
| 17394 | }, |
| 17372 | 17395 | else => {}, |
| 17373 | 17396 | }, |
| 17374 | 17397 | .Struct => { |
| ... | ... | @@ -17382,6 +17405,13 @@ fn coerce( |
| 17382 | 17405 | else => {}, |
| 17383 | 17406 | } |
| 17384 | 17407 | |
| 17408 | // undefined to anything. We do this after the big switch above so that |
| 17409 | // special logic has a chance to run first, such as `*[N]T` to `[]T` which |
| 17410 | // should initialize the length field of the slice. |
| 17411 | if (is_undef) { |
| 17412 | return sema.addConstUndef(dest_ty); |
| 17413 | } |
| 17414 | |
| 17385 | 17415 | return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty }); |
| 17386 | 17416 | } |
| 17387 | 17417 | |
| ... | ... | @@ -18452,7 +18482,7 @@ fn coerceArrayPtrToSlice( |
| 18452 | 18482 | inst: Air.Inst.Ref, |
| 18453 | 18483 | inst_src: LazySrcLoc, |
| 18454 | 18484 | ) CompileError!Air.Inst.Ref { |
| 18455 | | if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| { |
| 18485 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { |
| 18456 | 18486 | const ptr_array_ty = sema.typeOf(inst); |
| 18457 | 18487 | const array_ty = ptr_array_ty.childType(); |
| 18458 | 18488 | const slice_val = try Value.Tag.slice.create(sema.arena, .{ |
| ... | ... | @@ -21336,7 +21366,7 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { |
| 21336 | 21366 | } |
| 21337 | 21367 | |
| 21338 | 21368 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { |
| 21339 | | return sema.addConstant(ty, Value.initTag(.undef)); |
| 21369 | return sema.addConstant(ty, Value.undef); |
| 21340 | 21370 | } |
| 21341 | 21371 | |
| 21342 | 21372 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { |