Require adjacent auto ref return as well (#21061)

This commit is contained in:
Dennis 2025-03-22 22:59:00 +01:00 committed by GitHub
parent 8a96c4745c
commit 31bfe613b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 9 deletions

View file

@ -0,0 +1,12 @@
Keywords `auto` and `ref` must be adjacent for `auto ref` return.
Similar to `auto ref` parameters in 2.111, it's now deprecated to declare an `auto ref` return type without putting those two keywords next to each other as well.
---
ref auto int f() => 3;
auto { ref int g() => 3; }
// Correction:
auto ref f() => 3;
auto ref g() => 3;
---

View file

@ -235,6 +235,17 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
if ((funcdecl.storage_class & STC.TYPECTOR) && !(ad || funcdecl.isNested()))
funcdecl.storage_class &= ~STC.TYPECTOR;
auto tf = funcdecl.type.isTypeFunction();
if ((funcdecl.storage_class & STC.auto_) && tf.isRef && !funcdecl.inferRetType)
{
if (!(funcdecl.storage_class & STC.autoref))
{
// @@@DEPRECATED_2.122@@@
// Deprecated in 2.112, turn into an error in 2.122
deprecation(funcdecl.loc, "`auto ref` return type must have `auto` and `ref` adjacent");
funcdecl.storage_class |= STC.autoref;
}
}
//printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration.isFinal());
if (sc.traitsCompiles)
@ -313,7 +324,6 @@ void funcDeclarationSemantic(Scope* sc, FuncDeclaration funcdecl)
sc = sc.push();
sc.stc |= funcdecl.storage_class & (STC.disable | STC.deprecated_); // forward to function type
TypeFunction tf = funcdecl.type.toTypeFunction();
if (sc.func)
{
/* If the nesting parent is pure without inference,

View file

@ -3,13 +3,14 @@ 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`
fail_compilation/diag9679.d(24): Error: returning `r` escapes a reference to local variable `i`
fail_compilation/diag9679.d(94): Deprecation: `auto ref` return type must have `auto` and `ref` adjacent
fail_compilation/diag9679.d(100): Deprecation: `auto ref` return type must have `auto` and `ref` adjacent
fail_compilation/diag9679.d(16): Error: rvalue `1` cannot be assigned to `ref n`
fail_compilation/diag9679.d(17): Error: variable `diag9679.main.n` - storage class `auto` has no effect if type is not inferred, did you mean `scope`?
fail_compilation/diag9679.d(18): Error: variable `diag9679.main.S.a` - field declarations cannot be `ref`
fail_compilation/diag9679.d(25): Error: returning `r` escapes a reference to local variable `i`
---
*/
void main()
{
if (ref n = 1) {}
@ -60,7 +61,6 @@ fail_compilation/diag9679.d(96): Error: variable `x` - `auto ref` variable must
---
*/
void test5()
{
ref int r5;
@ -90,8 +90,11 @@ void test9()
auto ref int y = void;
}
void testKeywordOrder()(ref auto int x, auto const ref float y) {}
void testKeywordOrder()
void testKeywordOrder()(ref auto int x, auto const ref float y) {};
ref auto int testKeywordOrder()
{
ref auto int x = 3;
return 3;
}
auto { ref int autoFromScope() => 3; }