Skip to content
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

The alias defined using the type keyword is not used during code generation; instead, the original type is used. #415

Open
Ifuhao opened this issue Sep 4, 2024 · 5 comments

Comments

@Ifuhao
Copy link

Ifuhao commented Sep 4, 2024

You can use go bug to have a cool, automatically filled out bug template, or
fill out the template below.

Describe the bug

The alias defined using the type keyword is not used during code generation; instead, the original type is used.

To Reproduce

Let's make some changes to the journey program.

There are 2 packages: main and types

in the package types: there are two go files named message.go and greeter.go

message.go

package types

import "fmt"

type Message interface {
	Print()
}

type message struct {
	content string
}

type MessageOptions = func(*message) string

func NewMessage(opt MessageOptions) Message {
	m := &message{}
	opt(m)
	return m
}

func (m *message) Print() {
	fmt.Println(m.content)
}

greeter.go

package types

type Greeter struct {
	message Message
}

func NewGreeter(message Message) Greeter {
	return Greeter{message: message}
}

func (g Greeter) Message() Message {
	return g.message
}

in the package main, there is only one file named wire.go

wire.go

//go:build wireinject
// +build wireinject

package main

import (
	"github.com/google/wire"

	"types"
)

func InitController(gen types.MessageOptions) types.Greeter {
	wire.Build(types.NewGreeter, types.NewMessage)
	return types.Greeter{}
}

Then I ran the wire program to generate wire_gen.go.

wire_gen.go

// Code generated by Wire. DO NOT EDIT.

//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject

package main

import (
	"cascade/app/test/5/types"
)

// Injectors from wire.go:

func InitController(gen func(*types.message) string) types.Greeter {
	message := types.NewMessage(gen)
	greeter := types.NewGreeter(message)
	return greeter
}

Expected behavior

I expect types.MessageOptions to remain in wire_gen.go, rather than being translated to *func(types.message).

Version

v0.6.0

Additional context

nothing

@Ifuhao
Copy link
Author

Ifuhao commented Sep 7, 2024

@ijt @dmitris @cflewis @rsc please help me

@rsc
Copy link
Collaborator

rsc commented Sep 8, 2024

Why does it matter? The type alias and its actual definition should be equivalent?

@Ifuhao
Copy link
Author

Ifuhao commented Sep 9, 2024

@rsc Because type alias is exported(types.MessageOptions), but actual definition has unexported class(types.message)

@rsc
Copy link
Collaborator

rsc commented Sep 9, 2024

I understand now, thanks. The go/types API historically did not expose any information about aliases, so this is the best wire could do. The right answer is probably to make your alias not be an alias:

type MessageOptions func(*message) string

Because func(*message) string is an unnamed type, the language allows implicit conversions between that type and MessageOptions, so basically none of your code should need to change.

We are slowly rolling out support in go/types for having alias information; once that is settled it would probably not be too hard to fix wire if you wanted to.

@Ifuhao
Copy link
Author

Ifuhao commented Sep 10, 2024

Thanks, it works when I use

type MessageOptions func(*message) string

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants