code: Symbol findField(Env<AttrContext> env,
                       Type site,
                       Name name,
                       TypeSymbol c) {
          while (c.type.hasTag(TYPEVAR))
              c = c.type.getUpperBound().tsym;
          Symbol bestSoFar = varNotFound;
          Symbol sym;
          for (Symbol s : c.members().getSymbolsByName(name)) {
              if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
                  return isAccessible(env, site, s)
                      ? s : new AccessError(env, site, s);
              }
          }
          Type st = types.supertype(c.type);
          if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
              sym = findField(env, site, name, st.tsym);
              bestSoFar = bestOf(bestSoFar, sym);
          }
          for (List<Type> l = types.interfaces(c.type);
               bestSoFar.kind != AMBIGUOUS && l.nonEmpty();
               l = l.tail) {
              sym = findField(env, site, name, l.head.tsym);
              if (bestSoFar.exists() && sym.exists() &&
                  sym.owner != bestSoFar.owner)
                  bestSoFar = new AmbiguityError(bestSoFar, sym);
              else
                  bestSoFar = bestOf(bestSoFar, sym);
          }
          return bestSoFar;
      }
docs: Find field. Synthetic fields are always skipped.
  @param env     The current environment.
  @param site    The original type from where the selection takes place.
  @param name    The name of the field.
  @param c       The class to search for the field. This is always
  a superclass or implemented interface of site's class.