Skip to content

Commit

Permalink
Merge pull request swiftlang#59233 from hborla/archetype-printing
Browse files Browse the repository at this point in the history
[ASTPrinter] Simplify archetype printing by visiting the interface type.
  • Loading branch information
hborla authored Jun 2, 2022
2 parents 7c4b32f + 0ba655e commit 1997438
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 40 deletions.
62 changes: 24 additions & 38 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6289,8 +6289,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {

void visitOpenedArchetypeType(OpenedArchetypeType *T) {
if (auto parent = T->getParent()) {
visitParentType(parent);
printArchetypeCommon(T, getAbstractTypeParamDecl(T));
printArchetypeCommon(T);
return;
}

Expand All @@ -6299,8 +6298,20 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
visit(T->getExistentialType());
}

void printArchetypeCommon(ArchetypeType *T,
const AbstractTypeParamDecl *Decl) {
void printDependentMember(DependentMemberType *T) {
if (auto *const Assoc = T->getAssocType()) {
if (Options.ProtocolQualifiedDependentMemberTypes) {
Printer << "[";
Printer.printName(Assoc->getProtocol()->getName());
Printer << "]";
}
Printer.printTypeRef(T, Assoc, T->getName());
} else {
Printer.printName(T->getName());
}
}

void printArchetypeCommon(ArchetypeType *T) {
if (Options.AlternativeTypeNames) {
auto found = Options.AlternativeTypeNames->find(T->getCanonicalType());
if (found != Options.AlternativeTypeNames->end()) {
Expand All @@ -6309,36 +6320,22 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
}
}

const auto Name = T->getName();
if (Name.empty()) {
Printer << "<anonymous>";
} else if (Decl) {
Printer.printTypeRef(T, Decl, Name);
auto interfaceType = T->getInterfaceType();
if (auto *dependentMember = interfaceType->getAs<DependentMemberType>()) {
visitParentType(T->getParent());
printDependentMember(dependentMember);
} else {
Printer.printName(Name);
visit(interfaceType);
}
}

static AbstractTypeParamDecl *getAbstractTypeParamDecl(ArchetypeType *T) {
if (auto gp = T->getInterfaceType()->getAs<GenericTypeParamType>()) {
return gp->getDecl();
}

auto depMemTy = T->getInterfaceType()->castTo<DependentMemberType>();
return depMemTy->getAssocType();
}

void visitPrimaryArchetypeType(PrimaryArchetypeType *T) {
if (auto parent = T->getParent())
visitParentType(parent);

printArchetypeCommon(T, getAbstractTypeParamDecl(T));
printArchetypeCommon(T);
}

void visitOpaqueTypeArchetypeType(OpaqueTypeArchetypeType *T) {
if (auto parent = T->getParent()) {
visitParentType(parent);
printArchetypeCommon(T, getAbstractTypeParamDecl(T));
printArchetypeCommon(T);
return;
}

Expand Down Expand Up @@ -6415,9 +6412,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
}

void visitSequenceArchetypeType(SequenceArchetypeType *T) {
if (auto parent = T->getParent())
visitParentType(parent);
printArchetypeCommon(T, getAbstractTypeParamDecl(T));
printArchetypeCommon(T);
}

void visitGenericTypeParamType(GenericTypeParamType *T) {
Expand Down Expand Up @@ -6475,16 +6470,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {

void visitDependentMemberType(DependentMemberType *T) {
visitParentType(T->getBase());
if (auto *const Assoc = T->getAssocType()) {
if (Options.ProtocolQualifiedDependentMemberTypes) {
Printer << "[";
Printer.printName(Assoc->getProtocol()->getName());
Printer << "]";
}
Printer.printTypeRef(T, Assoc, T->getName());
} else {
Printer.printName(T->getName());
}
printDependentMember(T);
}

#define REF_STORAGE(Name, name, ...) \
Expand Down
6 changes: 6 additions & 0 deletions lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6242,6 +6242,12 @@ bool TypeBase::hasSimpleTypeRepr() const {
case TypeKind::OpenedArchetype:
return false;

case TypeKind::PrimaryArchetype: {
auto archetype = cast<const PrimaryArchetypeType>(this);
auto interface = archetype->getInterfaceType();
return interface->hasSimpleTypeRepr();
}

case TypeKind::ProtocolComposition: {
// 'Any', 'AnyObject' and single protocol compositions are simple
auto composition = cast<const ProtocolCompositionType>(this);
Expand Down
4 changes: 2 additions & 2 deletions test/Generics/opaque_archetype_concrete_requirement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct DefinesOpaqueP1 : P {
struct ConcreteHasP<T : P1, TT : P2, TU> {}

// CHECK-LABEL: ExtensionDecl line={{.*}} base=ConcreteHasP
// CHECK-NEXT: Generic signature: <T, TT, TU where T == some P1, TT == (some P1).T, TU == (some P1).U>
// CHECK-NEXT: Generic signature: <T, TT, TU where T == some P1, TT == (some P1).[P1]T, TU == (some P1).[P1]U>
extension ConcreteHasP where T == DefinesOpaqueP1.T, TT == T.T, TU == T.U {
func checkSameType1(_ t: TT) -> DefinesOpaqueP1.T.T { return t }
func checkSameType2(_ u: TU) -> DefinesOpaqueP1.T.U { return u }
Expand All @@ -47,7 +47,7 @@ protocol HasP {
}

// CHECK-LABEL: ExtensionDecl line={{.*}} base=HasP
// CHECK-NEXT: Generic signature: <Self where Self : HasP, Self.[HasP]T == some P1, Self.[HasP]U == G<(some P1).T>>
// CHECK-NEXT: Generic signature: <Self where Self : HasP, Self.[HasP]T == some P1, Self.[HasP]U == G<(some P1).[P1]T>>
extension HasP where T == DefinesOpaqueP1.T, U == G<T.T> {
func checkSameType1(_ t: T.T) -> DefinesOpaqueP1.T.T { return t }
func checkSameType2(_ u: T.U) -> DefinesOpaqueP1.T.U { return u }
Expand Down
8 changes: 8 additions & 0 deletions test/type/opaque_parameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ protocol Q {
associatedtype A: P & Equatable

func f() -> A
func takesA(_: A)
}

extension Int: P { }
Expand All @@ -16,17 +17,24 @@ extension Array: Q where Element: P, Element: Equatable {
func f() -> Element {
return first!
}

func takesA(_: Element) {}
}

extension Set: Q where Element: P, Element: Equatable { // expected-warning {{redundant conformance constraint 'Element' : 'Equatable'}}
func f() -> Element {
return first!
}

func takesA(_: Element) {}
}

// expected-note@+2{{where 'some Q' = 'Int'}}
// expected-note@+1{{in call to function 'takesQ'}}
func takesQ(_ q: some Q) -> Bool {
// expected-error@+1 {{cannot convert value of type 'Int' to expected argument type '(some Q).A'}}
q.takesA(1)

return q.f() == q.f()
}

Expand Down

0 comments on commit 1997438

Please sign in to comment.