From ff61b24b36ba828e3ef1551c826c8fe1c241bc87 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Mon, 15 Jun 2020 17:44:50 -0700 Subject: [PATCH 1/2] Remove Type's hash_value function Defining `hash_value` for `Type` makes it easy to forget that the underlying pointer is being hashed directly without canonicalization. Instead, define it only for `CanType`, and make `Type` users spell `getPointer` explicitly. --- include/swift/AST/Requirement.h | 2 +- include/swift/AST/Type.h | 9 ++++----- include/swift/AST/Witness.h | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/swift/AST/Requirement.h b/include/swift/AST/Requirement.h index c8b90bbc8b631..61a9c220dc544 100644 --- a/include/swift/AST/Requirement.h +++ b/include/swift/AST/Requirement.h @@ -142,7 +142,7 @@ class Requirement { case RequirementKind::Conformance: case RequirementKind::Superclass: case RequirementKind::SameType: - second = hash_value(requirement.getSecondType()); + second = hash_value(requirement.getSecondType().getPointer()); break; case RequirementKind::Layout: diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h index 1e9cf37b95fd9..3b0ac9c9d94f9 100644 --- a/include/swift/AST/Type.h +++ b/include/swift/AST/Type.h @@ -325,11 +325,6 @@ class Type { /// Return the name of the type as a string, for use in diagnostics only. std::string getString(const PrintOptions &PO = PrintOptions()) const; - friend llvm::hash_code hash_value(Type type) { - using llvm::hash_value; - return hash_value(type.getPointer()); - } - /// Return the name of the type, adding parens in cases where /// appending or prepending text to the result would cause that text /// to be appended to only a portion of the returned type. For @@ -502,6 +497,10 @@ class CanType : public Type { bool operator==(CanType T) const { return getPointer() == T.getPointer(); } bool operator!=(CanType T) const { return !operator==(T); } + friend llvm::hash_code hash_value(CanType T) { + return llvm::hash_value(T.getPointer()); + } + bool operator<(CanType T) const { return getPointer() < T.getPointer(); } }; diff --git a/include/swift/AST/Witness.h b/include/swift/AST/Witness.h index 4d72ae77ffd60..56747be0b8c2f 100644 --- a/include/swift/AST/Witness.h +++ b/include/swift/AST/Witness.h @@ -206,7 +206,7 @@ struct TypeWitnessAndDecl { } friend llvm::hash_code hash_value(const TypeWitnessAndDecl &owner) { - return llvm::hash_combine(owner.witnessType, + return llvm::hash_combine(owner.witnessType.getPointer(), owner.witnessDecl); } From 6041d2aa1b24c4ed39ed1ab60d770b414dd52096 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Mon, 15 Jun 2020 17:44:51 -0700 Subject: [PATCH 2/2] Fix equality of TypeWitnessAndDecl It was incorrectly hashing the type as a pointer but canonicalizing for equality. Change equality to compare pointers. --- include/swift/AST/Witness.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/swift/AST/Witness.h b/include/swift/AST/Witness.h index 56747be0b8c2f..18bc1e1879c3b 100644 --- a/include/swift/AST/Witness.h +++ b/include/swift/AST/Witness.h @@ -212,7 +212,7 @@ struct TypeWitnessAndDecl { friend bool operator==(const TypeWitnessAndDecl &lhs, const TypeWitnessAndDecl &rhs) { - return lhs.witnessType->isEqual(rhs.witnessType) && + return lhs.witnessType.getPointer() == rhs.witnessType.getPointer() && lhs.witnessDecl == rhs.witnessDecl; }