D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 17138 - Warn about superfluous "with" statements
Summary: Warn about superfluous "with" statements
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P4 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-02-02 14:40 UTC by Eyal
Modified: 2024-12-13 18:51 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Eyal 2017-02-02 14:40:00 UTC
When using:

  with(someObject) {
    BODY;
  }

And none of the expressions within BODY actually use any members of "someObject", and the destructor of "someObject" is not called at the end of the "with" statement, it is a likely bug.

I use the following RAII idiom:

  with(someLock.acquired()) {
    ..
  }

But get no warning if I accidentally:

  with(someLock) {
  }
Comment 1 Walter Bright 2017-05-12 00:53:42 UTC
What does the declaration of someObject look like?
Comment 2 Eyal 2017-05-12 15:24:58 UTC
struct Object {
   auto acquired() {
     struct Acquired {
         Object obj;
         this(Object* obj) { this.obj = obj; obj.acquire(); }
         ~this() { obj.release(); }
     }
     return Acquired(&this);
   }
   ...
}

Resource someObject;
with(someObject.acquired()) { // <-- makes sense
  ..
}

Resource someObject;
with(someObject) { // Oops! Accidental senseless 'with' statement
  ..
}

The latter can be detected as senseless, since it doesn't affect the code in any way.

If dropping the with() statement (and keeping its body instead) would result in the exact same semantics -- warn about superfluous 'with' statement.
Comment 3 Walter Bright 2017-05-13 15:54:47 UTC
Are you suggesting:

---
struct S {
    int field;
}

void foo(S s) {
    with (s)      // no error
        ++field;

    with (s)      // error
        ++s.field;
}
---

?
Comment 4 Eyal 2017-05-13 21:48:36 UTC
Yes, that would be great.
Comment 5 Eyal 2017-05-13 21:53:25 UTC
Another case that is beneficial and should not be an error:

If the expression results in an object that scopes over the block and has a destructor. 

Example:

with(someMutex.acquired) {

  // No use of any fields from the MutexAcquired object

} // dtor of MutexAcquired called here, releasing the mutex

So here you'd want no error either.
Comment 6 dlangBugzillaToGithub 2024-12-13 18:51:29 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/17788

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB