SaladLab/Unity3D.IncrementalCompiler

No way to disable warning CS0649? smcs.rsp replacement?

Closed this issue ยท 12 comments

Warning CS0649: Field '...' is never assigned to, and will always have its default value null.

Of course, with how Unity's serialization assigns values to component fields this warning will exist for pretty much every [SerializeField] field. Is there any way to disable this? It gets very annoying to have dozens/hundreds of these warnings after every compilation, and I don't want to put #pragma's everywhere.

Yes. There should be a way to disable warnings with compiler options. Smcs.rsp does not seem to work on this compiler. ๐Ÿ˜ข I'll take a look at this problem.

Seems like CompileOptions.cs already has support for -nowarn arguments. Just need a way to pass them from unity?

Good catch. You're right! Reading *.rsp and passing it to the compiler will be implemented.

I just released 1.2.5 that supports *.rsp file. Please add your custom compiler options to rsp file and try it again.

Thanks! It seems to work perfectly! I've tested the following warnings both in smcs.rsp (C#) and gmcs.rsp(C# Editor):

warning CS0649: Field '...' is never assigned to, and will always have its default value null
warning CS0414: The field '...' is assigned but its value is never used
warning CS0168: The variable '...' is declared but never used

Now I wonder whether or not CS0649 should be enabled by default somehow. It seems to never show up in Unity's own compilation, and not enabling it by default would definitely result in a ton of these warnings showing up when adding this project to an existing project. What are your thoughts on this?

Good to know it worked ๐Ÿ˜„ .

Basically I agree with your opinion that new compiler should show same warnings like builtin one. Because of this, CS0169 is disabled by default. But CS0649, CS0414, and CS0168 seem not disabled by default on builtin compiler.

Following source is tested for this issue.

using System.Collections;
using UnityEngine;

public class Test04 : MonoBehaviour
{
    // warning test

    private Hashtable table;  // CS0649

    private int x = 1;        // CS0414

    public void Func(object o, string p)
    {
        int j;                // CS0168
        table[p] = o;
    }
}

For this source, both of two compilers tell same warnings like following.

* Builtin Compiler *
Test04.cs(8,23): warning CS0649: Field `Test04.table' is never assigned to, and will always have its default value `null'
Test04.cs(10,17): warning CS0414: The private field `Test04.x' is assigned but its value is never used
Test04.cs(14,13): warning CS0168: The variable `j' is declared but never used

* Incremental Compiler *
Test04.cs(8,23): warning CS0649: Field 'Test04.table' is never assigned to, and will always have its default value null
Test04.cs(10,17): warning CS0414: The field 'Test04.x' is assigned but its value is never used
Test04.cs(14,13): warning CS0168: The variable 'j' is declared but never used

Would you give me an example that shows differences for generating warnings on both compilers?

It turns out CS0649 shows up by default, but not when that field has a [SerializeField] attribute. I don't really know if there is any real way of mimicking this behaviour easily...

Tested with 1.2.5:

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {

    [SerializeField]
    private Hashtable tableSerialized;   // CS0649
    private Hashtable tableAssigned;     // CS0649

    [SerializeField]
    private int xSerialized = 1;         // CS0414
    private int xAssigned = 1;           // CS0414

    public void Func(object o, string p) {
        tableSerialized[p] = o;
        tableAssigned[p] = o;
    }

}

Results:

* Builtin Compiler *
test.cs(8,23): warning CS0649: Field `test.tableAssigned' is never assigned to, and will always have its default value `null'
test.cs(11,17): warning CS0414: The private field `test.xSerialized' is assigned but its value is never used
test.cs(12,17): warning CS0414: The private field `test.xAssigned' is assigned but its value is never used

* Incremental Compiler *
test.cs(7,23): warning CS0649: Field 'test.tableSerialized' is never assigned to, and will always have its default value null
test.cs(8,23): warning CS0649: Field 'test.tableAssigned' is never assigned to, and will always have its default value null
test.cs(11,17): warning CS0414: The field 'test.xSerialized' is assigned but its value is never used
test.cs(12,17): warning CS0414: The field 'test.xAssigned' is assigned but its value is never used

On an unrelated note:
Editor/CompilerSettings.cs(211,26): warning CS0168: The variable 'e' is declared but never used

Thanks you for reporting example! ๐Ÿ‘

I've just delved into what's going on both of compiler for reporting warnings on CS0649. There is a subtle difference for deciding if generates warning or not.

For mono, it ignores CS0649 when there are attributes on an unused fields.

if (f.OptAttributes != null || PartialContainer.HasStructLayout)
    continue;

Report.Warning (649, ...);

But for roslyn, it always shows CS0649 for unused fields no matter if they contain attributes or not.

if (containingType.HasStructLayoutAttribute)
    continue;

diagnostics.Add(ErrorCode.WRN_UnassignedInternalField, ...);

This problem doesn't seem easy and now I'm considering following ways to solve it.

  • Leave it at that:
    • No labour ๐Ÿ˜„ but failed in giving smooth experience for new users.
  • Disable CS0649 by default.
    • Can give smooth experience but it could be dangerous to suppress warnings by default.
  • Manipulate roslyn code.
    • Quick hack that mimic mono's behaviour on reporintng CS0649.

You could add a toggle to the editor window to disable that particular warning. Enable it by default and add a tooltip to it to explain the reasoning behind it. If enabled add it directly to the arguments passed to the compiler instead of appending it to the .rsp files. This way you can keep it on for a smoother experience, or turn it off because you're adding your own stuff to .rsp files.

It's not a dangerous warning to hide after all. Hiding it by default shouldn't be that dangerous.

Nice suggestion for smooth UX ๐Ÿ‘

But I decided to manipulate Roslyn code to imitate mono's behavior of ignoring CS0649 for a field that contains attributes because it's good to keep the incremental compiler a drop-in replacement for built-in one. You can see this modified behavior on new 1.2.6 release.

Alright, kudos for your dedication! ๐Ÿ‘

Thanks for the swift responses and solutions. I'll close this issue now that it's solved for good. ๐Ÿ˜„