Skip to content

Commit 91a3d1d

Browse files
authored
🧪 Add test for synonym types (#128)
The `analyzer` package currently has tests for type aliases that define a new type, like this: ```go type TestAlias Test ``` But not for type aliases that _don't_ define a new type but only a new symbol, like this: ```go type TestSynonym = Test ``` I've called this second category "synonyms" but Go's documentation calls them "aliases". What the current tests call "aliases" is generally seen as a distinct type with the same memory layout. This PR adds tests for these "synonyms". All of these tests pass. The PR can be merged with no impact on any of the analyzer's behaviour. **Why am I adding these tests?** Because while these tests pass with Go 1.21, they fail with Go 1.23 and above. I haven't figured out what change in Go 1.23 breaks the analyzer for these cases yet. But when it comes time to fix the analyzer, these tests will be useful. **The linter is buggy in `golangci-lint` now.** When compiling `go-exhaustruct` directly, the `go 1.21` directive in `go.mod` makes sure the behaviour works as expected. However, `golangci-lint` does not compile `go-exhaustruct` directly: it imports the analyzer and then compiles `golangci-lint` as a whole. A few days ago, `golangci-lint` changed their `go 1.22` directive to `go 1.23`, which silently broke the `exhaustruct` linter. Starting with `golangci-lint` v1.65.0, the `exhaustruct` linter does not detect missing fields for types with an alias. Here is the smallest example I could build to reproduce: ```go package foo type Foo struct { A int B int } type FooAlias = Foo func MyFunc() { _ = FooAlias{ A: 1, } } ``` When running linters on the code above, we observe this behaviour: ✅ `golangci-lint` v1.64.x detects the missing field. ❌ `golangci-lint` v1.65.x does not detect the missing field. ✅ `go-exhaustruct` v3.3.0 compiled with Go 1.22 detects the missing field. ❌ `go-exhaustruct` v3.3.0 compiled with Go 1.23 does not detect the missing field. I plan to open an issue on `golangci-lint` as well, because it's their upgrade that broke the linter. However I think the fix will be easiest to implement in `go-exhaustruct`.
1 parent 64da973 commit 91a3d1d

File tree

1 file changed

+25
-0
lines changed
  • analyzer/testdata/src/i

1 file changed

+25
-0
lines changed

analyzer/testdata/src/i/i.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,28 @@ func shouldFailExternalTypeAliases() {
223223
_ = TestExternalAliasAlias{} // want "i.TestExternalAliasAlias is missing fields A, B"
224224
_ = TestExternalExcludedAlias{} // want "i.TestExternalExcludedAlias is missing fields A, B"
225225
}
226+
227+
type TestSynonym = Test
228+
type TestSynonymSynonym = TestSynonym
229+
type TestSynonymAlias TestSynonym
230+
type TestSynonymExcluded = Test
231+
232+
func shouldFailTypeSynonyms() {
233+
_ = TestSynonym{} // want "i.Test is missing fields A, B, C, D"
234+
_ = TestSynonymSynonym{} // want "i.Test is missing fields A, B, C, D"
235+
_ = TestSynonymAlias{} // want "i.TestSynonymAlias is missing fields A, B, C, D"
236+
_ = TestSynonymExcluded{} // want "i.Test is missing fields A, B, C, D"
237+
}
238+
239+
type TestExternalSynonym = e.External
240+
type TestExternalSynonymSynonym = TestExternalSynonym
241+
type TestExternalExcludedSynonym = e.ExternalExcluded
242+
243+
func shouldFailExternalTypeSynonyms() {
244+
_ = TestExternalSynonym{} // want "e.External is missing fields A, B"
245+
_ = TestExternalSynonymSynonym{} // want "e.External is missing fields A, B"
246+
}
247+
248+
func shouldSucceedExcludedSynonyms() {
249+
_ = TestExternalExcludedSynonym{}
250+
}

0 commit comments

Comments
 (0)