D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 8339 - is(typeof(...)) is reporting true when it's false due to nested function error
Summary: is(typeof(...)) is reporting true when it's false due to nested function error
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 blocker
Assignee: No Owner
URL:
Keywords: pull, rejects-valid
Depends on:
Blocks:
 
Reported: 2012-07-02 22:43 UTC by Jonathan M Davis
Modified: 2012-12-28 17:08 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Jonathan M Davis 2012-07-02 22:43:22 UTC
This code fails to compile:

import std.algorithm;

private bool testEmptyInit(R)()
{
    static if(is(typeof({R range;})))
    {
        R range;
        return range.empty;
    }
    else
        return false;
}

void main()
{
    testEmptyInit!(typeof(filter!"true"([0, 1, 2, 3])));
}

giving this error

h.d(7): Error: function std.algorithm.filter!("true").filter!(int[]).filter is a nested function and cannot be accessed from h.testEmptyInit!(FilteredRange).testEmptyInit

So, the compiler thinks that is(typeof({R range;})) is true for the type of filter's result and then it gives an error saying that it's invalid to use it, meaning that it's _not_ valid and therefore is(typeof({R range;})) should be false.

If bug# 5941 were fixed, this wouldn't be as big an issue (though the fact that you can get an error for using a construct when the test for using it passes is definitely a bug regardless), but as long as bug# 5941 exists, this is a major blocker for being able to create a template to check for whether the init value of a range type is empty or not.
Comment 1 Don 2012-07-12 06:11:44 UTC
>So, the compiler thinks that is(typeof({R range;})) is true for the type of
>filter's result and then it gives an error saying that it's invalid to use it,
>meaning that it's _not_ valid and therefore is(typeof({R range;})) should be
>false.

That doesn't follow.
is(typeof(X)) only checks for a valid type. It does *not* check that the code compiles. Checking that typeof(X) compiles is weaker than checking that X compiles. There are several cases where you can obtain a type from something you cannot possibly use. For example you can use typeof(this) in a static member function.

OTOH
__traits(compiles, {R range; }) almost certainly behaves the same way, but it isn't supposed to.

The issue is that the 'nested function' error is happening in the glue layer. It should be happening in the front end.
Comment 2 Jonathan M Davis 2012-07-15 22:48:35 UTC
We use is(typeof(exp)) to check for compilability all over the place. Are you saying that we should be using __traits(compiles, exp) instead?

Using __traits(compiles, {R range;}) still fails here. But should it work as I'm trying to do here if the glue layer issues is fixed?

If not, how am I supposed to test that I can actually _use_ R.init in addition to it existing? Or is it the case that I should _always_ be able to use R.init if it exists?
Comment 3 Don 2012-07-16 07:13:18 UTC
(In reply to comment #2)
> We use is(typeof(exp)) to check for compilability all over the place. Are you
> saying that we should be using __traits(compiles, exp) instead?

Probably. Mostly is(typeof()) does what you want, but just be aware that it's a trick. It's just checking for existence of a type, not for compilability.
It's widespread because it works for D1, which doesn't have __traits.

It's also rather better tested than __traits...

> Using __traits(compiles, {R range;}) still fails here. But should it work as
> I'm trying to do here if the glue layer issues is fixed?

Yes, it should work.
Comment 4 Kenji Hara 2012-08-18 02:48:43 UTC
https://github.com/D-Programming-Language/dmd/pull/1087
https://github.com/D-Programming-Language/phobos/pull/751

Front-end layer should check the frame access is really correct or not.
Comment 5 github-bugzilla 2012-08-18 08:24:06 UTC
Commits pushed to master at https://github.com/D-Programming-Language/phobos

https://github.com/D-Programming-Language/phobos/commit/4a0546480078d51a0ad4dbf141c71bf818e034ec
fix Issue 8339 - is(typeof(...)) is reporting true when it's false due to nested function error

Avoid frame access check and disabled default construction in predicate templates.

https://github.com/D-Programming-Language/phobos/commit/6d42d0286010fce62afe52ad3307cbf38102fe0b
Merge pull request #751 from 9rnsr/fix8339

Supplemental change for dmd/pull/1087 (fix Issue 8339)
Comment 6 github-bugzilla 2012-08-21 12:53:13 UTC
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/a8be86a36d7071092eb6a4a1efddd9552af2581d
fix Issue 8339 - is(typeof(...)) is reporting true when it's false due to nested function error

https://github.com/D-Programming-Language/dmd/commit/578ba6634f9dbb0eb1e132d46dd14c89542497d6
Merge pull request #1087 from 9rnsr/fix8339

Issue 8339 - is(typeof(...)) is reporting true when it's false due to nested function error