parser: implement parsing of `select` block (#6379)
							parent
							
								
									3a795e6d9b
								
							
						
					
					
						commit
						1bc9063573
					
				| 
						 | 
					@ -12,7 +12,7 @@ pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl
 | 
				
			||||||
pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | CastExpr |
 | 
					pub type Expr = AnonFn | ArrayInit | AsCast | Assoc | BoolLiteral | CallExpr | CastExpr |
 | 
				
			||||||
	ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral |
 | 
						ChanInit | CharLiteral | Comment | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral |
 | 
				
			||||||
	Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
 | 
						Ident | IfExpr | IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | LockExpr |
 | 
				
			||||||
	MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr |
 | 
						MapInit | MatchExpr | None | OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectExpr |
 | 
				
			||||||
	SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type |
 | 
						SelectorExpr | SizeOf | SqlExpr | StringInterLiteral | StringLiteral | StructInit | Type |
 | 
				
			||||||
	TypeOf | UnsafeExpr
 | 
						TypeOf | UnsafeExpr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -536,6 +536,27 @@ pub:
 | 
				
			||||||
	post_comments []Comment
 | 
						post_comments []Comment
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct SelectExpr {
 | 
				
			||||||
 | 
					pub:
 | 
				
			||||||
 | 
						branches      []SelectBranch
 | 
				
			||||||
 | 
						pos           token.Position
 | 
				
			||||||
 | 
					pub mut:
 | 
				
			||||||
 | 
						is_expr       bool // returns a value
 | 
				
			||||||
 | 
						return_type   table.Type
 | 
				
			||||||
 | 
						expected_type table.Type // for debugging only
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct SelectBranch {
 | 
				
			||||||
 | 
					pub:
 | 
				
			||||||
 | 
						stmt          Stmt // `a := <-ch` or `ch <- a`
 | 
				
			||||||
 | 
						stmts         []Stmt // right side
 | 
				
			||||||
 | 
						pos           token.Position
 | 
				
			||||||
 | 
						comment       Comment // comment above `select {`
 | 
				
			||||||
 | 
						is_else       bool
 | 
				
			||||||
 | 
						is_timeout    bool
 | 
				
			||||||
 | 
						post_comments []Comment
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
CompIf.is_opt:
 | 
					CompIf.is_opt:
 | 
				
			||||||
`$if xyz? {}` => this compile time `if` is optional,
 | 
					`$if xyz? {}` => this compile time `if` is optional,
 | 
				
			||||||
| 
						 | 
					@ -1062,6 +1083,9 @@ pub fn (expr Expr) position() token.Position {
 | 
				
			||||||
			return expr.pos
 | 
								return expr.pos
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// ast.ParExpr { }
 | 
							// ast.ParExpr { }
 | 
				
			||||||
 | 
							SelectExpr {
 | 
				
			||||||
 | 
								return expr.pos
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		SelectorExpr {
 | 
							SelectorExpr {
 | 
				
			||||||
			return expr.pos
 | 
								return expr.pos
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2641,6 +2641,10 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
 | 
				
			||||||
			// never happens
 | 
								// never happens
 | 
				
			||||||
			return table.void_type
 | 
								return table.void_type
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ast.SelectExpr {
 | 
				
			||||||
 | 
								// TODO: to be implemented
 | 
				
			||||||
 | 
								return table.void_type
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ast.SelectorExpr {
 | 
							ast.SelectorExpr {
 | 
				
			||||||
			return c.selector_expr(mut node)
 | 
								return c.selector_expr(mut node)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -953,6 +953,9 @@ pub fn (mut f Fmt) expr(node ast.Expr) {
 | 
				
			||||||
			f.write('..')
 | 
								f.write('..')
 | 
				
			||||||
			f.expr(node.high)
 | 
								f.expr(node.high)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ast.SelectExpr {
 | 
				
			||||||
 | 
								// TODO: implement this
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ast.SelectorExpr {
 | 
							ast.SelectorExpr {
 | 
				
			||||||
			f.expr(node.expr)
 | 
								f.expr(node.expr)
 | 
				
			||||||
			f.write('.')
 | 
								f.write('.')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2137,6 +2137,9 @@ fn (mut g Gen) expr(node ast.Expr) {
 | 
				
			||||||
		ast.RangeExpr {
 | 
							ast.RangeExpr {
 | 
				
			||||||
			// Only used in IndexExpr
 | 
								// Only used in IndexExpr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ast.SelectExpr {
 | 
				
			||||||
 | 
								// TODO: to be implemented
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ast.SizeOf {
 | 
							ast.SizeOf {
 | 
				
			||||||
			if node.is_type {
 | 
								if node.is_type {
 | 
				
			||||||
				node_typ := g.unwrap_generic(node.typ)
 | 
									node_typ := g.unwrap_generic(node.typ)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -619,6 +619,9 @@ fn (mut g JsGen) expr(node ast.Expr) {
 | 
				
			||||||
		ast.RangeExpr {
 | 
							ast.RangeExpr {
 | 
				
			||||||
			// Only used in IndexExpr, requires index type info
 | 
								// Only used in IndexExpr, requires index type info
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ast.SelectExpr {
 | 
				
			||||||
 | 
								// TODO: to be implemented
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		ast.SelectorExpr {
 | 
							ast.SelectorExpr {
 | 
				
			||||||
			g.gen_selector_expr(node)
 | 
								g.gen_selector_expr(node)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -288,3 +288,139 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
 | 
				
			||||||
		var_name: var_name
 | 
							var_name: var_name
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn (mut p Parser) select_expr() ast.SelectExpr {
 | 
				
			||||||
 | 
						match_first_pos := p.tok.position()
 | 
				
			||||||
 | 
						p.check(.key_select)
 | 
				
			||||||
 | 
						no_lcbr := p.tok.kind != .lcbr
 | 
				
			||||||
 | 
						if !no_lcbr {
 | 
				
			||||||
 | 
							p.check(.lcbr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mut branches := []ast.SelectBranch{}
 | 
				
			||||||
 | 
						mut has_else := false
 | 
				
			||||||
 | 
						mut has_timeout := false
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							branch_first_pos := p.tok.position()
 | 
				
			||||||
 | 
							comment := p.check_comment() // comment before {}
 | 
				
			||||||
 | 
							p.open_scope()
 | 
				
			||||||
 | 
							// final else
 | 
				
			||||||
 | 
							mut is_else := false
 | 
				
			||||||
 | 
							mut is_timeout := false
 | 
				
			||||||
 | 
							mut stmt := ast.Stmt{}
 | 
				
			||||||
 | 
							if p.tok.kind == .key_else {
 | 
				
			||||||
 | 
								if has_timeout {
 | 
				
			||||||
 | 
									p.error_with_pos('timeout `> t` and `else` are mutually exclusive `select` keys', p.tok.position())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if has_else {
 | 
				
			||||||
 | 
									p.error_with_pos('at most one `else` branch allowed in `select` block', p.tok.position())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								is_else = true
 | 
				
			||||||
 | 
								has_else = true
 | 
				
			||||||
 | 
								p.next()
 | 
				
			||||||
 | 
							} else if p.tok.kind == .gt {
 | 
				
			||||||
 | 
								if has_else {
 | 
				
			||||||
 | 
									p.error_with_pos('`else` and timeout `> t` are mutually exclusive `select` keys', p.tok.position())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if has_timeout {
 | 
				
			||||||
 | 
									p.error_with_pos('at most one timeout `> t` branch allowed in `select` block', p.tok.position())
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								is_timeout = true
 | 
				
			||||||
 | 
								has_timeout = true
 | 
				
			||||||
 | 
								p.next()
 | 
				
			||||||
 | 
								p.inside_match = true
 | 
				
			||||||
 | 
								expr := p.expr(0)
 | 
				
			||||||
 | 
								p.inside_match = false
 | 
				
			||||||
 | 
								stmt = ast.ExprStmt{
 | 
				
			||||||
 | 
									expr: expr
 | 
				
			||||||
 | 
									pos: expr.position()
 | 
				
			||||||
 | 
									comments: [comment]
 | 
				
			||||||
 | 
									is_expr: true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								p.inside_match = true
 | 
				
			||||||
 | 
								exprs, comments := p.expr_list()
 | 
				
			||||||
 | 
								if exprs.len != 1 {
 | 
				
			||||||
 | 
									p.error('only one expression allowed as `select` key')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if p.tok.kind in [.assign, .decl_assign] {
 | 
				
			||||||
 | 
									stmt = p.partial_assign_stmt(exprs, comments)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									stmt = ast.ExprStmt{
 | 
				
			||||||
 | 
										expr: exprs[0]
 | 
				
			||||||
 | 
										pos: exprs[0].position()
 | 
				
			||||||
 | 
										comments: [comment]
 | 
				
			||||||
 | 
										is_expr: true
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								p.inside_match = false
 | 
				
			||||||
 | 
								match stmt {
 | 
				
			||||||
 | 
									ast.ExprStmt {
 | 
				
			||||||
 | 
										if !stmt.is_expr {
 | 
				
			||||||
 | 
											p.error_with_pos('select: invalid expression', stmt.pos)
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											match stmt.expr as expr {
 | 
				
			||||||
 | 
												ast.InfixExpr {
 | 
				
			||||||
 | 
													if expr.op != .arrow {
 | 
				
			||||||
 | 
														p.error_with_pos('select key: `<-` operator expected', expr.pos)
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
												else {
 | 
				
			||||||
 | 
													p.error_with_pos('select key: send expression (`ch <- x`) expected', stmt.pos)
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									ast.AssignStmt {
 | 
				
			||||||
 | 
										match stmt.right[0] as expr {
 | 
				
			||||||
 | 
											ast.PrefixExpr {
 | 
				
			||||||
 | 
												if expr.op != .arrow {
 | 
				
			||||||
 | 
													p.error_with_pos('select key: `<-` operator expected', expr.pos)
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											} else {
 | 
				
			||||||
 | 
												p.error_with_pos('select key: receive expression expected', stmt.right[0].position())
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									else {
 | 
				
			||||||
 | 
										p.error_with_pos('select: transmission statement expected', stmt.position())
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							branch_last_pos := p.tok.position()
 | 
				
			||||||
 | 
							p.inside_match_body = true
 | 
				
			||||||
 | 
							stmts := p.parse_block_no_scope(false)
 | 
				
			||||||
 | 
							p.close_scope()
 | 
				
			||||||
 | 
							p.inside_match_body = false
 | 
				
			||||||
 | 
							pos := token.Position{
 | 
				
			||||||
 | 
								line_nr: branch_first_pos.line_nr
 | 
				
			||||||
 | 
								pos: branch_first_pos.pos
 | 
				
			||||||
 | 
								len: branch_last_pos.pos - branch_first_pos.pos + branch_last_pos.len
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							post_comments := p.eat_comments()
 | 
				
			||||||
 | 
							branches << ast.SelectBranch{
 | 
				
			||||||
 | 
								stmt: stmt
 | 
				
			||||||
 | 
								stmts: stmts
 | 
				
			||||||
 | 
								pos: pos
 | 
				
			||||||
 | 
								comment: comment
 | 
				
			||||||
 | 
								is_else: is_else
 | 
				
			||||||
 | 
								is_timeout: is_timeout
 | 
				
			||||||
 | 
								post_comments: post_comments
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if p.tok.kind == .rcbr || ((is_else || is_timeout) && no_lcbr) {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						match_last_pos := p.tok.position()
 | 
				
			||||||
 | 
						pos := token.Position{
 | 
				
			||||||
 | 
							line_nr: match_first_pos.line_nr
 | 
				
			||||||
 | 
							pos: match_first_pos.pos
 | 
				
			||||||
 | 
							len: match_last_pos.pos - match_first_pos.pos + match_last_pos.len
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if p.tok.kind == .rcbr {
 | 
				
			||||||
 | 
							p.check(.rcbr)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ast.SelectExpr{
 | 
				
			||||||
 | 
							branches: branches
 | 
				
			||||||
 | 
							pos: pos
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -859,8 +859,9 @@ fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if p.tok.kind in [.assign, .decl_assign] || p.tok.kind.is_assign() {
 | 
						if p.tok.kind in [.assign, .decl_assign] || p.tok.kind.is_assign() {
 | 
				
			||||||
		return p.partial_assign_stmt(left, left_comments)
 | 
							return p.partial_assign_stmt(left, left_comments)
 | 
				
			||||||
	} else if is_top_level && tok.kind !in [.key_if, .key_match, .key_lock, .key_rlock] &&
 | 
						} else if is_top_level && tok.kind !in
 | 
				
			||||||
		left0 !is ast.CallExpr && left0 !is ast.PostfixExpr && !(left0 is ast.InfixExpr &&
 | 
							[.key_if, .key_match, .key_lock, .key_rlock, .key_select] && left0 !is ast.CallExpr &&
 | 
				
			||||||
 | 
							left0 !is ast.PostfixExpr && !(left0 is ast.InfixExpr &&
 | 
				
			||||||
		(left0 as ast.InfixExpr).op in [.left_shift, .arrow]) && left0 !is ast.ComptimeCall {
 | 
							(left0 as ast.InfixExpr).op in [.left_shift, .arrow]) && left0 !is ast.ComptimeCall {
 | 
				
			||||||
		p.error_with_pos('expression evaluated but not used', left0.position())
 | 
							p.error_with_pos('expression evaluated but not used', left0.position())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,9 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr {
 | 
				
			||||||
		.key_match {
 | 
							.key_match {
 | 
				
			||||||
			node = p.match_expr()
 | 
								node = p.match_expr()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							.key_select {
 | 
				
			||||||
 | 
								node = p.select_expr()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		.number {
 | 
							.number {
 | 
				
			||||||
			node = p.parse_number_literal()
 | 
								node = p.parse_number_literal()
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					vlib/v/parser/tests/select_bad_key_1.vv:39:8: error: select key: receive expression expected
 | 
				
			||||||
 | 
					   37 | fn f3_bad(ch1 chan St) {
 | 
				
			||||||
 | 
					   38 |     select {
 | 
				
			||||||
 | 
					   39 |         b := 17 {
 | 
				
			||||||
 | 
					      |              ~~
 | 
				
			||||||
 | 
					   40 |             println(b)
 | 
				
			||||||
 | 
					   41 |         }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct St {
 | 
				
			||||||
 | 
						a int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f1_good(ch1 chan St, ch2 chan int, ch3 chan int) {
 | 
				
			||||||
 | 
						mut a := 5
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							a = <- ch3 {
 | 
				
			||||||
 | 
								println(a)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							b := <- ch1 {
 | 
				
			||||||
 | 
								println(b.a)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ch1 <- a {
 | 
				
			||||||
 | 
								a++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							> 50 * time.millisecond {
 | 
				
			||||||
 | 
								println('timeout')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						println('done')
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f2_good(ch1 chan St) {
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							b := <- ch1 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								println('no channel ready')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f3_bad(ch1 chan St) {
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							b := 17 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					vlib/v/parser/tests/select_bad_key_2.vv:7:5: error: select key: `<-` operator expected
 | 
				
			||||||
 | 
					    5 |             println(b)
 | 
				
			||||||
 | 
					    6 |         }
 | 
				
			||||||
 | 
					    7 |         a + 7 {
 | 
				
			||||||
 | 
					      |           ^
 | 
				
			||||||
 | 
					    8 |             println("shouldn't get here")
 | 
				
			||||||
 | 
					    9 |         }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					fn f3_bad(ch1 chan int) {
 | 
				
			||||||
 | 
						a := 5
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							b := <-ch1 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							a + 7 {
 | 
				
			||||||
 | 
								println("shouldn't get here")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					vlib/v/parser/tests/select_bad_key_3.vv:7:3: error: select key: send expression (`ch <- x`) expected
 | 
				
			||||||
 | 
					    5 |             println(b)
 | 
				
			||||||
 | 
					    6 |         }
 | 
				
			||||||
 | 
					    7 |         println(7) {
 | 
				
			||||||
 | 
					      |         ~~~~~~~~~~
 | 
				
			||||||
 | 
					    8 |             println("shouldn't get here")
 | 
				
			||||||
 | 
					    9 |         }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					fn f3_bad(ch1 chan int) {
 | 
				
			||||||
 | 
						a := 5
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							b := <-ch1 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							println(7) {
 | 
				
			||||||
 | 
								println("shouldn't get here")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					vlib/v/parser/tests/select_bad_key_4.vv:7:8: error: select key: `<-` operator expected
 | 
				
			||||||
 | 
					    5 |             println(b)
 | 
				
			||||||
 | 
					    6 |         }
 | 
				
			||||||
 | 
					    7 |         c := -a {
 | 
				
			||||||
 | 
					      |              ^
 | 
				
			||||||
 | 
					    8 |             println("shouldn't get here")
 | 
				
			||||||
 | 
					    9 |         }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					fn f3_bad(ch1 chan int) {
 | 
				
			||||||
 | 
						mut a := 5
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							a = <-ch1 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							c := -a {
 | 
				
			||||||
 | 
								println("shouldn't get here")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					vlib/v/parser/tests/select_else_1.vv:12:3: error: `else` and timeout `> t` are mutually exclusive `select` keys
 | 
				
			||||||
 | 
					   10 |             println("shouldn't get here")
 | 
				
			||||||
 | 
					   11 |         }
 | 
				
			||||||
 | 
					   12 |         > 30 * time.millisecond {
 | 
				
			||||||
 | 
					      |         ^
 | 
				
			||||||
 | 
					   13 |             println('bad')
 | 
				
			||||||
 | 
					   14 |         }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f3_bad(ch1 chan int) {
 | 
				
			||||||
 | 
						a := 5
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							b := <-ch1 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								println("shouldn't get here")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							> 30 * time.millisecond {
 | 
				
			||||||
 | 
								println('bad')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					vlib/v/parser/tests/select_else_2.vv:12:3: error: timeout `> t` and `else` are mutually exclusive `select` keys
 | 
				
			||||||
 | 
					   10 |             println('bad')
 | 
				
			||||||
 | 
					   11 |         }
 | 
				
			||||||
 | 
					   12 |         else {
 | 
				
			||||||
 | 
					      |         ~~~~
 | 
				
			||||||
 | 
					   13 |             println("shouldn't get here")
 | 
				
			||||||
 | 
					   14 |         }
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f3_bad(ch1 chan int) {
 | 
				
			||||||
 | 
						a := 5
 | 
				
			||||||
 | 
						select {
 | 
				
			||||||
 | 
							b := <-ch1 {
 | 
				
			||||||
 | 
								println(b)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							> 30 * time.millisecond {
 | 
				
			||||||
 | 
								println('bad')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								println("shouldn't get here")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue