parser: fix panic when single letter receiver parsed (#8381)
							parent
							
								
									5fc7eadd8b
								
							
						
					
					
						commit
						93b0d8ca64
					
				|  | @ -5296,7 +5296,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { | |||
| 			sym := c.table.get_type_symbol(arg.typ) | ||||
| 			if sym.kind == .placeholder | ||||
| 				|| (sym.kind in [table.Kind.int_literal, .float_literal] && !c.is_builtin_mod) { | ||||
| 				c.error('unknown type `$sym.name`', node.pos) | ||||
| 				c.error('unknown type `$sym.name`', node.receiver_pos) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -0,0 +1,3 @@ | |||
| vlib/v/checker/tests/receiver_unknown_type_single_letter.vv:1:5: error: unknown type `A` | ||||
|     1 | fn (p A) foo() {} | ||||
|       |     ~~~ | ||||
|  | @ -0,0 +1 @@ | |||
| fn (p A) foo() {} | ||||
|  | @ -190,6 +190,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { | |||
| 	mut rec_mut := false | ||||
| 	mut params := []table.Param{} | ||||
| 	if p.tok.kind == .lpar { | ||||
| 		p.is_parsing_receiver = true | ||||
| 		lpar_pos := p.tok.position() | ||||
| 		p.next() // (
 | ||||
| 		is_method = true | ||||
|  | @ -246,6 +247,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { | |||
| 			typ: rec_type | ||||
| 		} | ||||
| 		p.check(.rpar) | ||||
| 		p.is_parsing_receiver = false | ||||
| 	} | ||||
| 	mut name := '' | ||||
| 	if p.tok.kind == .name { | ||||
|  |  | |||
|  | @ -373,7 +373,7 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool, check | |||
| 					return table.int_literal_type | ||||
| 				} | ||||
| 				else { | ||||
| 					if name.len == 1 && name[0].is_capital() { | ||||
| 					if name.len == 1 && name[0].is_capital() && !p.is_parsing_receiver { | ||||
| 						return p.parse_generic_template_type(name) | ||||
| 					} | ||||
| 					if p.peek_tok.kind == .lt { | ||||
|  |  | |||
|  | @ -29,48 +29,49 @@ mut: | |||
| 	scanner           &scanner.Scanner | ||||
| 	comments_mode     scanner.CommentsMode = .skip_comments | ||||
| 	// see comment in parse_file
 | ||||
| 	tok               token.Token | ||||
| 	prev_tok          token.Token | ||||
| 	peek_tok          token.Token | ||||
| 	peek_tok2         token.Token | ||||
| 	peek_tok3         token.Token | ||||
| 	table             &table.Table | ||||
| 	language          table.Language | ||||
| 	inside_if         bool | ||||
| 	inside_if_expr    bool | ||||
| 	inside_ct_if_expr bool | ||||
| 	inside_or_expr    bool | ||||
| 	inside_for        bool | ||||
| 	inside_fn         bool // true even with implicit main
 | ||||
| 	inside_str_interp bool | ||||
| 	or_is_handled     bool         // ignore `or` in this expression
 | ||||
| 	builtin_mod       bool         // are we in the `builtin` module?
 | ||||
| 	mod               string       // current module name
 | ||||
| 	is_manualfree     bool         // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree
 | ||||
| 	attrs             []table.Attr // attributes before next decl stmt
 | ||||
| 	expr_mod          string       // for constructing full type names in parse_type()
 | ||||
| 	scope             &ast.Scope | ||||
| 	global_scope      &ast.Scope | ||||
| 	imports           map[string]string // alias => mod_name
 | ||||
| 	ast_imports       []ast.Import      // mod_names
 | ||||
| 	used_imports      []string // alias
 | ||||
| 	auto_imports      []string // imports, the user does not need to specify
 | ||||
| 	imported_symbols  map[string]string | ||||
| 	is_amp            bool // for generating the right code for `&Foo{}`
 | ||||
| 	returns           bool | ||||
| 	inside_match      bool // to separate `match A { }` from `Struct{}`
 | ||||
| 	inside_select     bool // to allow `ch <- Struct{} {` inside `select`
 | ||||
| 	inside_match_case bool // to separate `match_expr { }` from `Struct{}`
 | ||||
| 	inside_match_body bool // to fix eval not used TODO
 | ||||
| 	inside_unsafe     bool | ||||
| 	is_stmt_ident     bool // true while the beginning of a statement is an ident/selector
 | ||||
| 	expecting_type    bool // `is Type`, expecting type
 | ||||
| 	errors            []errors.Error | ||||
| 	warnings          []errors.Warning | ||||
| 	vet_errors        []vet.Error | ||||
| 	cur_fn_name       string | ||||
| 	in_generic_params bool // indicates if parsing between `<` and `>` of a method/function
 | ||||
| 	name_error        bool // indicates if the token is not a name or the name is on another line
 | ||||
| 	tok                 token.Token | ||||
| 	prev_tok            token.Token | ||||
| 	peek_tok            token.Token | ||||
| 	peek_tok2           token.Token | ||||
| 	peek_tok3           token.Token | ||||
| 	table               &table.Table | ||||
| 	language            table.Language | ||||
| 	inside_if           bool | ||||
| 	inside_if_expr      bool | ||||
| 	inside_ct_if_expr   bool | ||||
| 	inside_or_expr      bool | ||||
| 	inside_for          bool | ||||
| 	inside_fn           bool // true even with implicit main
 | ||||
| 	inside_str_interp   bool | ||||
| 	or_is_handled       bool         // ignore `or` in this expression
 | ||||
| 	builtin_mod         bool         // are we in the `builtin` module?
 | ||||
| 	mod                 string       // current module name
 | ||||
| 	is_manualfree       bool         // true when `[manualfree] module abc`, makes *all* fns in the current .v file, opt out of autofree
 | ||||
| 	attrs               []table.Attr // attributes before next decl stmt
 | ||||
| 	expr_mod            string       // for constructing full type names in parse_type()
 | ||||
| 	scope               &ast.Scope | ||||
| 	global_scope        &ast.Scope | ||||
| 	imports             map[string]string // alias => mod_name
 | ||||
| 	ast_imports         []ast.Import      // mod_names
 | ||||
| 	used_imports        []string // alias
 | ||||
| 	auto_imports        []string // imports, the user does not need to specify
 | ||||
| 	imported_symbols    map[string]string | ||||
| 	is_amp              bool // for generating the right code for `&Foo{}`
 | ||||
| 	returns             bool | ||||
| 	inside_match        bool // to separate `match A { }` from `Struct{}`
 | ||||
| 	inside_select       bool // to allow `ch <- Struct{} {` inside `select`
 | ||||
| 	inside_match_case   bool // to separate `match_expr { }` from `Struct{}`
 | ||||
| 	inside_match_body   bool // to fix eval not used TODO
 | ||||
| 	inside_unsafe       bool | ||||
| 	is_stmt_ident       bool // true while the beginning of a statement is an ident/selector
 | ||||
| 	expecting_type      bool // `is Type`, expecting type
 | ||||
| 	errors              []errors.Error | ||||
| 	warnings            []errors.Warning | ||||
| 	vet_errors          []vet.Error | ||||
| 	cur_fn_name         string | ||||
| 	in_generic_params   bool // indicates if parsing between `<` and `>` of a method/function
 | ||||
| 	name_error          bool // indicates if the token is not a name or the name is on another line
 | ||||
| 	is_parsing_receiver bool // indicates if parser is parsing receiver fn (x Xxx)
 | ||||
| } | ||||
| 
 | ||||
| // for tests
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue