Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sanitize Appender constraints a bit. #2178

Merged
merged 1 commit into from Jul 14, 2014
Merged

Sanitize Appender constraints a bit. #2178

merged 1 commit into from Jul 14, 2014

Conversation

monarchdodra
Copy link
Collaborator

This rewrites the template definition of Appender to use the isDynamicArray constraint: This avoids ridiculous declarations of Appender!A where A is convertible to a dynamic array, but not an actual dynamic array (think alias this and static array). AFAIK, this should break nothing, since the constraints should usually be explicit and correct.

I did not change appender's restraint itself, since it worked anyways, as it explicitly created an Appender!(E[]) anyways, and didn't want to break working code for no reason.

The bug I initially wanted to fix was related was (yet again) a "static array" => "dynamic array" implicit conversion error. Basically, static arrays were passed by value to appender, and then appender created an actual Appender by slicing that local static array. This left the appender referencing locally scoped and later destroyed data...

@schveiguy : You've been diligent at reviewing my appender fixes, give this a whirl?

static assert(!is(Appender!(char[5])));
static assert(!is(Appender!D));
static assert(!is(Appender!S));
static assert(!is(Appender!L));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these say !is(typeof(... ? I've never seen this type of construct before.
Edit: Nevermind, I get it now. Duh...

{
static assert (!isStaticArray!A || __traits(isRef, array),
"Cannot create Appender from an rvalue static array");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if this is a correct approach. I think the less code that allows implicit static-array to dynamic array conversion, the better. In particular, currently, this function (mostly) never worked taking static arrays anyways. My new code adds support for them, and I'm not sure that's the right direction to go in?

Maybe it would be better to simply reject them?

Appender!(E[]) appender(A : E[], E)(auto ref A array)
if (!is(A : E[N], size_t N))
{
    ...
}

I can't say there'd be no breakage, but it should be minimal... And it's the only way I see to make appender certifiably correct...

Thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static arrays should be usable by appender. Very frequently, one uses a static buffer, which will work as long as the buffer can hold the data, and then will start appending onto the heap when more data is needed. This provides a very good level of optimization where you may not know exactly how much space is needed, but you have a general idea of the common case.

In any case, supporting slices automatically supports passing in static arrays, since you can just slice it (at least today). I'm unsure of the correct answer. I think for now, just make the changes so the code is correct, and we can talk about breaking code in a different PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mostly meant having the call site take care of the slicing, rather than appender itself. In any case, after thinking about it, I think the new code is OK.

@schveiguy
Copy link
Member

I think this LGTM

@monarchdodra
Copy link
Collaborator Author

Sight, these fixes seem like an exercise in futility:
https://issues.dlang.org/show_bug.cgi?id=12796

@quickfur
Copy link
Member

LGTM, the autotester is passing. Should we just pull this?

@schveiguy
Copy link
Member

I think it can be pulled, I typically do not want to pull something that only I have reviewed. But now you did too, so...

@schveiguy
Copy link
Member

Auto-merge toggled on

schveiguy added a commit that referenced this pull request Jul 14, 2014
@schveiguy schveiguy merged commit 3115f01 into dlang:master Jul 14, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants