mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
Require adjacent auto ref
keywords
This commit is contained in:
parent
dfcee8d88b
commit
ae2dc11619
5 changed files with 49 additions and 9 deletions
18
changelog/dmd.auto-ref-adjacent.dd
Normal file
18
changelog/dmd.auto-ref-adjacent.dd
Normal file
|
@ -0,0 +1,18 @@
|
|||
`auto ref` variables must have adjacent keywords `auto` and `ref`
|
||||
|
||||
It's now deprecated to declare `auto ref` parameters without putting those two keywords next to eachother.
|
||||
This way it's clear that `auto ref` semantics are intended, rather than `ref` and `auto` semantics separately.
|
||||
For the newly introduced `ref` local / global variables, it's an error immediately.
|
||||
|
||||
---
|
||||
void t()(ref const auto int x) // Deprecation
|
||||
{
|
||||
ref auto y = x; // Error
|
||||
}
|
||||
|
||||
// Correction:
|
||||
void t()(auto ref const int x)
|
||||
{
|
||||
auto ref y = x;
|
||||
}
|
||||
---
|
|
@ -616,7 +616,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
|
|||
dsym.storage_class |= ad.storage_class & STC.TYPECTOR;
|
||||
|
||||
if ((dsym.storage_class & STC.auto_) && (dsym.storage_class & STC.ref_))
|
||||
dsym.storage_class |= STC.autoref;
|
||||
{
|
||||
if (!(dsym.storage_class & STC.autoref))
|
||||
{
|
||||
.error(dsym.loc, "%s `%s` - `auto ref` variable must have `auto` and `ref` adjacent", dsym.kind, dsym.toChars());
|
||||
dsym.storage_class |= STC.autoref;
|
||||
}
|
||||
}
|
||||
|
||||
/* If auto type inference, do the inference
|
||||
*/
|
||||
|
|
|
@ -651,6 +651,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
case TOK.auto_:
|
||||
stc = STC.auto_;
|
||||
if (peekNext() == TOK.ref_)
|
||||
stc |= STC.autoref;
|
||||
goto Lstc;
|
||||
|
||||
case TOK.scope_:
|
||||
|
@ -2935,6 +2937,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
case TOK.auto_:
|
||||
stc = STC.auto_;
|
||||
if (peekNext() == TOK.ref_)
|
||||
stc |= STC.autoref;
|
||||
goto L2;
|
||||
|
||||
case TOK.return_:
|
||||
|
@ -2952,8 +2956,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
// if stcx is not a power of 2
|
||||
if (stcx & (stcx - 1) && !(stcx == (STC.in_ | STC.ref_)))
|
||||
error("incompatible parameter storage classes");
|
||||
//if ((storageClass & STC.scope_) && (storageClass & (STC.ref_ | STC.out_)))
|
||||
//error("scope cannot be ref or out");
|
||||
|
||||
// Deprecated in 2.111
|
||||
if ((storageClass & STC.auto_) && (storageClass & STC.ref_) && !(storageClass & STC.autoref))
|
||||
deprecation("`auto` and `ref` storage classes should be adjacent");
|
||||
|
||||
const tv = peekNext();
|
||||
Loc loc;
|
||||
|
@ -4259,6 +4265,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
case TOK.auto_:
|
||||
stc = STC.auto_;
|
||||
if (peekNext() == TOK.ref_)
|
||||
stc |= STC.autoref;
|
||||
goto L1;
|
||||
|
||||
case TOK.scope_:
|
||||
|
@ -5079,7 +5087,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
{
|
||||
// function auto ref (parameters) { statements... }
|
||||
// delegate auto ref (parameters) { statements... }
|
||||
stc = STC.auto_ | STC.ref_;
|
||||
stc = STC.auto_ | STC.ref_ | STC.autoref;
|
||||
nextToken();
|
||||
}
|
||||
else
|
||||
|
@ -5121,7 +5129,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
{
|
||||
// auto ref (parameters) => expression
|
||||
// auto ref (parameters) { statements... }
|
||||
stc = STC.auto_ | STC.ref_;
|
||||
stc = STC.auto_ | STC.ref_ | STC.autoref;
|
||||
nextToken();
|
||||
}
|
||||
else
|
||||
|
@ -5678,6 +5686,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
|
|||
|
||||
case TOK.auto_:
|
||||
stc = STC.auto_;
|
||||
if (peekNext() == TOK.ref_)
|
||||
stc |= STC.autoref;
|
||||
break;
|
||||
|
||||
case TOK.const_:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* REQUIRED_ARGS: -verrors=0
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
fail_compilation/diag9679.d(93): Deprecation: `auto` and `ref` storage classes should be adjacent
|
||||
fail_compilation/diag9679.d(93): Deprecation: `auto` and `ref` storage classes should be adjacent
|
||||
fail_compilation/diag9679.d(15): Error: rvalue `1` cannot be assigned to `ref n`
|
||||
fail_compilation/diag9679.d(16): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
|
||||
fail_compilation/diag9679.d(17): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
|
||||
|
@ -8,8 +10,6 @@ fail_compilation/diag9679.d(24): Error: returning `r` escapes a reference to loc
|
|||
---
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
if (ref n = 1) {}
|
||||
|
@ -56,11 +56,11 @@ fail_compilation/diag9679.d(77): Error: type `immutable(int)` cannot be assigned
|
|||
fail_compilation/diag9679.d(84): Error: returning `x` escapes a reference to local variable `x`
|
||||
fail_compilation/diag9679.d(89): Error: variable `diag9679.test9.x` - void initializer not allowed for `ref` variable
|
||||
fail_compilation/diag9679.d(90): Error: variable `diag9679.test9.y` - void initializer not allowed for `ref` variable
|
||||
fail_compilation/diag9679.d(96): Error: variable `x` - `auto ref` variable must have `auto` and `ref` adjacent
|
||||
---
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void test5()
|
||||
{
|
||||
ref int r5;
|
||||
|
@ -89,3 +89,9 @@ void test9()
|
|||
ref int x = void;
|
||||
auto ref int y = void;
|
||||
}
|
||||
|
||||
void testKeywordOrder()(ref auto int x, auto const ref float y) {}
|
||||
void testKeywordOrder()
|
||||
{
|
||||
ref auto int x = 3;
|
||||
}
|
||||
|
|
|
@ -1699,7 +1699,7 @@ template forward(args...)
|
|||
{
|
||||
x_ = forward!x;
|
||||
}
|
||||
this()(auto const ref X x)
|
||||
this()(auto ref const X x)
|
||||
{
|
||||
x_ = forward!x;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue