[dmd-internals] How not to report unused identifiers

cy via dmd-internals dmd-internals at puremagic.com
Fri Apr 1 10:58:33 PDT 2016


On Wednesday, 30 March 2016 at 01:24:42 UTC, Jonathan M Davis 
wrote:
>  any attempt to warn about "unused identifiers" would have to 
> be done very carefully.

Well, obviously that was a vague, ignorant first attempt. I do 
realize some care would be needed. Though I don't think it's all 
that difficult to define unused identifiers, finding them is a 
lot more complicated than just listing the symbols a module has, 
and subtracting the symbols it ends up exporting. I thought 
search() would be called on internal symbols, not just exports.

> Aside from the normal issues with RAII and the like

So obviously any object with a constructor or a destructor would 
have to be excluded. Something with pure versions of those should 
probably be included though.

> it's _very_ common in D code to declare stuff and then not 
> actually use it when dealing with template constraints and the 
> traits tested in them,

I was sort of hoping to get in there after template instantiation 
had been calculated and only ones with true constraints were left.

> templates and string mixins could run into trouble depending on 
> the exact arguments used with them and how complicated some of 
> their static if-else logic is.

Again, it's important not to check for unused identifiers until 
you've given the programmer a chance to get rid of 'em 
themselves. While it would be possible to check "if this 
constraint had been true, THEN this code here with an unused 
identifier would be used" I don't see any real utility to that. I 
assume you're talking about like...

void main() {
   int i = 42;
   static if(false) {
     int j = 23;
   }
   import std.stdio: writeln;
   writeln(i);
}

I definitely would not include it as a goal to warn that "j" 
would be an unused identifier, if you ever set the condition to 
true. I'd be happy with a warning that only appeared when I did 
set the condition to true, and angry with one that wouldn't go 
away even if I used a CTFE to comment out the whole block of code 
"#if 0" style.

It might be safe not to report any unused identifier that 
appeared to be a type, not a variable or a module.

Anyway, if I could figure it out, this is what a "careful" 
algorithm would do. First, it would only check after the module 
has been fully instantiated, and all the compile time code has 
been executed. Of all the symbols a module has, it removes the 
ones that are touched by other modules (not just imported, but 
actually used, by this algorithm recursively). Then it removes 
any things that can have side effects even if not used, like 
structs or classes with non-pure constructors/destructors.

Then, generally the only thing that crops up in heavily modified 
code is unused imports, so there would be an option to report all 
unused identifiers and if not, it would eliminate all remaining 
symbols that weren't declared in a different module than this one.

Finally, it would have a set of unused identifiers. If the 
aforementioned option were false, it'd build a set of statements 
where those identifiers were imported, and highlight them giving 
a warning about unused import. And if true, it'd report each 
unused identifier, possibly grouped by the modules they came from.

Which is to say, that's what I would do, if I knew when to 
instrument it post-CTFE but pre-runtime, if I knew how to check 
if a symbol were an instantiation of an object with a 
constructor/destructor, if I knew how to look up those functions, 
if I knew how to check if a function is pure, if I knew how to 
get the module a symbol was declared in, if I knew how to get the 
statement a symbol was imported from, if I knew how to untangle 
complicated templated types into the identifiers they're 
constituted of, and if I knew how to add options to invoking dmd.

But for now, I'll have to use the strategy of repeatedly deleting 
import statements, and recompiling to see if it breaks my code.


More information about the dmd-internals mailing list