| ... | @@ -16945,10 +16945,11 @@ fn coerce( | ... | @@ -16945,10 +16945,11 @@ fn coerce( |
| 16945 | | 16945 | |
| 16946 | const arena = sema.arena; | 16946 | const arena = sema.arena; |
| 16947 | const target = sema.mod.getTarget(); | 16947 | const target = sema.mod.getTarget(); |
| | 16948 | const maybe_inst_val = try sema.resolveMaybeUndefVal(block, inst_src, inst); |
| 16948 | | 16949 | |
| 16949 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); | 16950 | const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src); |
| 16950 | if (in_memory_result == .ok) { | 16951 | if (in_memory_result == .ok) { |
| 16951 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { | 16952 | if (maybe_inst_val) |val| { |
| 16952 | // Keep the comptime Value representation; take the new type. | 16953 | // Keep the comptime Value representation; take the new type. |
| 16953 | return sema.addConstant(dest_ty, val); | 16954 | return sema.addConstant(dest_ty, val); |
| 16954 | } | 16955 | } |
| ... | @@ -16956,16 +16957,15 @@ fn coerce( | ... | @@ -16956,16 +16957,15 @@ fn coerce( |
| 16956 | return block.addBitCast(dest_ty, inst); | 16957 | return block.addBitCast(dest_ty, inst); |
| 16957 | } | 16958 | } |
| 16958 | | 16959 | |
| 16959 | // undefined to anything | 16960 | const is_undef = if (maybe_inst_val) |val| val.isUndef() else false; |
| 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); | | |
| 16966 | | 16961 | |
| 16967 | switch (dest_ty.zigTypeTag()) { | 16962 | switch (dest_ty.zigTypeTag()) { |
| 16968 | .Optional => { | 16963 | .Optional => { |
| | 16964 | // undefined sets the optional bit also to undefined. |
| | 16965 | if (is_undef) { |
| | 16966 | return sema.addConstUndef(dest_ty); |
| | 16967 | } |
| | 16968 | |
| 16969 | // null to ?T | 16969 | // null to ?T |
| 16970 | if (inst_ty.zigTypeTag() == .Null) { | 16970 | if (inst_ty.zigTypeTag() == .Null) { |
| 16971 | return sema.addConstant(dest_ty, Value.@"null"); | 16971 | return sema.addConstant(dest_ty, Value.@"null"); |
| ... | @@ -17167,8 +17167,8 @@ fn coerce( | ... | @@ -17167,8 +17167,8 @@ fn coerce( |
| 17167 | } | 17167 | } |
| 17168 | }, | 17168 | }, |
| 17169 | .Many => p: { | 17169 | .Many => p: { |
| | 17170 | if (!inst_ty.isSlice()) break :p; |
| 17170 | const inst_info = inst_ty.ptrInfo().data; | 17171 | const inst_info = inst_ty.ptrInfo().data; |
| 17171 | if (inst_info.size != .Slice) break :p; | | |
| 17172 | | 17172 | |
| 17173 | switch (try sema.coerceInMemoryAllowed( | 17173 | switch (try sema.coerceInMemoryAllowed( |
| 17174 | block, | 17174 | block, |
| ... | @@ -17191,9 +17191,6 @@ fn coerce( | ... | @@ -17191,9 +17191,6 @@ fn coerce( |
| 17191 | return sema.coerceCompatiblePtrs(block, dest_ty, slice_ptr, inst_src); | 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 | .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) { | 17195 | .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) { |
| 17199 | .Float, .ComptimeFloat => float: { | 17196 | .Float, .ComptimeFloat => float: { |
| ... | @@ -17230,6 +17227,9 @@ fn coerce( | ... | @@ -17230,6 +17227,9 @@ fn coerce( |
| 17230 | return block.addTyOp(.intcast, dest_ty, inst); | 17227 | return block.addTyOp(.intcast, dest_ty, inst); |
| 17231 | } | 17228 | } |
| 17232 | }, | 17229 | }, |
| | 17230 | .Undefined => { |
| | 17231 | return sema.addConstUndef(dest_ty); |
| | 17232 | }, |
| 17233 | else => {}, | 17233 | else => {}, |
| 17234 | }, | 17234 | }, |
| 17235 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { | 17235 | .Float, .ComptimeFloat => switch (inst_ty.zigTypeTag()) { |
| ... | @@ -17275,6 +17275,9 @@ fn coerce( | ... | @@ -17275,6 +17275,9 @@ fn coerce( |
| 17275 | //} | 17275 | //} |
| 17276 | return try sema.addConstant(dest_ty, result_val); | 17276 | return try sema.addConstant(dest_ty, result_val); |
| 17277 | }, | 17277 | }, |
| | 17278 | .Undefined => { |
| | 17279 | return sema.addConstUndef(dest_ty); |
| | 17280 | }, |
| 17278 | else => {}, | 17281 | else => {}, |
| 17279 | }, | 17282 | }, |
| 17280 | .Enum => switch (inst_ty.zigTypeTag()) { | 17283 | .Enum => switch (inst_ty.zigTypeTag()) { |
| ... | @@ -17313,11 +17316,14 @@ fn coerce( | ... | @@ -17313,11 +17316,14 @@ fn coerce( |
| 17313 | return sema.unionToTag(block, dest_ty, inst, inst_src); | 17316 | return sema.unionToTag(block, dest_ty, inst, inst_src); |
| 17314 | } | 17317 | } |
| 17315 | }, | 17318 | }, |
| | 17319 | .Undefined => { |
| | 17320 | return sema.addConstUndef(dest_ty); |
| | 17321 | }, |
| 17316 | else => {}, | 17322 | else => {}, |
| 17317 | }, | 17323 | }, |
| 17318 | .ErrorUnion => switch (inst_ty.zigTypeTag()) { | 17324 | .ErrorUnion => switch (inst_ty.zigTypeTag()) { |
| 17319 | .ErrorUnion => { | 17325 | .ErrorUnion => { |
| 17320 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |inst_val| { | 17326 | if (maybe_inst_val) |inst_val| { |
| 17321 | switch (inst_val.tag()) { | 17327 | switch (inst_val.tag()) { |
| 17322 | .undef => return sema.addConstUndef(dest_ty), | 17328 | .undef => return sema.addConstUndef(dest_ty), |
| 17323 | .eu_payload => { | 17329 | .eu_payload => { |
| ... | @@ -17341,7 +17347,15 @@ fn coerce( | ... | @@ -17341,7 +17347,15 @@ fn coerce( |
| 17341 | // E to E!T | 17347 | // E to E!T |
| 17342 | return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src); | 17348 | return sema.wrapErrorUnionSet(block, dest_ty, inst, inst_src); |
| 17343 | }, | 17349 | }, |
| | 17350 | .Undefined => { |
| | 17351 | return sema.addConstUndef(dest_ty); |
| | 17352 | }, |
| 17344 | else => { | 17353 | else => { |
| | 17354 | // undefined sets the error code also to undefined. |
| | 17355 | if (is_undef) { |
| | 17356 | return sema.addConstUndef(dest_ty); |
| | 17357 | } |
| | 17358 | |
| 17345 | // T to E!T | 17359 | // T to E!T |
| 17346 | return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src); | 17360 | return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src); |
| 17347 | }, | 17361 | }, |
| ... | @@ -17353,6 +17367,9 @@ fn coerce( | ... | @@ -17353,6 +17367,9 @@ fn coerce( |
| 17353 | return sema.coerceAnonStructToUnion(block, dest_ty, dest_ty_src, inst, inst_src); | 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 | else => {}, | 17373 | else => {}, |
| 17357 | }, | 17374 | }, |
| 17358 | .Array => switch (inst_ty.zigTypeTag()) { | 17375 | .Array => switch (inst_ty.zigTypeTag()) { |
| ... | @@ -17365,10 +17382,16 @@ fn coerce( | ... | @@ -17365,10 +17382,16 @@ fn coerce( |
| 17365 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); | 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 | else => {}, | 17388 | else => {}, |
| 17369 | }, | 17389 | }, |
| 17370 | .Vector => switch (inst_ty.zigTypeTag()) { | 17390 | .Vector => switch (inst_ty.zigTypeTag()) { |
| 17371 | .Array, .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src), | 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 | else => {}, | 17395 | else => {}, |
| 17373 | }, | 17396 | }, |
| 17374 | .Struct => { | 17397 | .Struct => { |
| ... | @@ -17382,6 +17405,13 @@ fn coerce( | ... | @@ -17382,6 +17405,13 @@ fn coerce( |
| 17382 | else => {}, | 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 | return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty }); | 17415 | return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty }); |
| 17386 | } | 17416 | } |
| 17387 | | 17417 | |
| ... | @@ -18452,7 +18482,7 @@ fn coerceArrayPtrToSlice( | ... | @@ -18452,7 +18482,7 @@ fn coerceArrayPtrToSlice( |
| 18452 | inst: Air.Inst.Ref, | 18482 | inst: Air.Inst.Ref, |
| 18453 | inst_src: LazySrcLoc, | 18483 | inst_src: LazySrcLoc, |
| 18454 | ) CompileError!Air.Inst.Ref { | 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 | const ptr_array_ty = sema.typeOf(inst); | 18486 | const ptr_array_ty = sema.typeOf(inst); |
| 18457 | const array_ty = ptr_array_ty.childType(); | 18487 | const array_ty = ptr_array_ty.childType(); |
| 18458 | const slice_val = try Value.Tag.slice.create(sema.arena, .{ | 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,7 +21366,7 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { |
| 21336 | } | 21366 | } |
| 21337 | | 21367 | |
| 21338 | fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { | 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 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { | 21372 | pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { |