1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
2 // Source: ../../cmd/compile/internal/types2/errsupport.go
3 4 // Copyright 2024 The Go Authors. All rights reserved.
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file.
7 8 // This file implements support functions for error messages.
9 10 package types
11 12 // lookupError returns a case-specific error when a lookup of selector sel in the
13 // given type fails but an object with alternative spelling (case folding) is found.
14 // If structLit is set, the error message is specifically for struct literal fields.
15 func (check *Checker) lookupError(typ Type, sel string, obj Object, structLit bool) string {
16 // Provide more detail if there is an unexported object, or one with different capitalization.
17 // If selector and object are in the same package (==), export doesn't matter, otherwise (!=) it does.
18 // Messages depend on whether it's a general lookup or a field lookup in a struct literal.
19 //
20 // case sel pkg have message (examples for general lookup)
21 // ---------------------------------------------------------------------------------------------------------
22 // ok x.Foo == Foo
23 // misspelled x.Foo == FoO type X has no field or method Foo, but does have field FoO
24 // misspelled x.Foo == foo type X has no field or method Foo, but does have field foo
25 // misspelled x.Foo == foO type X has no field or method Foo, but does have field foO
26 //
27 // misspelled x.foo == Foo type X has no field or method foo, but does have field Foo
28 // misspelled x.foo == FoO type X has no field or method foo, but does have field FoO
29 // ok x.foo == foo
30 // misspelled x.foo == foO type X has no field or method foo, but does have field foO
31 //
32 // ok x.Foo != Foo
33 // misspelled x.Foo != FoO type X has no field or method Foo, but does have field FoO
34 // unexported x.Foo != foo type X has no field or method Foo, but does have unexported field foo
35 // missing x.Foo != foO type X has no field or method Foo
36 //
37 // misspelled x.foo != Foo type X has no field or method foo, but does have field Foo
38 // missing x.foo != FoO type X has no field or method foo
39 // inaccessible x.foo != foo cannot refer to unexported field foo
40 // missing x.foo != foO type X has no field or method foo
41 42 const (
43 ok = iota
44 missing // no object found
45 misspelled // found object with different spelling
46 unexported // found object with name differing only in first letter
47 inaccessible // found object with matching name but inaccessible from the current package
48 )
49 50 // determine case
51 e := missing
52 var alt string // alternative spelling of selector; if any
53 if obj != nil {
54 alt = obj.Name()
55 if obj.Pkg() == check.pkg {
56 assert(alt != sel) // otherwise there is no lookup error
57 e = misspelled
58 } else if isExported(sel) {
59 if isExported(alt) {
60 e = misspelled
61 } else if tail(sel) == tail(alt) {
62 e = unexported
63 }
64 } else if isExported(alt) {
65 if tail(sel) == tail(alt) {
66 e = misspelled
67 }
68 } else if sel == alt {
69 e = inaccessible
70 }
71 }
72 73 if structLit {
74 switch e {
75 case missing:
76 return check.sprintf("unknown field %s in struct literal of type %s", sel, typ)
77 case misspelled:
78 return check.sprintf("unknown field %s in struct literal of type %s, but does have %s", sel, typ, alt)
79 case unexported:
80 return check.sprintf("unknown field %s in struct literal of type %s, but does have unexported %s", sel, typ, alt)
81 case inaccessible:
82 return check.sprintf("cannot refer to unexported field %s in struct literal of type %s", alt, typ)
83 }
84 } else {
85 what := "object"
86 switch obj.(type) {
87 case *Var:
88 what = "field"
89 case *Func:
90 what = "method"
91 }
92 switch e {
93 case missing:
94 return check.sprintf("type %s has no field or method %s", typ, sel)
95 case misspelled:
96 return check.sprintf("type %s has no field or method %s, but does have %s %s", typ, sel, what, alt)
97 case unexported:
98 return check.sprintf("type %s has no field or method %s, but does have unexported %s %s", typ, sel, what, alt)
99 case inaccessible:
100 return check.sprintf("cannot refer to unexported %s %s", what, alt)
101 }
102 }
103 104 panic("unreachable")
105 }
106 107 // tail returns the string s without its first (UTF-8) character.
108 // If len(s) == 0, the result is s.
109 func tail(s string) string {
110 for i, _ := range s {
111 if i > 0 {
112 return s[i:]
113 }
114 }
115 return s
116 }
117