checker: disallow `unsafe` map copy (#8720)
parent
e4a67dea37
commit
0f8edd918a
|
@ -163,13 +163,12 @@ fn fetch_with_method(method Method, url string, _config FetchConfig) ?Response {
|
||||||
|
|
||||||
fn build_url_from_fetch(_url string, config FetchConfig) ?string {
|
fn build_url_from_fetch(_url string, config FetchConfig) ?string {
|
||||||
mut url := urllib.parse(_url) ?
|
mut url := urllib.parse(_url) ?
|
||||||
params := unsafe {config.params}
|
if config.params.len == 0 {
|
||||||
if params.len == 0 {
|
|
||||||
return url.str()
|
return url.str()
|
||||||
}
|
}
|
||||||
mut pieces := []string{}
|
mut pieces := []string{cap: config.params.len}
|
||||||
for key in params.keys() {
|
for key, val in config.params {
|
||||||
pieces << '$key=${params[key]}'
|
pieces << '$key=$val'
|
||||||
}
|
}
|
||||||
mut query := pieces.join('&')
|
mut query := pieces.join('&')
|
||||||
if url.raw_query.len > 1 {
|
if url.raw_query.len > 1 {
|
||||||
|
|
|
@ -2726,11 +2726,11 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
c.error('use `array2 $assign_stmt.op.str() array1.clone()` instead of `array2 $assign_stmt.op.str() array1` (or use `unsafe`)',
|
c.error('use `array2 $assign_stmt.op.str() array1.clone()` instead of `array2 $assign_stmt.op.str() array1` (or use `unsafe`)',
|
||||||
assign_stmt.pos)
|
assign_stmt.pos)
|
||||||
}
|
}
|
||||||
if left_sym.kind == .map && !c.inside_unsafe && assign_stmt.op in [.assign, .decl_assign]
|
if left_sym.kind == .map && assign_stmt.op in [.assign, .decl_assign]
|
||||||
&& right_sym.kind == .map && !right_type.is_ptr() && !left.is_blank_ident()
|
&& right_sym.kind == .map && !right_type.is_ptr() && !left.is_blank_ident()
|
||||||
&& right.is_lvalue() {
|
&& right.is_lvalue() {
|
||||||
// Do not allow `a = b`
|
// Do not allow `a = b`
|
||||||
c.error('cannot copy map: call `move` or `clone` method first (or use `unsafe`)',
|
c.error('cannot copy map: call `move` or `clone` method (or use a reference)',
|
||||||
right.position())
|
right.position())
|
||||||
}
|
}
|
||||||
left_is_ptr := left_type.is_ptr() || left_sym.is_pointer()
|
left_is_ptr := left_type.is_ptr() || left_sym.is_pointer()
|
||||||
|
|
|
@ -12,14 +12,14 @@ vlib/v/checker/tests/array_or_map_assign_err.vv:5:5: error: use `array2 = array1
|
||||||
| ^
|
| ^
|
||||||
6 |
|
6 |
|
||||||
7 | m1 := {'one': 1}
|
7 | m1 := {'one': 1}
|
||||||
vlib/v/checker/tests/array_or_map_assign_err.vv:8:8: error: cannot copy map: call `move` or `clone` method first (or use `unsafe`)
|
vlib/v/checker/tests/array_or_map_assign_err.vv:8:8: error: cannot copy map: call `move` or `clone` method (or use a reference)
|
||||||
6 |
|
6 |
|
||||||
7 | m1 := {'one': 1}
|
7 | m1 := {'one': 1}
|
||||||
8 | m2 := m1
|
8 | m2 := m1
|
||||||
| ~~
|
| ~~
|
||||||
9 | mut m3 := map[string]int{}
|
9 | mut m3 := map[string]int{}
|
||||||
10 | m3 = m1
|
10 | m3 = m1
|
||||||
vlib/v/checker/tests/array_or_map_assign_err.vv:10:7: error: cannot copy map: call `move` or `clone` method first (or use `unsafe`)
|
vlib/v/checker/tests/array_or_map_assign_err.vv:10:7: error: cannot copy map: call `move` or `clone` method (or use a reference)
|
||||||
8 | m2 := m1
|
8 | m2 := m1
|
||||||
9 | mut m3 := map[string]int{}
|
9 | mut m3 := map[string]int{}
|
||||||
10 | m3 = m1
|
10 | m3 = m1
|
||||||
|
|
|
@ -115,16 +115,18 @@ pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string
|
||||||
out += '/** @namespace $name */\n'
|
out += '/** @namespace $name */\n'
|
||||||
}
|
}
|
||||||
out += 'const $name = (function ('
|
out += 'const $name = (function ('
|
||||||
imports := unsafe {g.namespaces[node.name].imports}
|
mut namespace := g.namespaces[node.name]
|
||||||
for i, key in imports.keys() {
|
mut first := true
|
||||||
if i > 0 {
|
for _, val in namespace.imports {
|
||||||
|
if !first {
|
||||||
out += ', '
|
out += ', '
|
||||||
}
|
}
|
||||||
out += imports[key]
|
first = false
|
||||||
|
out += val
|
||||||
}
|
}
|
||||||
out += ') {\n\t'
|
out += ') {\n\t'
|
||||||
// private scope
|
// private scope
|
||||||
out += g.namespaces[node.name].out.str().trim_space()
|
out += namespace.out.str().trim_space()
|
||||||
// public scope
|
// public scope
|
||||||
out += '\n'
|
out += '\n'
|
||||||
if g.enable_doc {
|
if g.enable_doc {
|
||||||
|
@ -137,21 +139,23 @@ pub fn gen(files []ast.File, table &table.Table, pref &pref.Preferences) string
|
||||||
out += '\n\t\t$typ,'
|
out += '\n\t\t$typ,'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, pub_var in g.namespaces[node.name].pub_vars {
|
for i, pub_var in namespace.pub_vars {
|
||||||
out += '\n\t\t$pub_var'
|
out += '\n\t\t$pub_var'
|
||||||
if i < g.namespaces[node.name].pub_vars.len - 1 {
|
if i < namespace.pub_vars.len - 1 {
|
||||||
out += ','
|
out += ','
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if g.namespaces[node.name].pub_vars.len > 0 {
|
if namespace.pub_vars.len > 0 {
|
||||||
out += '\n\t'
|
out += '\n\t'
|
||||||
}
|
}
|
||||||
out += '};'
|
out += '};'
|
||||||
out += '\n})('
|
out += '\n})('
|
||||||
for i, key in imports.keys() {
|
first = true
|
||||||
if i > 0 {
|
for key, _ in namespace.imports {
|
||||||
|
if !first {
|
||||||
out += ', '
|
out += ', '
|
||||||
}
|
}
|
||||||
|
first = false
|
||||||
out += key.replace('.', '_')
|
out += key.replace('.', '_')
|
||||||
}
|
}
|
||||||
out += ');\n'
|
out += ');\n'
|
||||||
|
|
Loading…
Reference in New Issue