See #5401.
Creating this issue as a copy-on-write.
See #5401.
Creating this issue as a copy-on-write.
std.fmt.*print functions (#5401) (削除ここまで)std.fmt.bufPrint (#5401) Is this issue relevant anymore? It's being tracked in #31661, but I'm unsure if it should count as untested as there are tests for std.fmt.comptimePrint which does this internally, along with many many tests which use expectFmt which also does this.
Currently doing what the reproduction in the original issue does (i.e. std.fmt.comptimePrint("{}", .{"some string"}) causes a @compileError saying cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any}), which seems like correct behavior but which I don't know how to test for...
Also, apologies if opening this issue is the incorrect approach for this discussion...
I agree, "cannot format slice without a specifier" looks correct to me for that old code. Here's my modern repro (zig 0.16.0)
test{comptimevarbuf=[_]u8{0}**16;conststr=comptimetrystd.fmt.bufPrint(&buf,"{s} {s}",.{"test","123"});conststr2:[str.len]u8=str[0..].*;// avoid "error: runtime value contains reference to comptime var"trystd.testing.expectEqualStrings("test 123",&str2);}conststd=@import("std");That "avoid error" line is pretty gnarly (maybe there's a better way?) but this should now be correctly testing the old bug, as far as I understand it.
edit: I dug around and found these tests:
pubinlinefncomptimePrint(comptimefmt:[]constu8,args:anytype)*const[count(fmt,args):0]u8{comptime{varbuf:[count(fmt,args):0]u8=undefined;_=bufPrint(&buf,fmt,args)catchunreachable;buf[buf.len]=0;constfinal=buf;return&final;}}testcomptimePrint{@setEvalBranchQuota(2000);trystd.testing.expectEqual(*const[3:0]u8,@TypeOf(comptimePrint("{}",.{100})));trystd.testing.expectEqualSlices(u8,"100",comptimePrint("{}",.{100}));trystd.testing.expectEqualStrings("30",comptimePrint("{d}",.{30.0}));trystd.testing.expectEqualStrings("30.0",comptimePrint("{d:3.1}",.{30.0}));trystd.testing.expectEqualStrings("0.05",comptimePrint("{d}",.{0.05}));trystd.testing.expectEqualStrings("5e-2",comptimePrint("{e}",.{0.05}));}
(aha, there is a better way!)
Given the original error from 5401 (error: else prong required when switching on type '(enum literal)'), I think this behavior is already tested (bufPrint works at comptime) and no new tests are needed.
I would say the issue should just be closed, but I didn't look at the old compiler code so I don't understand how OP's test is related to the issue title ("peer type resolution of anonymous literals at comptime") and Vexu's comment. Based on Vexu's comment that seems like a bit of a footgun, but that behavior can't be "fixed"/tested since that sort of lazy analysis is fundamental to zig and its cross-compiling strategy. IMO the programmer should:
vara:S=if(cond).{.a=1}else.{.a=2};// <- write thisvara=if(cond)S{.a=1}else.{.a=2};// <- not thisand if they write the footgun version, the error is somewhat clear: (it says struct '5401.foo__anon_42777__struct_42793' , not struct '5401.S'
error: no field named 'b' in struct '5401.foo__anon_42777__struct_42793'
std.debug.print(".a = {}, .b = {}\n", .{ a.a, a.b });
^
So basically I agree with Vexu's 4th alternative, "document this limitation and add a error note about it being an anonymous literal", and I think it makes sense to just close the issue.
No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?