Skip to content

Commit dff5b1e

Browse files
authored
v2: lifetimes; clone() auto-generation for structs with heap-allocated fields (#26859)
1 parent 80fd66f commit dff5b1e

29 files changed

Lines changed: 1235 additions & 47 deletions

cmd/v/v.v

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -234,16 +234,19 @@ fn launch_v2_compiler(is_verbose bool, args []string, is_ownership bool) {
234234
tool_name := if is_ownership { 'v2_ownership' } else { 'v2' }
235235
mut v2_exe := os.getenv(delegated_v2_exe_env)
236236
if v2_exe == '' {
237-
v2_source := os.join_path(vroot, 'cmd', 'v2', 'v2.v')
237+
v2_main_source := os.join_path(vroot, 'cmd', 'v2', 'v2.v')
238+
v2_cmd_dir := os.join_path(vroot, 'cmd', 'v2')
239+
v2_vlib_dir := os.join_path(vroot, 'vlib', 'v2')
238240
v2_exe = cached_v2_executable_path(vroot, is_ownership)
239241
v2_exe_dir := os.dir(v2_exe)
240242
os.mkdir_all(v2_exe_dir) or {
241243
eprintln('cannot create `${v2_exe_dir}`: ${err}')
242244
exit(1)
243245
}
244-
if util.should_recompile_tool(vexe, v2_source, tool_name, v2_exe) {
246+
if util.should_recompile_tool(vexe, v2_cmd_dir, tool_name, v2_exe)
247+
|| util.should_recompile_tool(vexe, v2_vlib_dir, tool_name, v2_exe) {
245248
d_flag := if is_ownership { '-d ownership ' } else { '' }
246-
compilation_command := '${os.quoted_path(vexe)} ${d_flag}-o ${os.quoted_path(v2_exe)} ${os.quoted_path(v2_source)}'
249+
compilation_command := '${os.quoted_path(vexe)} ${d_flag}-o ${os.quoted_path(v2_exe)} ${os.quoted_path(v2_main_source)}'
247250
if is_verbose {
248251
println('Compiling ${tool_name} with: "${compilation_command}"')
249252
}
@@ -252,7 +255,7 @@ fn launch_v2_compiler(is_verbose bool, args []string, is_ownership bool) {
252255
tool_compilation := os.execute(compilation_command)
253256
os.chdir(current_work_dir) or {}
254257
if tool_compilation.exit_code != 0 {
255-
eprintln('cannot compile `${v2_source}`: ${tool_compilation.exit_code}\n${tool_compilation.output}')
258+
eprintln('cannot compile `${v2_main_source}`: ${tool_compilation.exit_code}\n${tool_compilation.output}')
256259
exit(1)
257260
}
258261
}

doc/ownership.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,26 @@ fn main() {
8888
}
8989
```
9090

91+
### Explicit lifetimes
92+
93+
Ownership mode also supports explicit named lifetimes with `^name`.
94+
95+
Use `&^a T` for a borrowed reference with an explicit lifetime and `[^a]`
96+
in generic parameter and argument lists:
97+
98+
```v ignore
99+
struct Ignore {}
100+
101+
struct IgnoreMatch[^a] {}
102+
103+
fn matched_dir_entry[^a](self &^a Ignore) IgnoreMatch[^a] {
104+
return IgnoreMatch[^a]{}
105+
}
106+
```
107+
108+
`^` is used instead of Rust's `'` because `'` is already used for string and
109+
character literals in V.
110+
91111
Multiple immutable borrows are allowed:
92112

93113
```v okfmt

vlib/v/checker/tests/assign_immutable_reference_call_result_err.vv

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ fn rere(a &User) &User {
1111
}
1212

1313
fn main() {
14-
ja := User{name: 'foo'}
14+
ja := User{
15+
name: 'foo'
16+
}
1517
mut x := rere(ja)
1618
x.name = 'bar'
1719
}

vlib/v/checker/tests/disable_explicit_mutability.vv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,6 @@ fn main() {
3131
}
3232
u8 {}
3333
}
34+
3435
println('${counter.value} ${arr.len} ${nums.len} ${inc_copy(1)} ${i}')
3536
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
fn main() {
2-
_ := [2]int[1 2 3]
2+
_ := [2]int[1, 2, 3]
33
}

vlib/v/checker/tests/if_smartcast_mutation_err.vv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
type SmartcastValue = int | string
2+
23
fn main() {
34
a := SmartcastValue(1)
45
if a is int {

vlib/v/checker/tests/orm_dynamic_unknown_field_err.vv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct User {
88
fn main() {
99
db := sqlite.connect(':memory:') or { panic(err) }
1010
where_expr := {
11-
if true { zzz == 'Alice' },
11+
if true { zzz == 'Alice' }
1212
}
1313
_ := sql db {
1414
dynamic select from User where where_expr

vlib/v/checker/tests/pool_processor_callback_array_return_err.vv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ struct Foo {
66

77
fn main() {
88
_ := pool.new_pool_processor(
9-
callback: fn (mut pp pool.PoolProcessor, idx int, wid int) []Foo {
9+
callback: fn (mut pp pool.PoolProcessor, idx int, wid int) []main.Foo {
1010
_ = wid
1111
return [Foo{
1212
page: pp.get_item[int](idx).str()

vlib/v/gen/c/testdata/defer_fn_match_branch_capture.vv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ fn (mut o Object) f(x int) int {
1919
}
2020
else {}
2121
}
22+
2223
return 42
2324
}
2425

vlib/v2/ast/ast.v

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub type Expr = ArrayInitExpr
3333
| Keyword
3434
| KeywordOperator
3535
| LambdaExpr
36+
| LifetimeExpr
3637
| LockExpr
3738
| MapInitExpr
3839
| MatchExpr
@@ -94,6 +95,7 @@ pub type Type = AnonStructType
9495
| NilType
9596
| NoneType
9697
| OptionType
98+
| PointerType
9799
| ResultType
98100
| ThreadType
99101
| TupleType
@@ -155,6 +157,9 @@ pub fn (expr Expr) name() string {
155157
Keyword {
156158
expr.tok.str()
157159
}
160+
LifetimeExpr {
161+
'^' + expr.name
162+
}
158163
ModifierExpr {
159164
'${expr.kind} ${expr.expr.name()}'
160165
}
@@ -239,6 +244,9 @@ pub fn (expr Expr) pos() token.Pos {
239244
KeywordOperator {
240245
expr.pos
241246
}
247+
LifetimeExpr {
248+
expr.pos
249+
}
242250
LambdaExpr {
243251
expr.pos
244252
}
@@ -412,7 +420,7 @@ pub:
412420
pub struct GenericArgs {
413421
pub:
414422
lhs Expr
415-
args []Expr // concrete types
423+
args []Expr // concrete types and lifetimes
416424
pos token.Pos
417425
}
418426

@@ -561,6 +569,12 @@ pub:
561569
pos token.Pos
562570
}
563571

572+
pub struct LifetimeExpr {
573+
pub:
574+
name string
575+
pos token.Pos
576+
}
577+
564578
// name_str returns the parameter name.
565579
pub fn (p Parameter) name_str() string {
566580
return p.name
@@ -1039,6 +1053,12 @@ pub:
10391053
base_type Expr = empty_expr
10401054
}
10411055

1056+
pub struct PointerType {
1057+
pub:
1058+
base_type Expr = empty_expr
1059+
lifetime string
1060+
}
1061+
10421062
pub struct ResultType {
10431063
pub:
10441064
base_type Expr = empty_expr

0 commit comments

Comments
 (0)