From 324411a44b6be1d46cfe02a2bcbba5a94afc23a8 Mon Sep 17 00:00:00 2001 From: David Farler Date: Mon, 8 Dec 2014 23:09:04 +0000 Subject: [PATCH] Don't trap when creating a Set from a literal with duplicate elements rdar://problem/19178760 Swift SVN r23791 --- stdlib/core/HashedCollections.swift.gyb | 9 ++++-- test/1_stdlib/Set.swift | 37 ++++++++++++++++--------- test/1_stdlib/SetTraps.swift | 18 ------------ 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/stdlib/core/HashedCollections.swift.gyb b/stdlib/core/HashedCollections.swift.gyb index b88f82265c7..6f88f46edf2 100644 --- a/stdlib/core/HashedCollections.swift.gyb +++ b/stdlib/core/HashedCollections.swift.gyb @@ -1882,11 +1882,16 @@ internal struct _Native${Self}Storage<${TypeParametersDecl}> : %if Self == 'Set': + var count = 0 for key in elements { var (i, found) = nativeStorage._find(key, nativeStorage._bucket(key)) - _precondition(!found, "${Self} literal contains duplicate keys") + if found { + continue + } nativeStorage[i.offset] = Element(key: key) + ++count } + nativeStorage.count = count %elif Self == 'Dictionary': @@ -1895,10 +1900,10 @@ internal struct _Native${Self}Storage<${TypeParametersDecl}> : _precondition(!found, "${Self} literal contains duplicate keys") nativeStorage[i.offset] = Element(key: key, value: value) } + nativeStorage.count = elements.count %end - nativeStorage.count = elements.count return nativeStorage } } diff --git a/test/1_stdlib/Set.swift b/test/1_stdlib/Set.swift index fef768ee3b1..87278c87fda 100644 --- a/test/1_stdlib/Set.swift +++ b/test/1_stdlib/Set.swift @@ -2422,20 +2422,31 @@ SetTestSuite.test("SetBridgeFromObjectiveCConditional") { // Public API SetTestSuite.test("init(SequenceType:)") { - let s1 = Set([1010, 2020, 3030]) - var s2 = Set() - s2.insert(1010) - s2.insert(2020) - s2.insert(3030) - expectEqual(s1, s2) + let s1 = Set([1010, 2020, 3030]) + var s2 = Set() + s2.insert(1010) + s2.insert(2020) + s2.insert(3030) + expectEqual(s1, s2) - // Test the uniquing capabilities of a set - let s3 = Set([ - 1010, 1010, 1010, 1010, 1010, 1010, - 1010, 1010, 1010, 1010, 1010, 1010, - 2020, 2020, 2020, 3030, 3030, 3030 - ]) - expectEqual(s1, s3) + // Test the uniquing capabilities of a set + let s3 = Set([ + 1010, 1010, 1010, 1010, 1010, 1010, + 1010, 1010, 1010, 1010, 1010, 1010, + 2020, 2020, 2020, 3030, 3030, 3030 + ]) + expectEqual(s1, s3) +} + +SetTestSuite.test("init(arrayLiteral:)") { + let s1: Set = [1010, 2020, 3030, 1010, 2020, 3030] + let s2 = Set([1010, 2020, 3030]) + var s3 = Set() + s3.insert(1010) + s3.insert(2020) + s3.insert(3030) + expectEqual(s1, s2) + expectEqual(s2, s3) } SetTestSuite.test("isSubsetOf.Set.Set") { diff --git a/test/1_stdlib/SetTraps.swift b/test/1_stdlib/SetTraps.swift index d89dec1440c..8ea70e19640 100644 --- a/test/1_stdlib/SetTraps.swift +++ b/test/1_stdlib/SetTraps.swift @@ -3,9 +3,6 @@ // RUN: xcrun -sdk %target-sdk-name clang++ -arch %target-cpu %S/Inputs/CatchCrashes.cpp -c -o %t/CatchCrashes.o // RUN: %target-build-swift %s -Xlinker %t/CatchCrashes.o -o %t/a.out // -// RUN: %target-run %t/a.out DuplicateKeys1 2>&1 | FileCheck %s -check-prefix=CHECK -// RUN: %target-run %t/a.out DuplicateKeys2 2>&1 | FileCheck %s -check-prefix=CHECK -// RUN: %target-run %t/a.out DuplicateKeys3 2>&1 | FileCheck %s -check-prefix=CHECK // RUN: %target-run %t/a.out RemoveInvalidIndex1 2>&1 | FileCheck %s -check-prefix=CHECK // RUN: %target-run %t/a.out RemoveInvalidIndex2 2>&1 | FileCheck %s -check-prefix=CHECK // RUN: %target-run %t/a.out RemoveInvalidIndex3 2>&1 | FileCheck %s -check-prefix=CHECK @@ -72,21 +69,6 @@ if true { var nss: NSSet = s } -if arg == "DuplicateKeys1" { - println("OK") - let s: Set = [10, 20, 30, 10] -} - -if arg == "DuplicateKeys2" { - println("OK") - let s: Set = [10, 20, 30, 10] -} - -if arg == "DuplicateKeys3" { - println("OK") - var s: Set = [10, 10] -} - if arg == "RemoveInvalidIndex1" { var s = Set() let index = s.startIndex