D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 6912 - const(T)[] can be implicitly cast to inout(const(T)[])
Summary: const(T)[] can be implicitly cast to inout(const(T)[])
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 critical
Assignee: No Owner
URL:
Keywords: accepts-invalid, patch
Depends on:
Blocks:
 
Reported: 2011-11-08 16:03 UTC by timon.gehr
Modified: 2011-11-14 21:11 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 timon.gehr 2011-11-08 16:03:34 UTC
Consider:

int[] y;

inout(const(int)[]) foo(inout(int) x){
    y=new int[10];
    const(int)[] q = y;
    inout a = q;
    return a;
}

void main(){
    immutable int x;
    immutable int[] oops = foo(x);
    assert(is(typeof(oops[0]) == immutable));
    auto oldoops_0 = oops[0];
    y[0]++;
    assert(oops[0] != oldoops_0);
}


This is caused by the fact that !is(inout(const(int)[])==inout(int[])), i.e. inout is currently non-transitive in certain cases and making it 'override' const transitively will fix the issue.
Comment 1 Steven Schveighoffer 2011-11-09 06:35:05 UTC
inout a = q;

This line should fail to compile.  const does not implicitly cast to inout.

Note that:

immutable a = q;

doesn't work.  inout should follow the same restrictions.

I don't think this has to do with transitivity (and indeed, inout cannot override const or immutable).  It's just a simple case of inout cannot be implicitly cast from something else.

Remember, inout can get implicitly cast back to immutable or mutable upon function return.  I don't think inout should override *any* qualifiers without casts.
Comment 2 timon.gehr 2011-11-09 08:58:10 UTC
(In reply to comment #1)
> inout a = q;
> 
> This line should fail to compile.  const does not implicitly cast to inout.
> 

Yes, but the issue here is that it casts to inout(const(int)[]). (dmd rejects casting const(int[]) to inout(int[]) for exampe)

> Note that:
> 
> immutable a = q;
> 
> doesn't work.  inout should follow the same restrictions.
> 
> I don't think this has to do with transitivity (and indeed, inout cannot
> override const or immutable).  It's just a simple case of inout cannot be
> implicitly cast from something else.
> 
> Remember, inout can get implicitly cast back to immutable or mutable upon
> function return.  I don't think inout should override *any* qualifiers without
> casts.

You are right, it is not a transitivity/overriding issue.

Currently inout(const(T)) == inout(immutable(T)) == inout(T). That is bad, for example, how to represent the element type of inout(const(char)[]) ? (DMD treats it as const(char), which is obviously wrong, it should be inout(const(char)).)
Comment 3 Kenji Hara 2011-11-09 21:38:49 UTC
https://github.com/D-Programming-Language/dmd/pull/504

This patch will forbid some conversions like follows.
e.g. const(int)[]    to inout(const(int)[])
     const(int)[int] to inout(const(int)[int]).
Comment 4 Steven Schveighoffer 2011-11-10 05:36:46 UTC
I think this should be accepts-invalid, since the given example code should not compile.
Comment 5 Kenji Hara 2011-11-10 06:07:48 UTC
(In reply to comment #4)
> I think this should be accepts-invalid, since the given example code should not
> compile.

Wow, I'm sorry, and thank you for your fix.
Comment 6 Steven Schveighoffer 2011-11-10 06:49:38 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > I think this should be accepts-invalid, since the given example code should not
> > compile.
> 
> Wow, I'm sorry, and thank you for your fix.

Don't worry about it!  The main fix is the patch, my change was a nitpick :)