Skip to content

Commit 4c545f1

Browse files
committed
Fix issue with some std::unordered_map implementations
We currently don't adhere to the restriction that if two items are equal to each other, their hashes must be the same too. This comes from the issue that unitless numbers compare equal to the same number even if they have units.
1 parent 8d312a1 commit 4c545f1

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

src/ast.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ namespace Sass {
358358
class Hashed {
359359
private:
360360
std::unordered_map<
361-
K, T, ObjHash, ObjEquality
361+
K, T, ObjHash, ObjHashEquality
362362
> elements_;
363363

364364
sass::vector<K> _keys;
@@ -396,7 +396,7 @@ namespace Sass {
396396
bool has_duplicate_key() const { return duplicate_key_ != nullptr; }
397397
K get_duplicate_key() const { return duplicate_key_; }
398398
const std::unordered_map<
399-
K, T, ObjHash, ObjEquality
399+
K, T, ObjHash, ObjHashEquality
400400
>& elements() { return elements_; }
401401
Hashed& operator<<(std::pair<K, T> p)
402402
{
@@ -432,7 +432,7 @@ namespace Sass {
432432
return *this;
433433
}
434434
const std::unordered_map<
435-
K, T, ObjHash, ObjEquality
435+
K, T, ObjHash, ObjHashEquality
436436
>& pairs() const { return elements_; }
437437

438438
const sass::vector<K>& keys() const { return _keys; }

src/ast_helpers.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,30 @@ namespace Sass {
149149
}
150150
};
151151

152+
// ###########################################################################
153+
// Special compare function only for hashes.
154+
// We need to make sure to not have objects equal that
155+
// have different hashes. This is currently an issue,
156+
// since `1px` is equal to `1` but have different hashes.
157+
// This goes away once we remove unitless equality.
158+
// ###########################################################################
159+
160+
template <class T>
161+
// Compare the objects and its hashes
162+
bool ObjHashEqualityFn(const T& lhs, const T& rhs) {
163+
if (lhs == nullptr) return rhs == nullptr;
164+
else if (rhs == nullptr) return false;
165+
else return lhs->hash() == rhs->hash();
166+
}
167+
struct ObjHashEquality {
168+
template <class T>
169+
// Compare the objects and its contents and hashes
170+
bool operator() (const T& lhs, const T& rhs) const {
171+
return ObjEqualityFn<T>(lhs, rhs) &&
172+
ObjHashEqualityFn(lhs, rhs);
173+
}
174+
};
175+
152176
// ###########################################################################
153177
// Implement ordering operations for AST Nodes
154178
// ###########################################################################

0 commit comments

Comments
 (0)