From 15259b7319c1a7c7782888bec28c8d5acdeb317f Mon Sep 17 00:00:00 2001 From: k-hara Date: Sat, 13 Sep 2014 13:30:52 +0900 Subject: [PATCH 1/2] fix Issue 8307 - inconsistent treatment of auto functions --- function.dd | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/function.dd b/function.dd index 9e6b27343a..dc18e36016 100644 --- a/function.dd +++ b/function.dd @@ -125,27 +125,25 @@ foo() = 3; // reference returns can be lvalues $(H4 $(LNAME2 auto-functions, Auto Functions)) - $(P Auto functions have their return type inferred from any - $(GLINK2 statement, ReturnStatement)s - in the function body. - ) + $(P Auto functions have their return type inferred from any + $(GLINK2 statement, ReturnStatement)s in the function body. + ) - $(P An auto function is declared without a return type. + $(P An auto function is declared without a return type. If it does not already have a storage class, use the $(D_KEYWORD auto) storage class. - ) + ) - $(P If there are multiple $(I ReturnStatement)s, the types - of them must match exactly. If there are no $(I ReturnStatement)s, - the return type is inferred to be $(D_KEYWORD void). - ) + $(P If there are multiple $(I ReturnStatement)s, the types + of them must be implicitly convertible to a common type. + If there are no $(I ReturnStatement)s, the return type is inferred + to be $(D_KEYWORD void). ---- -auto foo(int i) -{ - return i + 3; // return type is inferred to be int -} ---- + --- + auto foo(int x) { return x + 3; } // inferred to be int + auto foo(int x) { return x; return 2.5; } // inferred to be double + --- + ) $(H4 $(LNAME2 auto-ref-functions, Auto Ref Functions)) From 7961228c7acafc7b96ef463256b5adc48e161598 Mon Sep 17 00:00:00 2001 From: k-hara Date: Sat, 13 Sep 2014 13:30:54 +0900 Subject: [PATCH 2/2] fix Issue 13336 - auto ref return deduced to be ref despite return value coercion --- function.dd | 48 +++++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/function.dd b/function.dd index dc18e36016..9d9d46d981 100644 --- a/function.dd +++ b/function.dd @@ -147,29 +147,43 @@ $(H4 $(LNAME2 auto-functions, Auto Functions)) $(H4 $(LNAME2 auto-ref-functions, Auto Ref Functions)) - $(P Auto ref functions infer their return type just as + $(P Auto ref functions infer their return type just as $(RELATIVE_LINK2 auto-functions, auto functions) do. In addition, they become $(RELATIVE_LINK2 ref-functions, ref functions) - if the return expression is an lvalue, + if all return expressions are lvalues, and it would not be a reference to a local or a parameter. - ) ---- -auto ref foo(int x) { return x; } // value return -auto ref foo() { return 3; } // value return -auto ref foo(ref int x) { return x; } // ref return -auto ref foo(out int x) { return x; } // ref return -auto ref foo() { static int x; return x; } // ref return ---- + --- + auto ref foo(int x) { return x; } // value return + auto ref foo() { return 3; } // value return + auto ref foo(ref int x) { return x; } // ref return + auto ref foo(out int x) { return x; } // ref return + auto ref foo() { static int x; return x; } // ref return + --- + ) - $(P The lexically first $(GLINK2 statement, ReturnStatement) - determines the ref-ness of a function: - ) + $(P The ref-ness of a function is determined from all + $(GLINK2 statement, ReturnStatement)s in the function body: ---- -auto ref foo(ref int x) { return 3; return x; } // ok, value return -auto ref foo(ref int x) { return x; return 3; } // error, ref return, 3 is not an lvalue ---- + --- + auto ref foo(ref int x) { return 3; return x; } // ok, value return + auto ref foo(ref int x) { return x; return 3; } // ok, value return + auto ref foo(ref int x, ref double y) + { + return x; return y; + // The return type is deduced to double, but cast(double)x is not an lvalue, + // then become a value return. + } + --- + ) + + $(P Auto ref function can have explicit return type. + + --- + auto ref int foo(ref int x) { return x; } // ok, ref return + auto ref int foo(double x) { return x; } // error, cannot convert double to int + --- + ) $(H4 $(LNAME2 inout-functions, Inout Functions))