-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider running debug builds of analyzers/source generators in some build leg #88901
Comments
Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas Issue DetailsAnalyzers are compiled against a specific version of the C# compiler. As such they can only recognize the shapes of the code that version of the compiler supports. With a new version of the compiler new shapes become possible, sometimes these are subtle changes, sometimes they mean adding new node types to representation or new enum values to properties. Since we can't update analyzers in sync with the compiler, the analyzer has to be written such that it can survive most of these changes without too much harm (typically it would simply ignore the new shape). But that means that we don't get to be notified if such a new shape start occurring and can't fix the analyzer unless we have some other reason to look into that case. There will be cases where the analyzer doesn't work the way it should simply because it wasn't updated to match the latest compiler behavior. We considered adding a warning into the analyzer to ask the user to file an issue if this happens, but that comes with rather severe downsides:
(See the discussion in #88836 for some more detail) For the illink analyzer we decided to change these cases into assertions. But that means we would like to run the debug build of the analyzer on as much code as possible so that we catch these things internally when they happen. I think it would make sense to do this for all the analyzers where it's possible - there are assertions in their code bases as well which are only exercised on targeted unit tests, but basically never on real-world code. The same thing applies to source generators as well obviously. /cc @sbomer @agocke @jkoritzinsky
|
In faf883d I inadvertently turned off the trim analyzer for libraries, because the analyzer bits don't flow to the consuming project with the ILLink.Tasks ProjectReference. This adds a separate ProjectReference to use the live analyzer. This addresses #88901 for the ILLink analyzers. Using the live analyzer uncovered some bugs that are fixed in this change: - Invalid assert for field initializers with `throw` statements - Invalid cast to `IMethodSymbol` for the ContainingSymbol of a local. Locals can occur in field initializers, when created from out params. - Wrong warning code produced for assignment to annotated property in an initializer. This was being treated as a call to the setter instead of an assignment to the underlying field: `Type AnnotatedPropertyWithSetter { get; set; } = GetUnknown ();` - Invalid assert for delegate creation where the delegate is created from anything other than a method (for example, a field that has an Action or Func type). - Assert inside GetFlowCaptureValue for the LHS of a compound assignment. I couldn't think of a case yet where we actually need to model the result of the assignment, so I implemented support for at least visiting the LHS by going through the same path as normal assignments (avoiding GetFlowCaptureValue).
This was done for the ILLink analyzers in #93259. @agocke @jkoritzinsky are there other analyzers or source generators we should consider?
Note that in #94888 (comment) we settled on throwing, not asserting (but throwing in Debug builds only). That's important because throwing will surface as an AD0001 warning that can be silenced, whereas asserts aren't easily silenced (see #94858). |
We moved all of our assertions into throws (in both debug and release) quite a while ago, so this doesn't apply for the interop generators. Since generally our generators produce code required for a successful compilation (or at least for any meaningful test case to pass), I'm not concerned about suppressions of AD0001. |
Analyzers are compiled against a specific version of the C# compiler. As such they can only recognize the shapes of the code that version of the compiler supports. With a new version of the compiler new shapes become possible, sometimes these are subtle changes, sometimes they mean adding new node types to representation or new enum values to properties. Since we can't update analyzers in sync with the compiler, the analyzer has to be written such that it can survive most of these changes without too much harm (typically it would simply ignore the new shape).
But that means that we don't get to be notified if such a new shape start occurring and can't fix the analyzer unless we have some other reason to look into that case. There will be cases where the analyzer doesn't work the way it should simply because it wasn't updated to match the latest compiler behavior.
We considered adding a warning into the analyzer to ask the user to file an issue if this happens, but that comes with rather severe downsides:
(See the discussion in #88836 for some more detail)
For the illink analyzer we decided to change these cases into assertions. But that means we would like to run the debug build of the analyzer on as much code as possible so that we catch these things internally when they happen.
I think it would make sense to do this for all the analyzers where it's possible - there are assertions in their code bases as well which are only exercised on targeted unit tests, but basically never on real-world code.
The same thing applies to source generators as well obviously.
/cc @sbomer @agocke @jkoritzinsky
The text was updated successfully, but these errors were encountered: