Skip to content

Commit 4b6fbbc

Browse files
committed
v3: preserve fallback failure stages (PR #28131 review)
1 parent a5e2e2f commit 4b6fbbc

5 files changed

Lines changed: 49 additions & 16 deletions

File tree

cmd/tools/modules/vbugreport/c_error_storage_test.v

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ fn test_c_error_string_returns_empty_without_error_line() {
4747

4848
fn test_c_error_string_preserves_v3_internal_error_message() {
4949
// v3-compiler-error reports stage an `error:`-prefixed message so it survives
50-
// c_error_string as a nonempty, stable, groupable diagnostic (PR #28131 review).
51-
msg := 'error: the experimental V3 compiler hit an internal compiler error building this program (the stable V compiler built it successfully)'
50+
// c_error_string as a nonempty, groupable diagnostic. Preserve the compiler stage
51+
// too, so unrelated V3 failures do not collapse into the same stored error.
52+
msg := 'error: the experimental V3 compiler hit an internal compiler error building this program during semantic checking (the stable V compiler built it successfully)'
5253
assert c_error_string(msg) == msg
5354
}

cmd/v/macos_v3_dispatch.c.v

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,21 @@ const macos_v3_c_error_source_name_file = 'source_name'
3737
// `macos_v3_compiler_error_fallback` the report describes a V3 internal compiler
3838
// error (V source only) instead of a generated-C compilation error.
3939
const macos_v3_c_error_kind_file = 'kind'
40-
// the diagnostic uploaded for a V3 internal compiler error (starts with `error:` so the
41-
// receiver's c_error_string parser stores a nonempty, groupable diagnostic).
42-
const macos_v3_compiler_error_message = 'error: the experimental V3 compiler hit an internal compiler error building this program (the stable V compiler built it successfully)'
40+
// the base diagnostic uploaded for a V3 internal compiler error (starts with `error:` so
41+
// the receiver's c_error_string parser stores a nonempty, groupable diagnostic).
42+
const macos_v3_compiler_error_message_base = 'error: the experimental V3 compiler hit an internal compiler error building this program'
43+
44+
fn macos_v3_compiler_error_message(stage string) string {
45+
stage_suffix := if stage == '' { '' } else { ' during ${stage}' }
46+
return '${macos_v3_compiler_error_message_base}${stage_suffix} (the stable V compiler built it successfully)'
47+
}
48+
49+
fn macos_v3_fallback_reason_and_stage(payload string) (string, string) {
50+
if !payload.contains('\n') {
51+
return payload, ''
52+
}
53+
return payload.all_before('\n'), payload.all_after_first('\n').trim_space()
54+
}
4355

4456
fn maybe_delegate_to_macos_v3(command string, prefs &pref.Preferences) ?MacosV3CErrorReport {
4557
if os.getenv(macos_v3_retry_env) == '1' {
@@ -195,7 +207,8 @@ fn replace_macos_v3_process_environment(environment map[string]string) {
195207
}
196208

197209
fn retry_macos_v3_with_old_compiler(caller_environment map[string]string, fallback_file string, c_error_dir string, retry_args []string, is_verbose bool, input_path string) {
198-
fallback_reason := os.read_file(fallback_file) or { return }
210+
fallback_payload := os.read_file(fallback_file) or { return }
211+
fallback_reason, fallback_stage := macos_v3_fallback_reason_and_stage(fallback_payload)
199212
os.rm(fallback_file) or {}
200213
if fallback_reason !in [macos_v3_inline_asm_fallback, macos_v3_compiler_error_fallback,
201214
macos_v3_c_error_fallback] {
@@ -242,7 +255,8 @@ fn retry_macos_v3_with_old_compiler(caller_environment map[string]string, fallba
242255
// or non-V input yields no source, so the report stays metadata-only but the
243256
// fallback is never silent.
244257
export_macos_v3_report_content(macos_v3_compiler_error_fallback, 'v3',
245-
macos_v3_compiler_error_message, macos_v3_compiler_error_input_source(input_path))
258+
macos_v3_compiler_error_message(fallback_stage),
259+
macos_v3_compiler_error_input_source(input_path))
246260
os.rmdir_all(c_error_dir) or {}
247261
if should_report {
248262
eprintln('V3 compilation failed; retrying with `-old-compiler`.')

cmd/v/macos_v3_test.v

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,10 +1488,12 @@ fn test_macos_v3_compiler_error_content_extraction() {
14881488
}
14891489
whole := lines.join('\n')
14901490
os.write_file(source, whole)!
1491+
compiler_error := macos_v3_compiler_error_message('source parsing')
14911492
v_file, v_source := builder.bounded_v3_fallback_source(macos_v3_compiler_error_fallback,
1492-
macos_v3_compiler_error_message, macos_v3_compiler_error_input_source(source))
1493+
compiler_error, macos_v3_compiler_error_input_source(source))
14931494
assert v_file == 'prog.v'
14941495
assert v_source != ''
1496+
assert compiler_error.contains('during source parsing')
14951497
// A bounded strict subset — never the whole file.
14961498
assert v_source.len < whole.len
14971499
// A directory build, a non-V file, or a missing input yields no source, so the
@@ -1501,10 +1503,16 @@ fn test_macos_v3_compiler_error_content_extraction() {
15011503
for empty in [root, note, os.join_path(root, 'missing.v'), ''] {
15021504
resolved := macos_v3_compiler_error_input_source(empty)
15031505
ef, es := builder.bounded_v3_fallback_source(macos_v3_compiler_error_fallback,
1504-
macos_v3_compiler_error_message, resolved)
1506+
compiler_error, resolved)
15051507
assert ef == '', empty
15061508
assert es == '', empty
15071509
}
1510+
legacy_reason, legacy_stage := macos_v3_fallback_reason_and_stage('compiler_error')
1511+
assert legacy_reason == macos_v3_compiler_error_fallback
1512+
assert legacy_stage == ''
1513+
reason, stage := macos_v3_fallback_reason_and_stage('compiler_error\nsemantic checking')
1514+
assert reason == macos_v3_compiler_error_fallback
1515+
assert stage == 'semantic checking'
15081516
}
15091517
}
15101518

@@ -1741,15 +1749,15 @@ fn test_take_macos_v3_report_content_carries_no_path() {
17411749
}
17421750
os.unsetenv(macos_v3_c_error_dir_env)
17431751
// A forwarded content report round-trips as content only.
1744-
export_macos_v3_report_content(macos_v3_compiler_error_fallback, 'v3',
1745-
macos_v3_compiler_error_message, '')
1752+
compiler_error := macos_v3_compiler_error_message('type specialization')
1753+
export_macos_v3_report_content(macos_v3_compiler_error_fallback, 'v3', compiler_error, '')
17461754
report := take_macos_v3_report_content() or {
17471755
assert false, 'the forwarded content report must be returned'
17481756
return
17491757
}
17501758
assert report.kind == macos_v3_compiler_error_fallback
17511759
assert report.ccompiler == 'v3'
1752-
assert report.c_output == macos_v3_compiler_error_message
1760+
assert report.c_output == compiler_error
17531761
// The variables are cleared, so a second take finds nothing.
17541762
if _ := take_macos_v3_report_content() {
17551763
assert false, 'the content variables must be cleared after a take'

vlib/v3/driver/driver.v

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5967,9 +5967,12 @@ fn record_user_define(mut defines []string, mut values map[string]string, define
59675967
values[name] = value
59685968
}
59695969

5970-
fn stage_macos_v3_compiler_error_fallback(fallback_file string) {
5970+
fn stage_macos_v3_compiler_error_fallback(fallback_file string, stage string) {
59715971
if fallback_file != '' {
5972-
os.write_file(fallback_file, macos_v3_compiler_error_fallback) or {}
5972+
// The first line remains the machine-readable fallback reason. The second
5973+
// carries only a controlled stage name, so a successful compatibility build
5974+
// can report where V3 failed even when no source excerpt is available.
5975+
os.write_file(fallback_file, '${macos_v3_compiler_error_fallback}\n${stage}') or {}
59735976
}
59745977
}
59755978

@@ -6430,7 +6433,7 @@ pub fn run(args []string) {
64306433
// produced its output. Specialized failures overwrite it below. Successful
64316434
// run/test programs clear it before launch, so their exit status is never
64326435
// mistaken for a compiler failure by the macOS driver.
6433-
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file)
6436+
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file, 'command-line processing')
64346437

64356438
mut input_file := ''
64366439
mut output_file := ''
@@ -7334,6 +7337,7 @@ pub fn run(args []string) {
73347337
// Cache markers and scoped output are stable across ordered worker chunks, so cached
73357338
// and preallocated builds use the same parallel function-body generator.
73367339
mut cache_no_parallel_cgen := current_no_parallel
7340+
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file, 'source parsing')
73377341
mut p := parser.Parser.new(prefs)
73387342
if building_v || cmd_v_build {
73397343
p.reserve_selfhost_ast()
@@ -7876,6 +7880,7 @@ pub fn run(args []string) {
78767880
// Type-collect + check BEFORE transform, so the transformer is type-aware
78777881
// (like v2: check runs before transform). The transformer reads cached
78787882
// per-expression types for type-dependent lowering.
7883+
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file, 'semantic checking')
78797884
mut pre_tc := types.TypeChecker.new(a)
78807885
mut checker_notice_count := 0
78817886
mut checker_warning_count := 0
@@ -8258,6 +8263,7 @@ pub fn run(args []string) {
82588263
// Transform (match lowering, string/in lowering, etc.). Threaded transform is enabled
82598264
// by default for compatible builds, and `-no-parallel` disables both threaded transform
82608265
// and cgen.
8266+
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file, 'AST transformation')
82618267
mut transform_was_parallel := false
82628268
mut transform_errors := []string{}
82638269
mut incremental_synthesized_helpers := []string{}
@@ -8671,6 +8677,7 @@ pub fn run(args []string) {
86718677
// Monomorphization only adds specialized generic instantiations to `used_fns`.
86728678
// Markused and Cgen already exclude unreachable generic templates, so builds
86738679
// with no reachable generic use need no generic cleanup pass at all.
8680+
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file, 'type specialization')
86748681
if cgen_cache_hit {
86758682
// The cached C plan and metadata are the only consumers of the specialized
86768683
// AST and checker state on this path.
@@ -8828,6 +8835,7 @@ pub fn run(args []string) {
88288835
} else {
88298836
b.step('finalize')
88308837
}
8838+
stage_macos_v3_compiler_error_fallback(macos_v3_fallback_file, 'backend code generation')
88318839
if backend == 'wasm' {
88328840
if msg := unsupported_backend_error(a, &pre_tc, used_fns, backend) {
88338841
eprintln(msg)

vlib/v3/tests/driver_cli_test.v

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,9 @@ fn main() {
10031003
result := run_driver_with_environment(v3_bin, ['-silent', '-no-parallel', '-nocache',
10041004
'-no-memory-limit', source], environment)
10051005
assert result.exit_code != 0
1006-
assert os.read_file(fallback_file)! == 'compiler_error'
1006+
fallback_payload := os.read_file(fallback_file)!
1007+
assert fallback_payload.starts_with('compiler_error\n')
1008+
assert fallback_payload.all_after_first('\n').trim_space() != ''
10071009

10081010
compat_output := os.join_path(root, 'compat')
10091011
compat := cmdexec.run(@VEXE, ['-old-compiler', '-o', compat_output, source])

0 commit comments

Comments
 (0)