gop icon indicating copy to clipboard operation
gop copied to clipboard

errWrap to a internal interface

Open xushiwei opened this issue 8 months ago • 4 comments

The following program sample.gop triggers an unexpected result

// add a sample

import "gop/x/gopprojs"

projs := gopprojs.parseAll(pattern...)!
for proj in projs {
    // ...
}

Expected result

OK

Got

cannot use gopprojs.ParseAll(pattern...) (value of type []interface{projObj()}) as []interface{projObj()} value in assignment

Gop Version

v1.3.7

Additional Notes

No response

xushiwei avatar Mar 31 '25 16:03 xushiwei

/code

xushiwei avatar Oct 12 '25 02:10 xushiwei

Analysis of errWrap with internal interface issue

I've investigated this issue extensively and found that it's a fundamental limitation in how Go's type system handles type aliases with internal interfaces.

Problem Summary:

  1. xgoprojs.Proj is defined as type Proj = interface{projObj()} where projObj() is unexported
  2. When errWrap creates a closure, it must specify return types in the closure signature
  3. The type system gives us []interface{projObj()}, but this cannot be written literally in generated code from package main because projObj() is not accessible
  4. Type aliases in Go are completely transparent - there's no *types.Named representation for them
  5. Creating a new *types.Named wrapper breaks type compatibility during assignment

Why This Is Hard:

  • We need a type that: (a) prints as []xgoprojs.Proj in generated code, AND (b) is considered identical to []interface{projObj()} for type checking
  • Go's type system doesn't provide a way to satisfy both requirements for type aliases
  • The only solution would be to modify gogen's code generator to detect interfaces with unexported methods from other packages and automatically use qualified type names

Proposed Solutions:

  1. Fix in gogen (recommended): Modify gogen's AST/printer to detect when an interface type contains unexported methods from another package, search for a type alias in that package's scope, and use the qualified name instead of the interface literal
  2. Fix in xgoprojs: Change the API design to not use internal interfaces as public return types (breaking change)
  3. Workaround in errWrap: Detect this specific case and generate different code (e.g., not use inline closures)

This issue requires deeper changes to either gogen or the package design. @xushiwei - what approach would you prefer?


Branch: codeagent/claude/issue-2236-1760236688 | Job Run

xgopilot[bot] avatar Oct 12 '25 02:10 xgopilot[bot]

@xgopilot I choose to fix in gogen. Please create an issue for gogen to describe this program and suggested solution.

xushiwei avatar Nov 17 '25 23:11 xushiwei

Task Completed

I've created issue goplus/gogen#547 describing the problem and suggested solution.

Summary:

  • Problem: When using errWrap with type aliases wrapping interfaces with unexported methods, the code generator produces type expressions that reference unexported method names from other packages
  • Root Cause: Type aliases are transparent in Go's type system, but interface literals with unexported methods cannot be written in code outside their defining package
  • Suggested Solution: Modify gogen's AST/printer to detect interfaces with unexported methods from other packages and automatically use the qualified type alias name instead of the interface literal

The issue includes:

  • Complete problem description with the sample code from this issue
  • Root cause analysis explaining why this happens
  • Detailed suggested implementation approach
  • Alternative workarounds for consideration

Please review the issue and let me know if you'd like any adjustments to the description or proposed solution.

xgopilot[bot] avatar Nov 17 '25 23:11 xgopilot[bot]