// isCompatible reports whether t and u are of compatible types. func isCompatible(t, u types.Type) bool { if types.Equal(t, u) { return true } if t, ok := t.(types.Numerical); ok { if u, ok := u.(types.Numerical); ok { // TODO: Check for other compatible types (e.g. pointers, array names, // strings). return t.IsNumerical() && u.IsNumerical() } } return false }
// isCompatibleArg reports whether the given call argument and function // parameter types are compatible. func isCompatibleArg(arg, param types.Type) bool { if isCompatible(arg, param) { return true } if arg, ok := arg.(*types.Array); ok { if param, ok := param.(*types.Array); ok { // TODO: Check for other compatible types (e.g. pointers, array names, // strings). if param.Len != 0 { return false } return types.Equal(arg.Elem, param.Elem) } } return false }
// Insert inserts the given declaration into the current scope. func (s *Scope) Insert(decl ast.Decl) error { // Early return for first-time declarations. ident := decl.Name() if ident == nil { // Anonymous function parameter declaration. return nil } name := ident.String() prev, ok := s.Decls[name] if !ok { s.Decls[name] = decl return nil } prevIdent := prev.Name() if prevIdent.NamePos == ident.NamePos { // Identifier already added to scope. return nil } // Previously declared. if !types.Equal(prev.Type(), decl.Type()) { return errors.Newf(ident.Start(), "redefinition of %q with type %q instead of %q", name, decl.Type(), prev.Type()) } // The last tentative definition becomes the definition, unless defined // explicitly (e.g. having an initializer or function body). if !s.IsDef(prev) { s.Decls[name] = decl return nil } // Definition already present in scope. if s.IsDef(decl) { // TODO: Consider adding support for multiple errors (and potentially // warnings and notifications). // // If support for notifications are added, add a note of the previous declaration. // errors.Notef(prevIdent.Start(), "previous definition of %q", name) return errors.Newf(ident.Start(), "redefinition of %q", name) } // Declaration of previously declared identifier. return nil }