Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClangImporter: Fix diagnostics for NS* prefix stripping from generic types #2702

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 14 additions & 5 deletions lib/ClangImporter/ImportDecl.cpp
Expand Up @@ -1295,10 +1295,19 @@ namespace {
auto typeDecl = dyn_cast_or_null<TypeDecl>(importedDecl);
if (!typeDecl) return nullptr;

// FIXME: We cannot currently handle generic types.
// Handle generic types.
GenericParamList *genericParams = nullptr;
GenericSignature *genericSig = nullptr;
auto underlyingType = typeDecl->getDeclaredInterfaceType();

if (auto generic = dyn_cast<GenericTypeDecl>(typeDecl)) {
if (generic->getGenericSignature() && !isa<ProtocolDecl>(typeDecl))
return nullptr;
if (generic->getGenericSignature() && !isa<ProtocolDecl>(typeDecl)) {
genericParams = generic->getGenericParams();
genericSig = generic->getGenericSignature();

underlyingType = ArchetypeBuilder::mapTypeIntoContext(
generic, underlyingType);
}
}

// Import the declaration context where this name will go. Note that
Expand All @@ -1310,15 +1319,15 @@ namespace {
if (!dc) return nullptr;

// Create the type alias.
auto underlyingType = typeDecl->getDeclaredInterfaceType();
auto alias = Impl.createDeclWithClangNode<TypeAliasDecl>(
decl,
Impl.importSourceLoc(decl->getLocStart()),
swift2Name.Imported.getBaseName(),
Impl.importSourceLoc(decl->getLocation()),
TypeLoc::withoutLoc(underlyingType),
/*genericparams*/nullptr, dc);
genericParams, dc);
alias->computeType();
alias->setGenericSignature(genericSig);

// Record that this is the Swift 2 version of this declaration.
Impl.ImportedDecls[{decl->getCanonicalDecl(), true}] = alias;
Expand Down
6 changes: 5 additions & 1 deletion lib/Sema/ConstraintSystem.cpp
Expand Up @@ -629,7 +629,11 @@ namespace {
arguments.push_back(TypeLoc::withoutLoc(
replacements[gp->getCanonicalType()]));
}


// FIXME: For some reason we can end up with unbound->getDecl()
// pointing at a generic TypeAliasDecl here. If we find a way to
// handle generic TypeAliases elsewhere, this can just become a
// call to BoundGenericType::get().
return cs.TC.applyUnboundGenericArguments(unbound, SourceLoc(), cs.DC,
arguments,
/*isGenericSignature*/false,
Expand Down
10 changes: 9 additions & 1 deletion lib/Sema/TypeCheckType.cpp
Expand Up @@ -503,7 +503,15 @@ Type TypeChecker::applyUnboundGenericArguments(
subs.push_back(Substitution(t.getType(), {}));

auto subst = TAD->getGenericParams()->getSubstitutionMap(subs);
return TAD->getUnderlyingType().subst(TAD->getParentModule(), subst, None);

// FIXME: return a SubstitutedType to preserve the fact that
// we resolved a generic TypeAlias, for availability diagnostics.
// A better fix might be to introduce a BoundGenericAliasType
// which desugars as appropriate.
return SubstitutedType::get(
TAD->getDeclaredType(),
TAD->getUnderlyingType().subst(TAD->getParentModule(), subst, None),
Context);
}

// Form the bound generic type.
Expand Down
2 changes: 2 additions & 0 deletions test/ClangModules/swift2_warnings.swift
Expand Up @@ -12,6 +12,8 @@ func testOldTypeNames() {


_ = NSPostingStyle(rawValue: 1) // expected-error{{'NSPostingStyle' has been renamed to 'PostingStyle'}}{{7-21=PostingStyle}}

_ = NSSoapDispenser<AnyObject>() // expected-error{{'NSSoapDispenser' has been renamed to 'SoapDispenser'}}{{7-22=SoapDispenser}}
}

func testOldMethodNames(array: NSArray) {
Expand Down
4 changes: 4 additions & 0 deletions test/Inputs/clang-importer-sdk/usr/include/Foundation.h
Expand Up @@ -1015,5 +1015,9 @@ extern NSString *NSHTTPRequestKey;
-(void)messageSomeObject:(nonnull id)object selector:(SEL)selector;
@end

@interface NSSoapDispenser<Fragrance> : NSObject

@end

#define NSTimeIntervalSince1970 978307200.0
#define NS_DO_SOMETHING 17
5 changes: 5 additions & 0 deletions test/attr/attr_availability.swift
Expand Up @@ -42,6 +42,11 @@ extension MyCollection {
func append(element: T) { } // expected-error {{'T' has been renamed to 'Element'}} {{24-25=Element}}
}

@available(*, unavailable, renamed: "MyCollection")
typealias YourCollection<Element> = MyCollection<Element> // expected-note {{'YourCollection' has been explicitly marked unavailable here}}

var x : YourCollection<Int> // expected-error {{'YourCollection' has been renamed to 'MyCollection'}}{{9-23=MyCollection}}

var x : int // expected-error {{'int' is unavailable: oh no you don't}}
var y : float // expected-error {{'float' has been renamed to 'Float'}}{{9-14=Float}}

Expand Down