Source file src/go/types/errsupport.go
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