Skip to content

Commit d48b620

Browse files
author
Nathan Hawes
committed
[ASTMangler] Fix USR generation/mangling crash in invalid code
In invalid code a decl may end up with an opened archetype type that the mangler doesn't expect. We still want to be able to generate a USR for these decls so that we can index and rename their occurences successfully. To allow this, this patch calls mapTypeOutOfContext on primary or opened archetype types prior to mangling. Resolves rdar://problem/54310026
1 parent 5ad5305 commit d48b620

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,29 +2356,34 @@ CanType ASTMangler::getDeclTypeForMangling(
23562356
}
23572357

23582358

2359-
CanType type = decl->getInterfaceType()
2360-
->getReferenceStorageReferent()
2361-
->getCanonicalType();
2362-
if (auto gft = dyn_cast<GenericFunctionType>(type)) {
2359+
Type type = decl->getInterfaceType()
2360+
->getReferenceStorageReferent();
2361+
if (type->hasArchetype()) {
2362+
assert(isa<ParamDecl>(decl) && "Only ParamDecl's still have archetypes");
2363+
type = type->mapTypeOutOfContext();
2364+
}
2365+
CanType canTy = type->getCanonicalType();
2366+
2367+
if (auto gft = dyn_cast<GenericFunctionType>(canTy)) {
23632368
genericSig = gft.getGenericSignature();
23642369
CurGenericSignature = gft.getGenericSignature();
23652370

2366-
type = CanFunctionType::get(gft.getParams(), gft.getResult(),
2367-
gft->getExtInfo());
2371+
canTy = CanFunctionType::get(gft.getParams(), gft.getResult(),
2372+
gft->getExtInfo());
23682373
}
23692374

2370-
if (!type->hasError()) {
2375+
if (!canTy->hasError()) {
23712376
// Shed the 'self' type and generic requirements from method manglings.
23722377
if (isMethodDecl(decl)) {
23732378
// Drop the Self argument clause from the type.
2374-
type = cast<AnyFunctionType>(type).getResult();
2379+
canTy = cast<AnyFunctionType>(canTy).getResult();
23752380
}
23762381

23772382
if (isMethodDecl(decl) || isa<SubscriptDecl>(decl))
23782383
parentGenericSig = decl->getDeclContext()->getGenericSignatureOfContext();
23792384
}
23802385

2381-
return type;
2386+
return canTy;
23822387
}
23832388

23842389
void ASTMangler::appendDeclType(const ValueDecl *decl, bool isFunctionMangling) {

test/Index/invalid_code.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck %s
1+
// RUN: %target-swift-ide-test -print-indexed-symbols -include-locals -source-filename %s | %FileCheck %s
22

33
// CHECK: [[@LINE+1]]:8 | struct/Swift | Int | {{.*}} | Ref | rel: 0
44
var _: Int { get { return 1 } }
@@ -37,3 +37,15 @@ public struct BadCollection: Collection {
3737
public func index(after index: Index) -> Index { }
3838
public subscript(position: Index) -> Element { }
3939
}
40+
41+
struct Protector<T> {}
42+
extension Protector where T: RangeReplaceableCollection {
43+
func append(_ newElement: T.Iterator.Element) {
44+
undefined { (foo: T) in
45+
// CHECK: [[@LINE-1]]:18 | param(local)/Swift | foo | {{.*}} | Def,RelChild
46+
// CHECK: [[@LINE-2]]:18 | function/acc-get(local)/Swift | getter:foo | {{.*}} | Def,Impl,RelChild,RelAcc
47+
// CHECK: [[@LINE-3]]:18 | function/acc-set(local)/Swift | setter:foo | {{.*}} | Def,Impl,RelChild,RelAcc
48+
_ = newElement
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)