Skip to content

Commit 19f72c8

Browse files
committed
ClangImporter: Fix diagnostics for NS* prefix stripping from generic types
We were failing to create an unavailable TypeAlias for the old name in the case the renamed type was generic, leading to poor diagnostics. Also, Sema resolves generic TypeAliases very early, while building a Type from a TypeRepr -- this means the unavailable/deprecated check runs too late to catch generic TypeAlises. Add a hack where we preserve a reference to the original TypeAliasDecl by way of constructing a SubstitutedType which desugars to the replacement type, rather than resolving the replacement type directly, so that the availability check can pick it up. A better fix for this would be to introduce a BoundGenericAliasType sugared type, but that's a bigger change that can come later. Fixes <rdar://problem/26206263>.
1 parent abc42b4 commit 19f72c8

File tree

6 files changed

+39
-7
lines changed

6 files changed

+39
-7
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,10 +1311,19 @@ namespace {
13111311
auto typeDecl = dyn_cast_or_null<TypeDecl>(importedDecl);
13121312
if (!typeDecl) return nullptr;
13131313

1314-
// FIXME: We cannot currently handle generic types.
1314+
// Handle generic types.
1315+
GenericParamList *genericParams = nullptr;
1316+
GenericSignature *genericSig = nullptr;
1317+
auto underlyingType = typeDecl->getDeclaredInterfaceType();
1318+
13151319
if (auto generic = dyn_cast<GenericTypeDecl>(typeDecl)) {
1316-
if (generic->getGenericSignature() && !isa<ProtocolDecl>(typeDecl))
1317-
return nullptr;
1320+
if (generic->getGenericSignature() && !isa<ProtocolDecl>(typeDecl)) {
1321+
genericParams = generic->getGenericParams();
1322+
genericSig = generic->getGenericSignature();
1323+
1324+
underlyingType = ArchetypeBuilder::mapTypeIntoContext(
1325+
generic, underlyingType);
1326+
}
13181327
}
13191328

13201329
// Import the declaration context where this name will go. Note that
@@ -1326,15 +1335,15 @@ namespace {
13261335
if (!dc) return nullptr;
13271336

13281337
// Create the type alias.
1329-
auto underlyingType = typeDecl->getDeclaredInterfaceType();
13301338
auto alias = Impl.createDeclWithClangNode<TypeAliasDecl>(
13311339
decl,
13321340
Impl.importSourceLoc(decl->getLocStart()),
13331341
swift2Name.Imported.getBaseName(),
13341342
Impl.importSourceLoc(decl->getLocation()),
13351343
TypeLoc::withoutLoc(underlyingType),
1336-
/*genericparams*/nullptr, dc);
1344+
genericParams, dc);
13371345
alias->computeType();
1346+
alias->setGenericSignature(genericSig);
13381347

13391348
// Record that this is the Swift 2 version of this declaration.
13401349
Impl.ImportedDecls[{decl->getCanonicalDecl(), true}] = alias;

lib/Sema/ConstraintSystem.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,11 @@ namespace {
629629
arguments.push_back(TypeLoc::withoutLoc(
630630
replacements[gp->getCanonicalType()]));
631631
}
632-
632+
633+
// FIXME: For some reason we can end up with unbound->getDecl()
634+
// pointing at a generic TypeAliasDecl here. If we find a way to
635+
// handle generic TypeAliases elsewhere, this can just become a
636+
// call to BoundGenericType::get().
633637
return cs.TC.applyUnboundGenericArguments(unbound, SourceLoc(), cs.DC,
634638
arguments,
635639
/*isGenericSignature*/false,

lib/Sema/TypeCheckType.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,15 @@ Type TypeChecker::applyUnboundGenericArguments(
503503
subs.push_back(Substitution(t.getType(), {}));
504504

505505
auto subst = TAD->getGenericParams()->getSubstitutionMap(subs);
506-
return TAD->getUnderlyingType().subst(TAD->getParentModule(), subst, None);
506+
507+
// FIXME: return a SubstitutedType to preserve the fact that
508+
// we resolved a generic TypeAlias, for availability diagnostics.
509+
// A better fix might be to introduce a BoundGenericAliasType
510+
// which desugars as appropriate.
511+
return SubstitutedType::get(
512+
TAD->getDeclaredType(),
513+
TAD->getUnderlyingType().subst(TAD->getParentModule(), subst, None),
514+
Context);
507515
}
508516

509517
// Form the bound generic type.

test/ClangModules/swift2_warnings.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ func testOldTypeNames() {
1212

1313

1414
_ = NSPostingStyle(rawValue: 1) // expected-error{{'NSPostingStyle' has been renamed to 'PostingStyle'}}{{7-21=PostingStyle}}
15+
16+
_ = NSSoapDispenser<AnyObject>() // expected-error{{'NSSoapDispenser' has been renamed to 'SoapDispenser'}}{{7-22=SoapDispenser}}
1517
}
1618

1719
func testOldMethodNames(array: NSArray) {

test/Inputs/clang-importer-sdk/usr/include/Foundation.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,5 +1015,9 @@ extern NSString *NSHTTPRequestKey;
10151015
-(void)messageSomeObject:(nonnull id)object selector:(SEL)selector;
10161016
@end
10171017

1018+
@interface NSSoapDispenser<Fragrance> : NSObject
1019+
1020+
@end
1021+
10181022
#define NSTimeIntervalSince1970 978307200.0
10191023
#define NS_DO_SOMETHING 17

test/attr/attr_availability.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ extension MyCollection {
4242
func append(element: T) { } // expected-error {{'T' has been renamed to 'Element'}} {{24-25=Element}}
4343
}
4444

45+
@available(*, unavailable, renamed: "MyCollection")
46+
typealias YourCollection<Element> = MyCollection<Element> // expected-note {{'YourCollection' has been explicitly marked unavailable here}}
47+
48+
var x : YourCollection<Int> // expected-error {{'YourCollection' has been renamed to 'MyCollection'}}{{9-23=MyCollection}}
49+
4550
var x : int // expected-error {{'int' is unavailable: oh no you don't}}
4651
var y : float // expected-error {{'float' has been renamed to 'Float'}}{{9-14=Float}}
4752

0 commit comments

Comments
 (0)