Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Issue 6905 - ref acts as auto ref when return type is missing #1401

Merged
merged 1 commit into from

3 participants

@9rnsr 9rnsr referenced this pull request in D-Programming-Language/phobos
Merged

Additional fix for issue 6905 #1028

@AndrejMitrovic
Collaborator

I think I'm going to write a pull request to update the documentation, because this isn't described anywhere:

ref bar1() { static int n; return n; }

IOW, ref can act as type inference just like auto can, except ref forces lvalue returns, auto forces rvalue returns, and auto ref is automatic.

However I'm not sure if this is deliberately designed this way or just another case of attributes acting as if they're auto. For example Issue 3573 (and there are other duplicate reports like this where a keyword acts as auto).

@9rnsr
Collaborator

From a long time ago, I have thought it is a feature. All function attributes with no explicit return type introduces return type inference. Certainly, in the early on the D2, Walter might had not intended about that. But I could not find any problems there in thinking of my three years. So, I can say there is no problem.

@AndrejMitrovic
Collaborator

From a long time ago, I have thought it is a feature. All function attributes with no explicit return type introduces return type inference.

I think it only makes sense for ref. If you use const:

const foo() { ... }

If foo is a method, does const apply to the method or the return type? And is foo a void method or a method that returns?

nothrow and pure are also attributes which are confusing because you can't tell if the function returns or not. I think we need to talk with @WalterBright and @andralex and decide exactly which attributes can be used for type inference. I think auto, auto ref, and ref should be the only ones.

Edit: I think const ref and maybe const auto also work, but I'm unsure. But I think they should be allowed if they work. We have so many of these..

@9rnsr
Collaborator

If foo is a method, does const apply to the method or the return type? And is foo a void method or a method that returns?

const apply to the method. I know there is a kind of confusing, but it is a different issue.

nothrow and pure are also attributes which are confusing because you can't tell if the function returns or not.

All return type inference implies "you can't tell if the function returns or not". It is the purpose.

Or, you are talking about ref + void return? If so, I can agree it is bit weird.

@9rnsr 9rnsr closed this
@9rnsr 9rnsr reopened this
@WalterBright WalterBright merged commit f193abd into from
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 32 additions and 3 deletions.
  1. +3 −3 src/statement.c
  2. +29 −0 test/runnable/declaration.d
View
6 src/statement.c
@@ -3919,7 +3919,7 @@ Statement *ReturnStatement::semantic(Scope *sc)
}
else
{
- if (tf->isref)
+ if (tf->isref && (fd->storage_class & STCauto))
{ /* Determine "refness" of function return:
* if it's an lvalue, return by ref, else return by value
*/
@@ -3932,11 +3932,11 @@ Statement *ReturnStatement::semantic(Scope *sc)
unsigned errors = global.startGagging();
exp->checkEscapeRef();
if (global.endGagging(errors))
- { tf->isref = FALSE; // return by value
- }
+ tf->isref = FALSE; // return by value
}
else
tf->isref = FALSE; // return by value
+ fd->storage_class &= ~STCauto;
}
tf->next = exp->type;
//fd->type = tf->semantic(loc, sc); // Removed with 6902
View
29 test/runnable/declaration.d
@@ -21,6 +21,34 @@ void test6475()
}
/***************************************************/
+// 6905
+
+void test6905()
+{
+ auto foo1() { static int n; return n; }
+ auto foo2() { int n; return n; }
+ auto foo3() { return 1; }
+ static assert(typeof(&foo1).stringof == "int delegate()");
+ static assert(typeof(&foo2).stringof == "int delegate()");
+ static assert(typeof(&foo3).stringof == "int delegate()");
+
+ ref bar1() { static int n; return n; }
+ static assert(!__traits(compiles, {
+ ref bar2() { int n; return n; }
+ }));
+ static assert(!__traits(compiles, {
+ ref bar3() { return 1; }
+ }));
+
+ auto ref baz1() { static int n; return n; }
+ auto ref baz2() { int n; return n; }
+ auto ref baz3() { return 1; }
+ static assert(typeof(&baz1).stringof == "int delegate() ref");
+ static assert(typeof(&baz2).stringof == "int delegate()");
+ static assert(typeof(&baz3).stringof == "int delegate()");
+}
+
+/***************************************************/
// 7019
struct S7019
@@ -169,6 +197,7 @@ void test8942()
int main()
{
test6475();
+ test6905();
test7019();
test7239();
test8123();
Something went wrong with that request. Please try again.