Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion cmd/v/macos_v3_args.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ fn macos_v3_non_compilation_command(command string) bool {
'interpret', 'get', 'translate']
}

// is_macos_v3_compiler_bootstrap reports whether `normalized_path` targets the
// `vlib/v3/v3.v` compiler bootstrap, which must build with the compatibility
// compiler rather than the embedded V3 driver. It matches the repo-relative path
// and any path ending in it, and also resolves a bare `v3.v` (for example when
// invoked from inside `vlib/v3`) through its real path, so the bootstrap is
// recognized regardless of the working directory. Both dispatch gates rely on
// it, so keep the detection in one place to stop them drifting.
@[markused]
fn is_macos_v3_compiler_bootstrap(normalized_path string) bool {
if normalized_path == 'vlib/v3/v3.v' || normalized_path.ends_with('/vlib/v3/v3.v') {
return true
}
// Only a file literally named `v3.v` can be the bootstrap; skip the real-path
// resolution (a filesystem lookup) for every other compilation target.
if os.base(normalized_path) != 'v3.v' {
return false
}
real_path := os.real_path(normalized_path).replace('\\', '/').trim_right('/')
return real_path == 'vlib/v3/v3.v' || real_path.ends_with('/vlib/v3/v3.v')
}

// macos_v3_force_requested reports whether `-new-compiler` should hand this
// invocation to the embedded V3 compiler. It gates on `-old-compiler`
// precedence, options/modes V3 cannot honor yet, and whether the command is an
Expand All @@ -44,7 +65,7 @@ fn macos_v3_force_requested(command string, prefs &pref.Preferences) bool {
normalized_path := prefs.path.replace('\\', '/').trim_right('/')
if normalized_path == 'cmd/v' || normalized_path.starts_with('cmd/v/')
|| normalized_path.contains('/cmd/v/') || normalized_path.ends_with('/cmd/v')
|| normalized_path == 'vlib/v3/v3.v' || normalized_path.ends_with('/vlib/v3/v3.v') {
|| is_macos_v3_compiler_bootstrap(normalized_path) {
return false
}
return command in ['run', 'build'] || prefs.is_script || os.is_dir(prefs.path)
Expand Down
2 changes: 1 addition & 1 deletion cmd/v/macos_v3_darwin.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fn is_macos_v3_relevant_command(command string, prefs &pref.Preferences) bool {
// modes use V3 by default.
if normalized_path == 'cmd/v' || normalized_path.starts_with('cmd/v/')
|| normalized_path.contains('/cmd/v/') || normalized_path.ends_with('/cmd/v')
|| normalized_path == 'vlib/v3/v3.v' || normalized_path.ends_with('/vlib/v3/v3.v')
|| is_macos_v3_compiler_bootstrap(normalized_path)
|| is_macos_v3_internal_tool_bootstrap(normalized_path, os.getenv('VCHILD') == 'true') {
return false
}
Expand Down
24 changes: 24 additions & 0 deletions cmd/v/macos_v3_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,30 @@ fn test_macos_v3_relevant_command_selects_user_compilation_and_tests() {
}
}

fn test_macos_v3_compiler_bootstrap_is_detected_from_any_cwd() {
// Repo-relative and absolute spellings are recognized directly.
assert is_macos_v3_compiler_bootstrap('vlib/v3/v3.v')
assert is_macos_v3_compiler_bootstrap('/home/user/v/vlib/v3/v3.v')
// Non-bootstrap targets stay on the V3 path.
assert !is_macos_v3_compiler_bootstrap('main.v')
assert !is_macos_v3_compiler_bootstrap('cmd/v')
assert !is_macos_v3_compiler_bootstrap('some/other/place/v3.v')

// A bare `v3.v` invoked from inside vlib/v3 must resolve to the bootstrap so
// it builds with the compatibility compiler instead of the embedded V3 driver.
repo_root := os.dir(os.dir(os.real_path(@FILE)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ascend one more directory before testing the bare path

With this test located at cmd/v/macos_v3_test.v, two os.dir calls resolve repo_root to <repo>/cmd, so v3_dir becomes <repo>/cmd/vlib/v3. The existence guard is therefore false in a normal checkout, and the key bare and dotted assertions never run, allowing the exact bare-v3.v dispatch regression this test targets to pass unnoticed.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — the two os.dir calls resolved repo_root to <repo>/cmd, so the vlib/v3 existence guard was always false and the key assertions never ran.

Fixed in 3b22b60 by dropping the @FILE-relative guard entirely: the test now builds an isolated <tmp>/vlib/v3/v3.v (plus a sibling non-bootstrap v3.v) and chdirs into it, so the real-path resolution is exercised unconditionally regardless of where the test file lives. I also confirmed the test now fails on assert bare if the helper's real-path branch is removed, so the regression can no longer pass unnoticed.

v3_dir := os.join_path(repo_root, 'vlib', 'v3')
if os.exists(os.join_path(v3_dir, 'v3.v')) {
saved := os.getwd()
os.chdir(v3_dir) or { return }
bare := is_macos_v3_compiler_bootstrap('v3.v')
dotted := is_macos_v3_compiler_bootstrap('./v3.v')
os.chdir(saved) or {}
assert bare
assert dotted
}
}

fn test_macos_v3_dispatch_allows_the_implicit_gc_default() {
$if macos {
implicit_gc, _ := pref.parse_args_and_show_errors([], ['', 'main.v'], false)
Expand Down
204 changes: 114 additions & 90 deletions vlib/v3/transform/array.v

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions vlib/v3/transform/comptime.v
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ fn (mut t Transformer) expand_comptime_for(id flat.NodeId, node flat.Node) []fla
// one-letter name from another function, but this template's `T` must not be
// expanded until its specialization is cloned.
if is_generic_fn_placeholder_name(node.typ) && t.generic_arg_is_unresolved(node.typ) {
return arr1(id)
return [id]
}
base_type := if kind == 'methods' {
source := t.comptime_for_value_source_type(node.typ) or { node.typ }
Expand All @@ -343,7 +343,7 @@ fn (mut t Transformer) expand_comptime_for(id flat.NodeId, node flat.Node) []fla
// Its metadata and `$zero(field.typ)` children are needed when the concrete
// specialization is cloned later; erasing them here leaves empty child ids.
if t.generic_arg_is_unresolved(base_type) {
return arr1(id)
return [id]
}
t.ignore_comptime_for_subtree(id)
body_id := t.a.child(&node, 0)
Expand Down Expand Up @@ -3410,7 +3410,7 @@ fn (mut t Transformer) clone_field_subst_scoped(id flat.NodeId, var_name string,
arg := t.a.child_node(&node, 1)
if callee.kind == .ident && callee.value == '__v3_isreftype' && arg.kind == .ident
&& arg.value == var_name {
return t.make_call('__v3_isreftype', arr1(t.make_sizeof_type(fm.comptime_typ)))
return t.make_call('__v3_isreftype', [t.make_sizeof_type(fm.comptime_typ)])
}
}
if node.kind == .ident && node.value == var_name {
Expand Down
Loading
Loading