mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
Improve parser errors for statements at global scope (#20871)
This commit is contained in:
parent
e85bc5f16e
commit
4b57724c91
9 changed files with 75 additions and 19 deletions
|
@ -1041,6 +1041,30 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
nextToken();
|
||||
continue;
|
||||
|
||||
// The following are all errors, the cases are just for better error messages than the default case
|
||||
case TOK.return_:
|
||||
case TOK.goto_:
|
||||
case TOK.break_:
|
||||
case TOK.continue_:
|
||||
error("`%s` statement must be inside function scope", token.toChars());
|
||||
goto Lerror;
|
||||
case TOK.asm_:
|
||||
case TOK.do_:
|
||||
case TOK.for_:
|
||||
case TOK.foreach_:
|
||||
case TOK.foreach_reverse_:
|
||||
case TOK.if_:
|
||||
case TOK.switch_:
|
||||
case TOK.try_:
|
||||
case TOK.while_:
|
||||
error("`%s` statement must be inside function scope", token.toChars());
|
||||
if (peekNext() == TOK.leftParenthesis || peekNext() == TOK.leftCurly)
|
||||
{
|
||||
parseStatement(0);
|
||||
s = null;
|
||||
continue;
|
||||
}
|
||||
goto Lerror;
|
||||
default:
|
||||
error("declaration expected, not `%s`", token.toChars());
|
||||
Lerror:
|
||||
|
@ -1504,28 +1528,26 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
if (token.value != TOK.identifier)
|
||||
{
|
||||
error("identifier expected following `template`");
|
||||
goto Lerr;
|
||||
return null;
|
||||
}
|
||||
id = token.ident;
|
||||
nextToken();
|
||||
tpl = parseTemplateParameterList();
|
||||
if (!tpl)
|
||||
goto Lerr;
|
||||
return null;
|
||||
|
||||
constraint = parseConstraint();
|
||||
|
||||
if (token.value != TOK.leftCurly)
|
||||
{
|
||||
error("`{` expected after template parameter list, not `%s`", token.toChars()); /* } */
|
||||
goto Lerr;
|
||||
nextToken();
|
||||
return null;
|
||||
}
|
||||
decldefs = parseBlock(null);
|
||||
|
||||
tempdecl = new AST.TemplateDeclaration(loc, id, tpl, constraint, decldefs, ismixin);
|
||||
return tempdecl;
|
||||
|
||||
Lerr:
|
||||
return null;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
|
@ -4571,6 +4593,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
default:
|
||||
error("semicolon expected to close `alias` declaration, not `%s`", token.toChars());
|
||||
nextToken();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5016,6 +5039,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
default:
|
||||
error("semicolon expected to close `alias` declaration, not `%s`", token.toChars());
|
||||
nextToken();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -5356,9 +5380,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
error("template constraint must follow parameter lists and attributes");
|
||||
else
|
||||
error("cannot use function constraints for non-template functions. Use `static if` instead");
|
||||
|
||||
parseConstraint();
|
||||
}
|
||||
else
|
||||
{
|
||||
error("semicolon expected following function declaration, not `%s`", token.toChars());
|
||||
nextToken();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
26
compiler/test/fail_compilation/code_global_scope.d
Normal file
26
compiler/test/fail_compilation/code_global_scope.d
Normal file
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/code_global_scope.d(18): Error: `switch` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(19): Error: `do` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(20): Error: `foreach` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(21): Error: `while` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(22): Error: `if` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(23): Error: `return` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(24): Error: `goto` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(25): Error: `continue` statement must be inside function scope
|
||||
fail_compilation/code_global_scope.d(26): Error: `break` statement must be inside function scope
|
||||
---
|
||||
*/
|
||||
|
||||
|
||||
|
||||
switch s;
|
||||
do d;
|
||||
foreach (i; 0 .. 4) {}
|
||||
while (x) {}
|
||||
if (y) {}
|
||||
return 0;
|
||||
goto A;
|
||||
continue B;
|
||||
break;
|
|
@ -4,7 +4,7 @@ TEST_OUTPUT:
|
|||
fail_compilation/diag_template_alias.d(1): Error: identifier expected for template `alias` parameter
|
||||
fail_compilation/diag_template_alias.d(1): Error: found `alias` when expecting `(`
|
||||
fail_compilation/diag_template_alias.d(1): Error: semicolon expected following function declaration, not `(`
|
||||
fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `(`
|
||||
fail_compilation/diag_template_alias.d(1): Error: declaration expected, not `)`
|
||||
---
|
||||
*/
|
||||
#line 1
|
||||
|
|
|
@ -4,7 +4,7 @@ TEST_OUTPUT:
|
|||
fail_compilation/diag_template_this.d(1): Error: identifier expected for template `this` parameter
|
||||
fail_compilation/diag_template_this.d(1): Error: found `this` when expecting `(`
|
||||
fail_compilation/diag_template_this.d(1): Error: semicolon expected following function declaration, not `(`
|
||||
fail_compilation/diag_template_this.d(1): Error: declaration expected, not `(`
|
||||
fail_compilation/diag_template_this.d(1): Error: declaration expected, not `)`
|
||||
---
|
||||
*/
|
||||
#line 1
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fail17570.d(12): Error: cannot use function constraints for non-template functions. Use `static if` instead
|
||||
fail_compilation/fail17570.d(12): Error: declaration expected, not `if`
|
||||
fail_compilation/fail17570.d(13): Error: declaration expected, not `{`
|
||||
fail_compilation/fail17570.d(15): Error: `}` expected following members in `struct` declaration
|
||||
fail_compilation/fail17570.d(11): struct `S` starts here
|
||||
---
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/fnconstraint.d(14): Error: template constraint must follow parameter lists and attributes
|
||||
fail_compilation/fnconstraint.d(14): Error: declaration expected, not `if`
|
||||
fail_compilation/fnconstraint.d(15): Error: declaration expected, not `{`
|
||||
fail_compilation/fnconstraint.d(23): Error: template constraint must follow parameter lists and attributes
|
||||
fail_compilation/fnconstraint.d(23): Error: declaration expected, not `if`
|
||||
fail_compilation/fnconstraint.d(23): Error: declaration expected, not `{`
|
||||
fail_compilation/fnconstraint.d(27): Error: `}` expected following members in `struct` declaration
|
||||
fail_compilation/fnconstraint.d(19): struct `S` starts here
|
||||
---
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/issue16020.d(13): Error: user-defined attributes not allowed for `alias` declarations
|
||||
fail_compilation/issue16020.d(14): Error: semicolon expected to close `alias` declaration, not `(`
|
||||
fail_compilation/issue16020.d(14): Error: declaration expected, not `(`
|
||||
fail_compilation/issue16020.d(15): Deprecation: storage class `final` has no effect in type aliases
|
||||
fail_compilation/issue16020.d(14): Error: user-defined attributes not allowed for `alias` declarations
|
||||
fail_compilation/issue16020.d(15): Error: semicolon expected to close `alias` declaration, not `(`
|
||||
fail_compilation/issue16020.d(15): Error: semicolon needed to end declaration of `t` instead of `)`
|
||||
fail_compilation/issue16020.d(15): Error: declaration expected, not `)`
|
||||
fail_compilation/issue16020.d(16): Deprecation: storage class `final` has no effect in type aliases
|
||||
---
|
||||
*/
|
||||
module issue16020;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/template_decl.d(8): Error: `{` expected after template parameter list, not `(`
|
||||
fail_compilation/template_decl.d(8): Error: declaration expected, not `(`
|
||||
fail_compilation/template_decl.d(8): Error: declaration expected, not `)`
|
||||
---
|
||||
*/
|
||||
template b(alias d)() {
|
||||
|
|
|
@ -15,19 +15,19 @@ fail_compilation/udaparams.d(45): Error: `@nogc` attribute for function paramete
|
|||
fail_compilation/udaparams.d(51): Error: cannot put a storage-class in an `alias` declaration.
|
||||
fail_compilation/udaparams.d(52): Error: cannot put a storage-class in an `alias` declaration.
|
||||
fail_compilation/udaparams.d(53): Error: semicolon expected to close `alias` declaration, not `=>`
|
||||
fail_compilation/udaparams.d(53): Error: declaration expected, not `=>`
|
||||
fail_compilation/udaparams.d(53): Error: declaration expected, not `1`
|
||||
fail_compilation/udaparams.d(54): Error: semicolon expected to close `alias` declaration, not `=>`
|
||||
fail_compilation/udaparams.d(54): Error: declaration expected, not `=>`
|
||||
fail_compilation/udaparams.d(54): Error: declaration expected, not `1`
|
||||
fail_compilation/udaparams.d(57): Error: basic type expected, not `@`
|
||||
fail_compilation/udaparams.d(57): Error: identifier expected for template value parameter
|
||||
fail_compilation/udaparams.d(57): Error: found `@` when expecting `)`
|
||||
fail_compilation/udaparams.d(57): Error: basic type expected, not `3`
|
||||
fail_compilation/udaparams.d(57): Error: found `3` when expecting `)`
|
||||
fail_compilation/udaparams.d(57): Error: semicolon expected following function declaration, not `)`
|
||||
fail_compilation/udaparams.d(57): Error: no identifier for declarator `T`
|
||||
fail_compilation/udaparams.d(57): Error: declaration expected, not `)`
|
||||
---
|
||||
*/
|
||||
|
||||
void vararg1(int a, @(10) ...);
|
||||
extern(C) void vararg2(int a, @(10) ...);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue