all: allow functions to return `shared` object (#8606)
							parent
							
								
									fe9d062b41
								
							
						
					
					
						commit
						5343f1374b
					
				| 
						 | 
					@ -2548,7 +2548,7 @@ fn (mut g Gen) expr(node ast.Expr) {
 | 
				
			||||||
				node.return_type.clear_flag(.optional)
 | 
									node.return_type.clear_flag(.optional)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			mut shared_styp := ''
 | 
								mut shared_styp := ''
 | 
				
			||||||
			if g.is_shared {
 | 
								if g.is_shared && !ret_type.has_flag(.shared_f) {
 | 
				
			||||||
				ret_sym := g.table.get_type_symbol(ret_type)
 | 
									ret_sym := g.table.get_type_symbol(ret_type)
 | 
				
			||||||
				shared_typ := ret_type.set_flag(.shared_f)
 | 
									shared_typ := ret_type.set_flag(.shared_f)
 | 
				
			||||||
				shared_styp = g.typ(shared_typ)
 | 
									shared_styp = g.typ(shared_typ)
 | 
				
			||||||
| 
						 | 
					@ -2576,7 +2576,7 @@ fn (mut g Gen) expr(node ast.Expr) {
 | 
				
			||||||
				g.strs_to_free0 = []
 | 
									g.strs_to_free0 = []
 | 
				
			||||||
				// println('pos=$node.pos.pos')
 | 
									// println('pos=$node.pos.pos')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if g.is_shared {
 | 
								if g.is_shared && !ret_type.has_flag(.shared_f) {
 | 
				
			||||||
				g.writeln('}, sizeof($shared_styp))')
 | 
									g.writeln('}, sizeof($shared_styp))')
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// if g.autofree && node.autofree_pregen != '' { // g.strs_to_free0.len != 0 {
 | 
								// if g.autofree && node.autofree_pregen != '' { // g.strs_to_free0.len != 0 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -207,6 +207,9 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
 | 
				
			||||||
				p.warn_with_pos('use `(mut f Foo)` instead of `(f mut Foo)`', lpar_pos.extend(p.peek_tok2.position()))
 | 
									p.warn_with_pos('use `(mut f Foo)` instead of `(f mut Foo)`', lpar_pos.extend(p.peek_tok2.position()))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if p.tok.kind == .key_shared {
 | 
				
			||||||
 | 
								p.error_with_pos('use `(shared f Foo)` instead of `(f shared Foo)`', lpar_pos.extend(p.peek_tok2.position()))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		receiver_pos = rec_start_pos.extend(p.tok.position())
 | 
							receiver_pos = rec_start_pos.extend(p.tok.position())
 | 
				
			||||||
		is_amp := p.tok.kind == .amp
 | 
							is_amp := p.tok.kind == .amp
 | 
				
			||||||
		if p.tok.kind == .name && p.tok.lit == 'JS' {
 | 
							if p.tok.kind == .name && p.tok.lit == 'JS' {
 | 
				
			||||||
| 
						 | 
					@ -685,6 +688,9 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				is_mut = true
 | 
									is_mut = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if p.tok.kind == .key_shared {
 | 
				
			||||||
 | 
									p.error_with_pos('use `shared f Foo` instead of `f shared Foo`', p.tok.position())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if p.tok.kind == .ellipsis {
 | 
								if p.tok.kind == .ellipsis {
 | 
				
			||||||
				p.next()
 | 
									p.next()
 | 
				
			||||||
				is_variadic = true
 | 
									is_variadic = true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					struct St {
 | 
				
			||||||
 | 
					mut:
 | 
				
			||||||
 | 
						x f64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f() shared St {
 | 
				
			||||||
 | 
						shared x := St{ x: 3.25 }
 | 
				
			||||||
 | 
						return x
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn g(good bool) ?shared St {
 | 
				
			||||||
 | 
						if !good {
 | 
				
			||||||
 | 
							return error('no shared St created')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						shared x := St{ x: 12.75 }
 | 
				
			||||||
 | 
						return x
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_shared_fn_return() {
 | 
				
			||||||
 | 
						shared x := f()
 | 
				
			||||||
 | 
						val := rlock x { x.x }
 | 
				
			||||||
 | 
						assert val == 3.25
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn shared_opt_propagate(good bool) ?f64 {
 | 
				
			||||||
 | 
						shared x := g(good) ?
 | 
				
			||||||
 | 
						ret := rlock x { x.x }
 | 
				
			||||||
 | 
						return ret
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_shared_opt_propagate() {
 | 
				
			||||||
 | 
						x := shared_opt_propagate(true) or { 1.25 }
 | 
				
			||||||
 | 
						y := shared_opt_propagate(false) or { 2.125 }
 | 
				
			||||||
 | 
						assert x == 12.75
 | 
				
			||||||
 | 
						assert y == 2.125
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_shared_opt_good() {
 | 
				
			||||||
 | 
						shared yy := g(true) or {
 | 
				
			||||||
 | 
							shared my_default := St{ x: 37.5 }
 | 
				
			||||||
 | 
						    my_default
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						val := rlock yy { yy.x }
 | 
				
			||||||
 | 
						assert val == 12.75
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn test_shared_opt_bad() {
 | 
				
			||||||
 | 
						shared yy := g(false) or {
 | 
				
			||||||
 | 
							shared my_default := St{ x: 37.5 }
 | 
				
			||||||
 | 
						    my_default
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						val := rlock yy { yy.x }
 | 
				
			||||||
 | 
						assert val == 37.5
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -427,7 +427,7 @@ pub fn (tok Kind) is_relational() bool {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (k Kind) is_start_of_type() bool {
 | 
					pub fn (k Kind) is_start_of_type() bool {
 | 
				
			||||||
	return k in [.name, .lpar, .amp, .lsbr, .question]
 | 
						return k in [.name, .lpar, .amp, .lsbr, .question, .key_shared]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (kind Kind) is_prefix() bool {
 | 
					pub fn (kind Kind) is_prefix() bool {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue