[Diagnostics] Port name shadowing diagnostics

Diagnose an attempt to reference a top-level name shadowed by
a local member e.g.

```swift
extension Sequence {
  func test() -> Int {
    return max(1, 2)
  }
}
```

Here `min` refers to a global function `min<T>(_: T, _: T)` in `Swift`
module and can only be accessed by adding `Swift.` to it, because `Sequence`
has a member named `min` which accepts a single argument.
This commit is contained in:
Pavel Yaskevich
2020-01-03 20:31:17 -08:00
parent 7351bfc86f
commit c9c20afe27
4 changed files with 73 additions and 8 deletions

View File

@@ -6137,3 +6137,45 @@ bool UnableToInferProtocolLiteralType::diagnoseAsError() {
return true;
}
bool MissingQuialifierInMemberRefFailure::diagnoseAsError() {
auto selectedOverload = getOverloadChoiceIfAvailable(getLocator());
if (!selectedOverload)
return false;
auto *UDE = cast<UnresolvedDotExpr>(getRawAnchor());
auto baseType = getType(UDE->getBase());
auto methodKind = baseType->isAnyExistentialType()
? DescriptiveDeclKind::StaticMethod
: DescriptiveDeclKind::Method;
auto choice = selectedOverload->choice.getDeclOrNull();
if (!choice)
return false;
auto *DC = choice->getDeclContext();
if (!(DC->isModuleContext() || DC->isModuleScopeContext())) {
emitDiagnostic(UDE->getLoc(), diag::member_shadows_function, UDE->getName(),
methodKind, choice->getDescriptiveKind(),
choice->getFullName());
return true;
}
auto qualifier = DC->getParentModule()->getName();
emitDiagnostic(UDE->getLoc(), diag::member_shadows_global_function,
UDE->getName(), methodKind, choice->getDescriptiveKind(),
choice->getFullName(), qualifier);
SmallString<32> namePlusDot = qualifier.str();
namePlusDot.push_back('.');
emitDiagnostic(UDE->getLoc(), diag::fix_unqualified_access_top_level_multi,
namePlusDot, choice->getDescriptiveKind(), qualifier)
.fixItInsert(UDE->getStartLoc(), namePlusDot);
emitDiagnostic(choice, diag::decl_declared_here, choice->getFullName());
return true;
}