@@ -111,12 +111,14 @@ func Build(c ir.Container, idx *Index, opts Options) (Plan, []diag.Diag) {
111111 diags = append (diags , emDiags ... )
112112
113113 r := & resolver {
114- idx : idx ,
115- inputs : inputs ,
116- overrides : overrides ,
117- embeds : embeds ,
118- stepByKey : map [string ]int {},
119- active : map [string ]bool {},
114+ idx : idx ,
115+ inputs : inputs ,
116+ overrides : overrides ,
117+ embeds : embeds ,
118+ stepByKey : map [string ]int {},
119+ active : map [string ]bool {},
120+ selfPkgPath : c .PkgPath ,
121+ selfFuncName : constructorName ,
120122 }
121123
122124 var outputs []Output
@@ -175,6 +177,15 @@ type resolver struct {
175177 steps []Step
176178 stepByKey map [string ]int
177179 active map [string ]bool
180+
181+ // selfPkgPath and selfFuncName identify this container's own
182+ // generated constructor. They are used to filter the by-type lookup
183+ // so a container whose `inject:"returns"` declares an interface that
184+ // matches an unrelated provider does not see its own previously
185+ // emitted constructor as a candidate (a self-loop that would also
186+ // produce a spurious "multiple providers" error).
187+ selfPkgPath string
188+ selfFuncName string
178189}
179190
180191// embedSource describes one exported field of an inject:"embed" input that
@@ -192,6 +203,24 @@ func (r *resolver) resolveField(f ir.Field) (int, []diag.Diag) {
192203 return r .resolveByType (f .Type , f .Pos , "field " + f .Name )
193204}
194205
206+ // excludeSelfProvider drops the container's own previously generated
207+ // constructor from the candidate list so a `inject:"returns"` field does
208+ // not pick itself up via type lookup. Callers that name a provider
209+ // explicitly via inject:"with=..." are not affected.
210+ func (r * resolver ) excludeSelfProvider (candidates []* ir.Provider ) []* ir.Provider {
211+ if r .selfFuncName == "" {
212+ return candidates
213+ }
214+ kept := candidates [:0 :0 ]
215+ for _ , c := range candidates {
216+ if c .PkgPath == r .selfPkgPath && c .FuncName == r .selfFuncName {
217+ continue
218+ }
219+ kept = append (kept , c )
220+ }
221+ return kept
222+ }
223+
195224func (r * resolver ) resolveByType (want types.Type , pos token.Position , parent string ) (int , []diag.Diag ) {
196225 tk := TypeKey (want )
197226
@@ -210,6 +239,7 @@ func (r *resolver) resolveByType(want types.Type, pos token.Position, parent str
210239 }
211240
212241 candidates := r .idx .LookupByType (want )
242+ candidates = r .excludeSelfProvider (candidates )
213243 if len (candidates ) == 0 {
214244 return - 1 , []diag.Diag {
215245 diag .Errorf (pos , "no provider for %s (required by %s)" , TypeString (want ), parent ),
0 commit comments