feat: report scan matches whose type is inaccessible (AWT193)#115
Conversation
A `[Scan]` dropped a candidate the generated container cannot name (an implementation `internal` to another assembly, or a private nested class) without a word: the type vanished from the container and the build stayed green. The contract side of the same feature already carries dropped interfaces through to AWT188, so an inaccessible exposure interface warned while an inaccessible implementation type did not. The accessibility test moves out of `IsScanCandidate`'s early-out, where it ran before marker assignability and so could only have warned once per internal type in every scanned assembly. Candidates are now carried as a `ScanCandidate` flagged with the accessibility verdict (mirroring `ScanContractSet.Inaccessible`), the scan's `NamePatterns`/`NamespacePatterns`/`Exclude` filters run as usual, and only a flagged candidate that survives them is reported as AWT193 and dropped. A markerless scan reports it too, since AWT183 already forces it to narrow its candidates. `IsScanCandidate` now also skips a type with no source name at all (`CanBeReferencedByName`), which the accessibility test used to filter incidentally: `<Module>` and compiler-generated closures are nobody's scan match and must not reach the diagnostic. Two consequences worth naming: an `InAssembliesOf` assembly whose only matches are inaccessible reports AWT193 rather than AWT140, which no longer has to hint at a missing `ProjectReference`; and `Awaiten.Tests` sets `NoWarn=AWT193`, because its cross-assembly scan fixture deliberately keeps an internal plugin it has no way to filter out.
Corrects the NoWarn justification in Awaiten.Tests. The old comment claimed the cross-assembly scans had no way to filter the internal fixture out, which contradicted both the diagnostic's own advice ("exclude it from the scan") and this branch's own DoesNotReportWhenNamePatternsExcludeTheType, which pins that a `!`-prefixed NamePatterns entry silences AWT193 on an inaccessible type without ever naming it. The real reason to suppress rather than filter is that a name filter would become the reason the type is skipped, when those scans exist to prove that the accessibility is.
Pins the AWT184 a markerless scan reports alongside AWT193. It was previously unasserted, so the pair was an accident rather than a decision. Both are true and complementary: AWT184 says nothing registered, AWT193 says why, which is strictly more than AWT184 said on its own before.
Covers the InternalsVisibleTo remedy the message advertises, which had no test. It holds for an internal type with an implicit constructor; an explicitly internal constructor still reports AWT104 until the sibling accessibility fix lands, so the test pins only the half that is stable here.
Rewrites AWT193's XML doc to drop a spaced-hyphen parenthetical, which the rest of Diagnostics.cs expresses with commas and colons instead.
🚀 Benchmark ResultsDetails
Details
Details
|
The message and docs advised 'exclude it from the scan', but the Exclude type list cannot name an inaccessible type; only a NamePatterns/ NamespacePatterns entry can. Say so. Also record why the Awaiten.Tests suppression is project-wide NoWarn: AWT193 is emitted by the source generator, which neither #pragma warning disable nor a per-file .editorconfig severity reaches.
|
… inaccessible (AWT193) (#115) by Valentin Breuß
… inaccessible (AWT193) (#115) by Valentin Breuß



A
[Scan]dropped a candidate the generated container cannot name (an implementationinternalto another assembly, or a private nested class) without a word: the type vanished from the container and the build stayed green. The contract side of the same feature already carries dropped interfaces through to AWT188, so an inaccessible exposure interface warned while an inaccessible implementation type did not.The accessibility test moves out of
IsScanCandidate's early-out, where it ran before marker assignability and so could only have warned once per internal type in every scanned assembly. Candidates are now carried as aScanCandidateflagged with the accessibility verdict (mirroringScanContractSet.Inaccessible), the scan'sNamePatterns/NamespacePatterns/Excludefilters run as usual, and only a flagged candidate that survives them is reported as AWT193 and dropped. A markerless scan reports it too, since AWT183 already forces it to narrow its candidates.IsScanCandidatenow also skips a type with no source name at all (CanBeReferencedByName), which the accessibility test used to filter incidentally:<Module>and compiler-generated closures are nobody's scan match and must not reach the diagnostic.Two consequences worth naming: an
InAssembliesOfassembly whose only matches are inaccessible reports AWT193 rather than AWT140, which no longer has to hint at a missingProjectReference; andAwaiten.TestssetsNoWarn=AWT193, because its cross-assembly scan fixture deliberately keeps an internal plugin it has no way to filter out.