Skip to content

Commit 37774eb

Browse files
authored
Fix the TypeChecker's omitNeedlessWords to use interface types. (#7193)
...avoiding a crash when trying to detect near misses of protocol requirements. Unfortunately I can't come up with a test case for the VarDecl changes; everything I try seems to already work. But using interface types is more correct anyway. https://bugs.swift.org/browse/SR-3812
1 parent ac34369 commit 37774eb

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3594,7 +3594,7 @@ Optional<DeclName> TypeChecker::omitNeedlessWords(AbstractFunctionDecl *afd) {
35943594

35953595
// Always look at the parameters in the last parameter list.
35963596
for (auto param : *afd->getParameterLists().back()) {
3597-
paramTypes.push_back(getTypeNameForOmission(param->getType())
3597+
paramTypes.push_back(getTypeNameForOmission(param->getInterfaceType())
35983598
.withDefaultArgument(param->isDefaultArgument()));
35993599
}
36003600

@@ -3662,10 +3662,10 @@ Optional<DeclName> TypeChecker::omitNeedlessWords(AbstractFunctionDecl *afd) {
36623662
Optional<Identifier> TypeChecker::omitNeedlessWords(VarDecl *var) {
36633663
auto &Context = var->getASTContext();
36643664

3665-
if (!var->hasType())
3665+
if (!var->hasInterfaceType())
36663666
validateDecl(var);
36673667

3668-
if (var->isInvalid() || !var->hasType())
3668+
if (var->isInvalid() || !var->hasInterfaceType())
36693669
return None;
36703670

36713671
if (var->getName().empty())
@@ -3696,7 +3696,7 @@ Optional<Identifier> TypeChecker::omitNeedlessWords(VarDecl *var) {
36963696

36973697
// Omit needless words.
36983698
StringScratchSpace scratch;
3699-
OmissionTypeName typeName = getTypeNameForOmission(var->getType());
3699+
OmissionTypeName typeName = getTypeNameForOmission(var->getInterfaceType());
37003700
OmissionTypeName contextTypeName = getTypeNameForOmission(contextType);
37013701
if (::omitNeedlessWords(name, { }, "", typeName, contextTypeName, { },
37023702
/*returnsSelf=*/false, true, allPropertyNames,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %target-swift-frontend -emit-module -D LIB %s -o %t/Lib.swiftmodule
3+
// RUN: %target-swift-frontend -I %t -typecheck %s -verify
4+
// REQUIRES: objc_interop
5+
6+
#if LIB
7+
8+
import Foundation
9+
10+
@objc public protocol Proto {
11+
@objc optional func method(_: Int, for object: NSObject, dividing double: Double)
12+
}
13+
14+
#else
15+
16+
import Foundation
17+
import Lib
18+
19+
class Impl: Proto {
20+
func methodWithInt(_: Int, forObject object: NSObject, dividingDouble: Double) { }
21+
// expected-warning@-1 {{instance method 'methodWithInt(_:forObject:dividingDouble:)' nearly matches optional requirement 'method(_:for:dividing:)' of protocol 'Proto'}}
22+
// expected-note@-2{{rename to 'method(_:for:dividing:)' to satisfy this requirement}}{{8-21=method}}{{30-39=for}}{{58-58=dividing }}{{none}}
23+
// expected-note@-3{{move 'methodWithInt(_:forObject:dividingDouble:)' to an extension to silence this warning}}
24+
// expected-note@-4{{make 'methodWithInt(_:forObject:dividingDouble:)' private to silence this warning}}{{3-3=private }}
25+
}
26+
27+
#endif

0 commit comments

Comments
 (0)