2366 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { |
2366 void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { |
2367 ClashFilter cf = new ClashFilter(site); |
2367 ClashFilter cf = new ClashFilter(site); |
2368 //for each method m1 that is overridden (directly or indirectly) |
2368 //for each method m1 that is overridden (directly or indirectly) |
2369 //by method 'sym' in 'site'... |
2369 //by method 'sym' in 'site'... |
2370 for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { |
2370 for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { |
2371 if (!sym.overrides(m1, site.tsym, types, false)) continue; |
2371 if (!sym.overrides(m1, site.tsym, types, false)) { |
|
2372 checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)m1); |
|
2373 continue; |
|
2374 } |
2372 //...check each method m2 that is a member of 'site' |
2375 //...check each method m2 that is a member of 'site' |
2373 for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { |
2376 for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { |
2374 if (m2 == m1) continue; |
2377 if (m2 == m1) continue; |
2375 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as |
2378 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as |
2376 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error |
2379 //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error |
2404 ClashFilter cf = new ClashFilter(site); |
2407 ClashFilter cf = new ClashFilter(site); |
2405 //for each method m1 that is a member of 'site'... |
2408 //for each method m1 that is a member of 'site'... |
2406 for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) { |
2409 for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) { |
2407 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as |
2410 //if (i) the signature of 'sym' is not a subsignature of m1 (seen as |
2408 //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error |
2411 //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error |
2409 if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) && |
2412 if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) { |
2410 types.hasSameArgs(s.erasure(types), sym.erasure(types))) { |
2413 if (types.hasSameArgs(s.erasure(types), sym.erasure(types))) { |
2411 log.error(pos, |
2414 log.error(pos, |
2412 "name.clash.same.erasure.no.hide", |
2415 "name.clash.same.erasure.no.hide", |
2413 sym, sym.location(), |
2416 sym, sym.location(), |
2414 s, s.location()); |
2417 s, s.location()); |
2415 return; |
2418 return; |
2416 } |
2419 } else { |
|
2420 checkPotentiallyAmbiguousOverloads(pos, site, sym, (MethodSymbol)s); |
|
2421 } |
|
2422 } |
2417 } |
2423 } |
2418 } |
2424 } |
2419 |
2425 |
2420 //where |
2426 //where |
2421 private class ClashFilter implements Filter<Symbol> { |
2427 private class ClashFilter implements Filter<Symbol> { |
2494 s.isInheritedIn(site.tsym, types) && |
2500 s.isInheritedIn(site.tsym, types) && |
2495 !s.isConstructor(); |
2501 !s.isConstructor(); |
2496 } |
2502 } |
2497 } |
2503 } |
2498 |
2504 |
|
2505 /** |
|
2506 * Report warnings for potentially ambiguous method declarations. Two declarations |
|
2507 * are potentially ambiguous if they feature two unrelated functional interface |
|
2508 * in same argument position (in which case, a call site passing an implicit |
|
2509 * lambda would be ambiguous). |
|
2510 */ |
|
2511 void checkPotentiallyAmbiguousOverloads(DiagnosticPosition pos, Type site, |
|
2512 MethodSymbol msym1, MethodSymbol msym2) { |
|
2513 if (msym1 != msym2 && |
|
2514 allowDefaultMethods && |
|
2515 lint.isEnabled(LintCategory.OVERLOADS) && |
|
2516 (msym1.flags() & POTENTIALLY_AMBIGUOUS) == 0 && |
|
2517 (msym2.flags() & POTENTIALLY_AMBIGUOUS) == 0) { |
|
2518 Type mt1 = types.memberType(site, msym1); |
|
2519 Type mt2 = types.memberType(site, msym2); |
|
2520 //if both generic methods, adjust type variables |
|
2521 if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL) && |
|
2522 types.hasSameBounds((ForAll)mt1, (ForAll)mt2)) { |
|
2523 mt2 = types.subst(mt2, ((ForAll)mt2).tvars, ((ForAll)mt1).tvars); |
|
2524 } |
|
2525 //expand varargs methods if needed |
|
2526 int maxLength = Math.max(mt1.getParameterTypes().length(), mt2.getParameterTypes().length()); |
|
2527 List<Type> args1 = rs.adjustArgs(mt1.getParameterTypes(), msym1, maxLength, true); |
|
2528 List<Type> args2 = rs.adjustArgs(mt2.getParameterTypes(), msym2, maxLength, true); |
|
2529 //if arities don't match, exit |
|
2530 if (args1.length() != args2.length()) return; |
|
2531 boolean potentiallyAmbiguous = false; |
|
2532 while (args1.nonEmpty() && args2.nonEmpty()) { |
|
2533 Type s = args1.head; |
|
2534 Type t = args2.head; |
|
2535 if (!types.isSubtype(t, s) && !types.isSubtype(s, t)) { |
|
2536 if (types.isFunctionalInterface(s) && types.isFunctionalInterface(t) && |
|
2537 types.findDescriptorType(s).getParameterTypes().length() > 0 && |
|
2538 types.findDescriptorType(s).getParameterTypes().length() == |
|
2539 types.findDescriptorType(t).getParameterTypes().length()) { |
|
2540 potentiallyAmbiguous = true; |
|
2541 } else { |
|
2542 break; |
|
2543 } |
|
2544 } |
|
2545 args1 = args1.tail; |
|
2546 args2 = args2.tail; |
|
2547 } |
|
2548 if (potentiallyAmbiguous) { |
|
2549 //we found two incompatible functional interfaces with same arity |
|
2550 //this means a call site passing an implicit lambda would be ambigiuous |
|
2551 msym1.flags_field |= POTENTIALLY_AMBIGUOUS; |
|
2552 msym2.flags_field |= POTENTIALLY_AMBIGUOUS; |
|
2553 log.warning(LintCategory.OVERLOADS, pos, "potentially.ambiguous.overload", |
|
2554 msym1, msym1.location(), |
|
2555 msym2, msym2.location()); |
|
2556 return; |
|
2557 } |
|
2558 } |
|
2559 } |
|
2560 |
2499 /** Report a conflict between a user symbol and a synthetic symbol. |
2561 /** Report a conflict between a user symbol and a synthetic symbol. |
2500 */ |
2562 */ |
2501 private void syntheticError(DiagnosticPosition pos, Symbol sym) { |
2563 private void syntheticError(DiagnosticPosition pos, Symbol sym) { |
2502 if (!sym.type.isErroneous()) { |
2564 if (!sym.type.isErroneous()) { |
2503 if (warnOnSyntheticConflicts) { |
2565 if (warnOnSyntheticConflicts) { |