Issue 13628 - Error: immutable method S.~this is not callable using a mutable object and vice versa
Summary: Error: immutable method S.~this is not callable using a mutable object and vi...
Status: RESOLVED MOVED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P3 normal
Assignee: No Owner
URL:
Keywords: spec
Depends on:
Blocks:
 
Reported: 2014-10-17 13:00 UTC by Marco Leise
Modified: 2023-03-01 14:22 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Marco Leise 2014-10-17 13:00:16 UTC
I get these errors on structs that define a `~this() immutable`:

    Error: immutable method Lib.Sys.File.File.~this is not callable using a mutable object
    Error: mutable method Lib.Sys.File.File.~this is not callable using a immutable object
    Error: mutable method Lib.Sys.FileMapping.FileMapping.~this is not callable using a immutable object
    Error: mutable method Lib.Sys.File.File.~this is not callable using a immutable object
    Error: immutable method Lib.Sys.FileMapping.FileMapping.~this is not callable using a mutable object

For starters it would be nice in which functions these destructions happen.

But then ... WAT?

A) Why would the compiler call the exact opposite dtor of what is needed and the complain? :)

B) If I did actually try to define both `~this()` and `~this() immutable` the compiler would complain that I cannot define both.

C) Why can a dtor be immutable if you cannot even define both a mutable and immutable version to special case some code? It seems to add a lot of complexity.


It seems to me that immutable still has a way to go or that we need to disallow certain usages of immutable.
Comment 1 Marco Leise 2014-10-17 13:21:47 UTC
Reduced test case:

struct B {
    ~this() { /* some cleanup */ }
}

struct C {
    immutable B b;
}

void main() {
    C(immutable B());
}
Comment 2 Maxim Fomin 2015-06-11 19:01:55 UTC
It is by design. You must make destructor immutable to call it for immutable object. Closed as invalid.
Comment 3 Marco Leise 2015-06-11 20:06:53 UTC
You can't just close this without further discussion. That is disrespectful given the three questions I had refer to my failed attempts at doing what you propose as a solution.
Comment 4 Maxim Fomin 2015-06-11 20:47:00 UTC
A) It does not call opposite dtor. It tries to call mutable dtor for mutable object. In other words, it tries to pass immutable object as argument for mutable lvalue parameter. It cannot work.

B) Then it means that currently there is no way to define two dtors which differ by this pointer qualifier. So, it is another problem with D type system. I think it should be possible to do, and compiler should select proper overload. 

C) Basically it is same as b.

I suggest to reopen as request to fix b.
Comment 5 Marco Leise 2015-06-11 21:50:33 UTC
Thanks. B) really is what was bugging me. You can have either type of dtor, but not both, making it impossible to have structs with dtors as both mutable and immutable.
Comment 6 anonymous4 2021-12-20 16:10:19 UTC
In the meantime behavior was changed for simplicity or something like that, now unqualified destructor is always called on unqualified instance, like this:

struct SecureString
{
    char[] secret;
    ~this() { secret[]=0; }
}

int main()
{
    immutable s=immutable SecureString("aa");
    return 0;
}
Comment 7 RazvanN 2023-03-01 14:22:08 UTC
The original report has been fixed as the test case compiles successfully. As for the matter of overloading dtors, there are other issues that represent this problem.