Re: Solution to "statement is not reachable" depending on template variables?

2017-06-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sunday, 18 June 2017 at 11:11:59 UTC, Johan Engelen wrote:
On Sunday, 18 June 2017 at 09:56:50 UTC, Steven Schveighoffer 
wrote:

On Sunday, 18 June 2017 at 09:28:57 UTC, Johan Engelen wrote:
Reviving this thread to see whether anything has changed on 
the topic.




If Timon gets static for each into the language, it can look a 
little better.


Can you help me understand what you mean? How will it improve 
things? (static foreach would disable the "statement not 
reachable" analysis?)


-Johan


On my phone so can't be too detailed, but you could do:

static foreach(i; 0..seq.length+1)
  static if(seq.length == i)
return true;
  else static if(is(seq[i] == bool))
return false;

Maybe looks a little better than the first workaround.

-Steve


Re: Solution to "statement is not reachable" depending on template variables?

2017-06-18 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 18 June 2017 at 11:11:59 UTC, Johan Engelen wrote:
On Sunday, 18 June 2017 at 09:56:50 UTC, Steven Schveighoffer 
wrote:

On Sunday, 18 June 2017 at 09:28:57 UTC, Johan Engelen wrote:
Reviving this thread to see whether anything has changed on 
the topic.




If Timon gets static for each into the language, it can look a 
little better.


Can you help me understand what you mean? How will it improve 
things? (static foreach would disable the "statement not 
reachable" analysis?)


The new static foreach is AFAIK supposed to execute the loop 
instead of unrolling it, i.e. the expansion of


---
foreach (i, U; T) {
static if (is(U == bool)) {
return false;
}
}
return true;
---

to

---
static if (is(U1 == bool)) {
return false;
}
static if (is(U2 == bool)) {
return false;
}
...
return true;
---

, which triggers that "statement is not reachable"  if at least 
one of U1,U2,... = T is bool, will not occur if you instead use 
`static foreach (i, U; T)`.


Re: Solution to "statement is not reachable" depending on template variables?

2017-06-18 Thread Johan Engelen via Digitalmars-d-learn
On Sunday, 18 June 2017 at 09:56:50 UTC, Steven Schveighoffer 
wrote:

On Sunday, 18 June 2017 at 09:28:57 UTC, Johan Engelen wrote:
Reviving this thread to see whether anything has changed on 
the topic.




If Timon gets static for each into the language, it can look a 
little better.


Can you help me understand what you mean? How will it improve 
things? (static foreach would disable the "statement not 
reachable" analysis?)


-Johan



Re: Solution to "statement is not reachable" depending on template variables?

2017-06-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On Sunday, 18 June 2017 at 09:28:57 UTC, Johan Engelen wrote:
Reviving this thread to see whether anything has changed on the 
topic.




If Timon gets static for each into the language, it can look a 
little better.


-Steve




Re: Solution to "statement is not reachable" depending on template variables?

2017-06-18 Thread Johan Engelen via Digitalmars-d-learn
Reviving this thread to see whether anything has changed on the 
topic.


I now have this monster:
```
struct FMT {
  // has immutable members. FMT cannot be assigned to.
}

FMT monsterThatCompilerAccepts(T)(){
alias TP = Tuple!(__traits(getAttributes, T));
foreach(i, att; TP){
static if( ... ) {
return FMT( ... );
}

// Make sure we return a default value in the last 
iteration.
// Prevents "statement not reachable" warning when placed 
here instead of outside the foreach.

else static if (i + 1 == TP.length) {
return FMT( ... );
}
}
static if (TP.length == 0) {
return FMT( ... );
}
}

FMT codeThatIsUnderstandableButNotAccepted(T)(){
alias TP = Tuple!(__traits(getAttributes, T));
foreach(i, att; TP){
static if( ... ) {
return FMT( ... );
}
}
return FMT( ... );
}
```

Thanks,
  Johan


Re: Solution to "statement is not reachable" depending on template variables?

2016-04-01 Thread ZombineDev via Digitalmars-d-learn

On Friday, 1 April 2016 at 01:21:32 UTC, Walter Bright wrote:

On 3/16/2016 4:18 AM, Johan Engelen wrote:
   I've found discussions, but not an actual "recommended" 
solution for the
problem of "statement is not reachable" warnings in templates 
with early

returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not 
reachable"

}



bool nobool(T...)() {
 bool result = true;
 foreach (i, U; T) {
 static if (is(U == bool)) {
 result = false;
 break;
 }
 else
 {
 ...
 }
 }
 return result;  // emits "Warning: statement is not 
reachable"

}

Note that the optimizer will remove the dead loads.


Actually, I would expect every call of this fuction to be 
replaced by a boolean constant, since the result depends only on 
compile-time information.


What happened to "obvious code should be correct"? Can we try to 
find a solution that doesn't look like a hack? I don't think that 
we should ask users of the language to uglify their code just to 
workaround a deficiency in the compiler. Instead, we should 
improve the lowering of the static foreach construct so the 
information that it is syntactically a loop is preserved after 
loop unrolling.


Re: Solution to "statement is not reachable" depending on template variables?

2016-04-01 Thread Johan Engelen via Digitalmars-d-learn

On Friday, 1 April 2016 at 01:21:32 UTC, Walter Bright wrote:

On 3/16/2016 4:18 AM, Johan Engelen wrote:
   I've found discussions, but not an actual "recommended" 
solution for the
problem of "statement is not reachable" warnings in templates 
with early

returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not 
reachable"

}



bool nobool(T...)() {
 bool result = true;
 foreach (i, U; T) {
 static if (is(U == bool)) {
 result = false;
 break;
 }
 else
 {
 ...
 }
 }
 return result;  // emits "Warning: statement is not 
reachable"

}


As you can see from my first post, that is the solution I used 
first  (without the "break;" addition), but it works until...



Note that the optimizer will remove the dead loads.


... until someone adds a (imho useful) diagnostic of dead 
stores/loads. :-)
In that case, I guess inverting all bools and then inverting the 
return value at the end will work (using default initialization 
of result); but this is not possible in a slightly more 
complicated case with non-bool return types.


In another piece of code, the return type is a struct with an 
immutable member. That's when I gave up on working around the 
warning and just disabled it.

Simplified, something like this:

struct IMM {
immutable bool result;
}
IMM immut(T...)() {
IMM retval = IMM(true);
foreach (i, U; T) {
static if (is(U == bool)) {
retval = IMM(false);  //  "Error: cannot modify 
struct retval IMM with immutable member".

}
}
return retval;
}




Re: Solution to "statement is not reachable" depending on template variables?

2016-03-31 Thread Walter Bright via Digitalmars-d-learn

On 3/16/2016 4:18 AM, Johan Engelen wrote:

   I've found discussions, but not an actual "recommended" solution for the
problem of "statement is not reachable" warnings in templates with early
returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not reachable"
}



bool nobool(T...)() {
 bool result = true;
 foreach (i, U; T) {
 static if (is(U == bool)) {
 result = false;
 break;
 }
 else
 {
 ...
 }
 }
 return result;  // emits "Warning: statement is not reachable"
}

Note that the optimizer will remove the dead loads.


Solution to "statement is not reachable" depending on template variables?

2016-03-20 Thread Johan Engelen via Digitalmars-d-learn

Hi all,
  I've found discussions, but not an actual "recommended" 
solution for the problem of "statement is not reachable" warnings 
in templates with early returns, e.g.:

```
bool nobool(T...)() {
foreach (i, U; T) {
static if (is(U == bool)) {
return false;
}
}
return true;  // emits "Warning: statement is not reachable"
}

bool nobool_nowarning(T...)() {
bool retval = true;
foreach (i, U; T) {
static if (is(U == bool)) {
retval = false;
}
}
return retval;
}

void main() {
static assert ( nobool_nowarning!(int,bool)() == false );
static assert ( nobool_nowarning!(int,int)() == true );

static assert ( nobool!(int,bool)() == false );
static assert ( nobool!(int,int)() == true );
}
```
(I have heavily simplified the real-world code, please don't 
discuss alternative solutions to the "is(U==bool)" in particular. 
For sake of argument, assume that the predicate is a complicated 
beast.)


The `nobool` template prevents compilation with `-w`. Is 
`nobool_nowarning`, with the early return eradicated, the only 
acceptable solution? (with the hope that there will not be a 
"dead store" warning in the future...)

What if early returns cannot be avoided?

Thanks,
  Johan



Re: Solution to "statement is not reachable" depending on template variables?

2016-03-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/16/16 7:18 AM, Johan Engelen wrote:

Hi all,
   I've found discussions, but not an actual "recommended" solution for
the problem of "statement is not reachable" warnings in templates with
early returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not reachable"
}


Instead of foreach, you could use recursive mechanism. Not ideal, but it 
would work.


Another possibility:

foreach(i, U; T) {
   static if(is(U == bool)) {
   return false;
   } else static if(i + 1 == T.length) {
   return true;
   }
}

-Steve


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 3/16/16 9:48 PM, tsbockman wrote:

On Wednesday, 16 March 2016 at 11:22:02 UTC, rikki cattermole wrote:

Change those static if's to just plain old ifs.


This only works (sometimes) because D's value range propagation doesn't
understand comparisons or normal if statements very well. This will
hopefully be fixed sooner or later:
 https://github.com/D-Programming-Language/dmd/pull/1913
 https://github.com/D-Programming-Language/dmd/pull/5229

The only future-proof way to fix the "statement is not reachable"
warning, is to guard the potentially unreachable code with a `static if`
whose predicate precisely describes the circumstances in which it
becomes unreachable...

Which itself is a terrible solution that doesn't scale well at all
to complex generic code and violates the "DRY" principle.

We really ought to just remove the warning. It just doesn't mesh well
with D's super-powered meta-programming features.


Yes. I agree. The way I look at it is that the code *is* reached in some 
cases, so it should compile (and just remove that section in that instance).


IMO any time a template value is used for branching, it should turn that 
warning off.


-Steve


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread tsbockman via Digitalmars-d-learn
On Thursday, 17 March 2016 at 17:12:07 UTC, Steven Schveighoffer 
wrote:
Yes. I agree. The way I look at it is that the code *is* 
reached in some cases, so it should compile (and just remove 
that section in that instance).


IMO any time a template value is used for branching, it should 
turn that warning off.


-Steve


That's what I think it should do, also. However, when we 
discussed it before, Daniel Murphy pretty much told me there is 
no practical way to actually implement that behavior in the 
compiler.


So, the next best thing is to just remove the warning entirely.


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread QAston via Digitalmars-d-learn

On Wednesday, 16 March 2016 at 11:18:36 UTC, Johan Engelen wrote:

Hi all,
  I've found discussions, but not an actual "recommended" 
solution for the problem of "statement is not reachable" 
warnings in templates with early returns, e.g.:

```
bool nobool(T...)() {
foreach (i, U; T) {
static if (is(U == bool)) {
return false;
}
}
return true;  // emits "Warning: statement is not reachable"
}

[...]


On Wednesday, 16 March 2016 at 11:18:36 UTC, Johan Engelen wrote:
import std.meta;
template isBool(U)() = is(U == bool);
static if (!allSatisfy!(isBool, T)) {
return true;  // no longer emits a warning
}

Something like this should work.


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread Johan Engelen via Digitalmars-d-learn

On Wednesday, 16 March 2016 at 11:47:35 UTC, QAston wrote:


import std.meta;
template isBool(U)() = is(U == bool);
static if (!allSatisfy!(isBool, T)) {
return true;  // no longer emits a warning
}

Something like this should work.


Thanks, but:

On Wednesday, 16 March 2016 at 11:18:36 UTC, Johan Engelen wrote:
(I have heavily simplified the real-world code, please don't 
discuss alternative solutions to the "is(U==bool)" in 
particular. For sake of argument, assume that the predicate is 
a complicated beast.)




Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread rikki cattermole via Digitalmars-d-learn

On 17/03/16 5:05 AM, Johan Engelen wrote:

On Wednesday, 16 March 2016 at 11:22:02 UTC, rikki cattermole wrote:


Change those static if's to just plain old ifs.


But then this wouldn't compile, would it?
```
static if(__traits(compiles, __traits(getMember, a, "b"))) {
return a.b;
}
```
(real code, I am not making this up)


Hmm no.
If that's in a foreach as well, you'll need to solve it some other way.

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus



Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread QAston via Digitalmars-d-learn

On Wednesday, 16 March 2016 at 17:08:20 UTC, Johan Engelen wrote:

On Wednesday, 16 March 2016 at 11:47:35 UTC, QAston wrote:


import std.meta;
template isBool(U)() = is(U == bool);
static if (!allSatisfy!(isBool, T)) {
return true;  // no longer emits a warning
}

Something like this should work.


Thanks, but:

On Wednesday, 16 March 2016 at 11:18:36 UTC, Johan Engelen 
wrote:
(I have heavily simplified the real-world code, please don't 
discuss alternative solutions to the "is(U==bool)" in 
particular. For sake of argument, assume that the predicate is 
a complicated beast.)


This method will work regarless of the predicate, just check if 
the predicate isn't matched for the whole array using 
allSatisfy/anySatisfy.


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread Johan Engelen via Digitalmars-d-learn
On Wednesday, 16 March 2016 at 17:34:13 UTC, Steven Schveighoffer 
wrote:

On 3/16/16 7:18 AM, Johan Engelen wrote:

Hi all,
   I've found discussions, but not an actual "recommended" 
solution for
the problem of "statement is not reachable" warnings in 
templates with

early returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not 
reachable"

}


Instead of foreach, you could use recursive mechanism. Not 
ideal, but it would work.


Another possibility:

foreach(i, U; T) {
   static if(is(U == bool)) {
   return false;
   } else static if(i + 1 == T.length) {
   return true;
   }
}


I like your second solution, it's clever :)




Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread tsbockman via Digitalmars-d-learn
On Wednesday, 16 March 2016 at 11:22:02 UTC, rikki cattermole 
wrote:

Change those static if's to just plain old ifs.


This only works (sometimes) because D's value range propagation 
doesn't understand comparisons or normal if statements very well. 
This will hopefully be fixed sooner or later:

https://github.com/D-Programming-Language/dmd/pull/1913
https://github.com/D-Programming-Language/dmd/pull/5229

The only future-proof way to fix the "statement is not reachable" 
warning, is to guard the potentially unreachable code with a 
`static if` whose predicate precisely describes the circumstances 
in which it becomes unreachable...


...Which itself is a terrible solution that doesn't scale well at 
all to complex generic code and violates the "DRY" principle.


We really ought to just remove the warning. It just doesn't mesh 
well with D's super-powered meta-programming features.


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-19 Thread rikki cattermole via Digitalmars-d-learn

On 16/03/16 11:18 PM, Johan Engelen wrote:

Hi all,
   I've found discussions, but not an actual "recommended" solution for
the problem of "statement is not reachable" warnings in templates with
early returns, e.g.:
```
bool nobool(T...)() {
 foreach (i, U; T) {
 static if (is(U == bool)) {
 return false;
 }
 }
 return true;  // emits "Warning: statement is not reachable"
}

bool nobool_nowarning(T...)() {
 bool retval = true;
 foreach (i, U; T) {
 static if (is(U == bool)) {
 retval = false;
 }
 }
 return retval;
}

void main() {
 static assert ( nobool_nowarning!(int,bool)() == false );
 static assert ( nobool_nowarning!(int,int)() == true );

 static assert ( nobool!(int,bool)() == false );
 static assert ( nobool!(int,int)() == true );
}
```
(I have heavily simplified the real-world code, please don't discuss
alternative solutions to the "is(U==bool)" in particular. For sake of
argument, assume that the predicate is a complicated beast.)

The `nobool` template prevents compilation with `-w`. Is
`nobool_nowarning`, with the early return eradicated, the only
acceptable solution? (with the hope that there will not be a "dead
store" warning in the future...)
What if early returns cannot be avoided?

Thanks,
   Johan


Change those static if's to just plain old ifs.

Imagine those foreach loops being unrolled and what that happens there 
isn't just one return there, imagine many many many of them and all of 
them valid.


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus



Re: Solution to "statement is not reachable" depending on template variables?

2016-03-18 Thread Johan Engelen via Digitalmars-d-learn
On Wednesday, 16 March 2016 at 11:22:02 UTC, rikki cattermole 
wrote:


Change those static if's to just plain old ifs.


But then this wouldn't compile, would it?
```
static if(__traits(compiles, __traits(getMember, a, "b"))) {
   return a.b;
}
```
(real code, I am not making this up)

Imagine those foreach loops being unrolled and what that 
happens there isn't just one return there, imagine many many 
many of them and all of them valid.


Yep :-)

Perhaps the only solution is to be able to annotate the code to 
"shut up" DMD about it.


Re: Solution to "statement is not reachable" depending on template variables?

2016-03-18 Thread tsbockman via Digitalmars-d-learn

On Wednesday, 16 March 2016 at 11:18:36 UTC, Johan Engelen wrote:

Hi all,
  I've found discussions, but not an actual "recommended" 
solution for the problem of "statement is not reachable" 
warnings in templates with early returns...


"statement is not reachable" is fundamentally broken in D for 
generic code:

https://issues.dlang.org/show_bug.cgi?id=14835

It's mostly not too big of a deal right now, only because the D 
front end's value range propagation capabilities are very weak.


Lionello Lunesu made a pull request a while back that majorly 
improves VRP in D as a part of his efforts to fix DMD issue 259. 
I decided to port it to DDMD a few months ago, and in the process 
discovered that with decent VRP, issue 14835 becomes 10-100x 
worse.


There was a forum discussion a while back as to what should be 
done about this, but unfortunately the conclusion was that it 
probably cannot really be fixed with any reasonable effort:

http://forum.dlang.org/thread/bnzfuekewfguvnwdz...@forum.dlang.org


As far as I can tell, the only reasonable way forward is to 
simply remove the warning entirely (or ban meaningful upgrades to 
VRP).