Repository: goadesign/goa (go)

Issue:
Data type of method output declared twice
I am seeing the following build issue in goa-generated code since I upgraded to v3.2.1:

```# github.com/sevein/goademo/api/gen/demo
api/gen/demo/service.go:59:6: GoademoStoredDemo redeclared in this block
	previous declaration at api/gen/demo/service.go:40:6
##[error]Process completed with exit code 2.
```

See [build output](https://github.com/sevein/goademo/runs/980198285) for more details.

I have set up a repository where the issue can be reproduced consistently: https://github.com/sevein/goademo.

Pull request:
Correctly handle mime types with dashes
when computing types that need to be generated.

Fix #2657 

Patch:
diff --git a/codegen/service/service.go b/codegen/service/service.go
index b61a92b7..1c3b4e9c 100644
--- a/codegen/service/service.go
+++ b/codegen/service/service.go
@@ -66,7 +66,7 @@ func File(genpkg string, service *expr.ServiceExpr) *codegen.File {
 		}
 	}
 	for _, ut := range svc.userTypes {
-		if _, ok := seen[ut.Name]; !ok {
+		if _, ok := seen[ut.VarName]; !ok {
 			sections = append(sections, &codegen.SectionTemplate{
 				Name:   "service-user-type",
 				Source: userTypeT,


Test patch:
diff --git a/codegen/service/service_test.go b/codegen/service/service_test.go
index a591dc78..6ecf3053 100644
--- a/codegen/service/service_test.go
+++ b/codegen/service/service_test.go
@@ -28,6 +28,7 @@ func TestService(t *testing.T) {
 		{"result-collection-multiple-views", testdata.ResultCollectionMultipleViewsMethodDSL, testdata.ResultCollectionMultipleViewsMethod},
 		{"result-with-other-result", testdata.ResultWithOtherResultMethodDSL, testdata.ResultWithOtherResultMethod},
 		{"result-with-result-collection", testdata.ResultWithResultCollectionMethodDSL, testdata.ResultWithResultCollectionMethod},
+		{"result-with-dashed-mime-type", testdata.ResultWithDashedMimeTypeMethodDSL, testdata.ResultWithDashedMimeTypeMethod},
 		{"service-level-error", testdata.ServiceErrorDSL, testdata.ServiceError},
 		{"custom-errors", testdata.CustomErrorsDSL, testdata.CustomErrors},
 		{"custom-errors-custom-field", testdata.CustomErrorsCustomFieldDSL, testdata.CustomErrorsCustomField},
diff --git a/codegen/service/testdata/service_code.go b/codegen/service/testdata/service_code.go
index 7c9090cd..5951e05d 100644
--- a/codegen/service/testdata/service_code.go
+++ b/codegen/service/testdata/service_code.go
@@ -1079,6 +1079,72 @@ func newRT2ViewTiny(res *RT2) *resultwithresulttypecollectionviews.RT2View {
 }
 `
 
+const ResultWithDashedMimeTypeMethod = `
+// Service is the ResultWithDashedMimeType service interface.
+type Service interface {
+	// A implements A.
+	A(context.Context) (res *ApplicationDashedType, err error)
+	// List implements list.
+	List(context.Context) (res *ListResult, err error)
+}
+
+// ServiceName is the name of the service as defined in the design. This is the
+// same value that is set in the endpoint request contexts under the ServiceKey
+// key.
+const ServiceName = "ResultWithDashedMimeType"
+
+// MethodNames lists the service method names as defined in the design. These
+// are the same values that are set in the endpoint request contexts under the
+// MethodKey key.
+var MethodNames = [2]string{"A", "list"}
+
+// ApplicationDashedType is the result type of the ResultWithDashedMimeType
+// service A method.
+type ApplicationDashedType struct {
+	Name *string
+}
+
+// ListResult is the result type of the ResultWithDashedMimeType service list
+// method.
+type ListResult struct {
+	Items ApplicationDashedTypeCollection
+}
+
+type ApplicationDashedTypeCollection []*ApplicationDashedType
+
+// NewApplicationDashedType initializes result type ApplicationDashedType from
+// viewed result type ApplicationDashedType.
+func NewApplicationDashedType(vres *resultwithdashedmimetypeviews.ApplicationDashedType) *ApplicationDashedType {
+	return newApplicationDashedType(vres.Projected)
+}
+
+// NewViewedApplicationDashedType initializes viewed result type
+// ApplicationDashedType from result type ApplicationDashedType using the given
+// view.
+func NewViewedApplicationDashedType(res *ApplicationDashedType, view string) *resultwithdashedmimetypeviews.ApplicationDashedType {
+	p := newApplicationDashedTypeView(res)
+	return &resultwithdashedmimetypeviews.ApplicationDashedType{Projected: p, View: "default"}
+}
+
+// newApplicationDashedType converts projected type ApplicationDashedType to
+// service type ApplicationDashedType.
+func newApplicationDashedType(vres *resultwithdashedmimetypeviews.ApplicationDashedTypeView) *ApplicationDashedType {
+	res := &ApplicationDashedType{
+		Name: vres.Name,
+	}
+	return res
+}
+
+// newApplicationDashedTypeView projects result type ApplicationDashedType to
+// projected type ApplicationDashedTypeView using the "default" view.
+func newApplicationDashedTypeView(res *ApplicationDashedType) *resultwithdashedmimetypeviews.ApplicationDashedTypeView {
+	vres := &resultwithdashedmimetypeviews.ApplicationDashedTypeView{
+		Name: res.Name,
+	}
+	return vres
+}
+`
+
 const ForceGenerateType = `
 // Service is the ForceGenerateType service interface.
 type Service interface {
diff --git a/codegen/service/testdata/service_dsls.go b/codegen/service/testdata/service_dsls.go
index 5a856106..3aa9dd2a 100644
--- a/codegen/service/testdata/service_dsls.go
+++ b/codegen/service/testdata/service_dsls.go
@@ -310,6 +310,24 @@ var ResultWithResultCollectionMethodDSL = func() {
 	})
 }
 
+var ResultWithDashedMimeTypeMethodDSL = func() {
+	var RT = ResultType("application/vnd.application.dashed-type", func() {
+		Attributes(func() {
+			Attribute("name")
+		})
+	})
+	var _ = Service("ResultWithDashedMimeType", func() {
+		Method("A", func() {
+			Result(RT)
+		})
+		Method("list", func() {
+			Result(func() {
+				Attribute("items", CollectionOf(RT))
+			})
+		})
+	})
+}
+
 var ForceGenerateTypeDSL = func() {
 	var _ = Type("ForcedType", func() {
 		Attribute("a", String)