checker: allow noreturn in match expr (#11126)
							parent
							
								
									4ce9ad6a56
								
							
						
					
					
						commit
						ac442abc11
					
				| 
						 | 
				
			
			@ -6124,7 +6124,8 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
 | 
			
		|||
						if !c.check_types(ret_type, expr_type)
 | 
			
		||||
							&& !c.check_types(expr_type, ret_type) {
 | 
			
		||||
							ret_sym := c.table.get_type_symbol(ret_type)
 | 
			
		||||
							if !(node.is_expr && ret_sym.kind == .sum_type) {
 | 
			
		||||
							is_noreturn := is_noreturn_callexpr(stmt.expr)
 | 
			
		||||
							if !(node.is_expr && ret_sym.kind == .sum_type) && !is_noreturn {
 | 
			
		||||
								c.error('return type mismatch, it should be `$ret_sym.name`',
 | 
			
		||||
									stmt.expr.position())
 | 
			
		||||
							}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1084,6 +1084,13 @@ fn (mut g Gen) stmts(stmts []ast.Stmt) {
 | 
			
		|||
	g.stmts_with_tmp_var(stmts, '')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn is_noreturn_callexpr(expr ast.Expr) bool {
 | 
			
		||||
	if expr is ast.CallExpr {
 | 
			
		||||
		return expr.is_noreturn
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tmp_var is used in `if` expressions only
 | 
			
		||||
fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
 | 
			
		||||
	g.indent++
 | 
			
		||||
| 
						 | 
				
			
			@ -1119,7 +1126,13 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
 | 
			
		|||
			} else {
 | 
			
		||||
				g.stmt_path_pos << g.out.len
 | 
			
		||||
				g.skip_stmt_pos = true
 | 
			
		||||
				g.write('$tmp_var = ')
 | 
			
		||||
				mut is_noreturn := false
 | 
			
		||||
				if stmt is ast.ExprStmt {
 | 
			
		||||
					is_noreturn = is_noreturn_callexpr(stmt.expr)
 | 
			
		||||
				}
 | 
			
		||||
				if !is_noreturn {
 | 
			
		||||
					g.write('$tmp_var = ')
 | 
			
		||||
				}
 | 
			
		||||
				g.stmt(stmt)
 | 
			
		||||
				if !g.out.last_n(2).contains(';') {
 | 
			
		||||
					g.writeln(';')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -287,3 +287,17 @@ fn test_match_expression_add() {
 | 
			
		|||
	} + 3
 | 
			
		||||
	assert a == 4
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type LeType = int | string
 | 
			
		||||
 | 
			
		||||
fn test_noreturn() {
 | 
			
		||||
	t := LeType(3)
 | 
			
		||||
	_ := match t {
 | 
			
		||||
		int {
 | 
			
		||||
			'test'
 | 
			
		||||
		}
 | 
			
		||||
		string {
 | 
			
		||||
			exit(0)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue