checker: disallow `unsafe` map copy (#8720)

pull/8799/head
Nick Treleaven 2021-02-17 04:19:25 +00:00 committed by GitHub
parent e4a67dea37
commit 0f8edd918a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 19 deletions

View File

@ -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 {

View File

@ -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()

View File

@ -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

View File

@ -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'