Skip to content

[test] Add a couple of tests #39481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions test/Constraints/dynamic_lookup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ let _: DynamicIUO = o[dyn_iuo]!
let _: DynamicIUO = o[dyn_iuo]!!
let _: DynamicIUO? = o[dyn_iuo]
// FIXME: These should all produce lvalues that we can write through
o.t = s // expected-error {{cannot assign to property: 'o' is immutable}}
o.t! = s // expected-error {{cannot assign through '!': 'o' is immutable}}
o.t!! = s // expected-error {{cannot assign through '!': 'o' is immutable}}
o[dyn_iuo] = dyn_iuo // expected-error {{cannot assign through subscript: 'o' is immutable}}
o[dyn_iuo]! = dyn_iuo // expected-error {{cannot assign through '!': 'o' is immutable}}
o[dyn_iuo]!! = dyn_iuo // expected-error {{cannot assign through '!': 'o' is immutable}}
Expand Down Expand Up @@ -450,3 +453,10 @@ func test_dynamic_subscript_accepts_type_name_argument() {
// expected-note@-2 {{use '.self' to reference the type object}} {{20-20=.self}}
}
}

func testAnyObjectConstruction(_ x: AnyObject) {
AnyObject() // expected-error {{protocol type 'AnyObject' cannot be instantiated}}

// FIXME(SR-15210): This should also be rejected.
_ = type(of: x).init()
}
4 changes: 4 additions & 0 deletions test/Constraints/iuo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,7 @@ func rdar83352038() {
return foo(cnode)
}
}

// Make sure we reject an attempt at a function conversion.
func returnsIUO() -> Int! { 0 }
let _ = (returnsIUO as () -> Int)() // expected-error {{cannot convert value of type '() -> Int?' to type '() -> Int' in coercion}}
74 changes: 74 additions & 0 deletions test/Constraints/ranking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,80 @@ extension X where Self : GenericClass<String> {
}
}

//--------------------------------------------------------------------
// Constructor-specific ranking
//--------------------------------------------------------------------

// We have a special ranking rule that only currently applies to constructors,
// and compares the concrete parameter types.

protocol Q {
init()
}

struct S1<T : Q> {
// We want to prefer the non-optional init over the optional init here.
init(_ x: T = .init()) {}
init(_ x: T? = nil) {}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking2S1V11testRankingACyxGyt_tcfC
init(testRanking: Void) {
// CHECK: function_ref @$s7ranking2S1VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in τ_0_0, @thin S1<τ_0_0>.Type) -> S1<τ_0_0>
self.init()
}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking2S1V15testInitRankingyyF
func testInitRanking() {
// CHECK: function_ref @$s7ranking2S1VyACyxGxcfC : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in τ_0_0, @thin S1<τ_0_0>.Type) -> S1<τ_0_0>
_ = S1<T>()
}
}

protocol R {}
extension Array : R {}
extension Int : R {}

struct S2 {
init(_ x: R) {}
init(_ x: Int...) {}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking2S2V15testInitRankingyyF
func testInitRanking() {
// We currently prefer the non-variadic init due to having
// "less effective parameters", and we don't compare the types for ranking due
// to the difference in variadic-ness.
// CHECK: function_ref @$s7ranking2S2VyAcA1R_pcfC : $@convention(method) (@in R, @thin S2.Type) -> S2
_ = S2(0)
}
}

// Very cursed: As a holdover from how we used to represent function inputs,
// we rank these as tuples and consider (x:x:) to be a subtype of (x:y:). Seems
// unlikely this is being relied on in the real world, but let's at least have
// it as a test case to track its behavior.
struct S3 {
init(x _: Int = 0, y _: Int = 0) {}
init(x _: Int = 0, x _: Int = 0) {}

func testInitRanking() {
// CHECK: function_ref @$s7ranking2S3V1xAdCSi_SitcfC : $@convention(method) (Int, Int, @thin S3.Type) -> S3
_ = S3()
}
}

// Also another consequence of having ranked as tuples: we prefer the unlabeled
// init here.
struct S4 {
init(x: Int = 0, y: Int = 0) {}
init(_ x: Int = 0, _ y: Int = 0) {}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking2S4V15testInitRankingyyF
func testInitRanking() {
// CHECK: function_ref @$s7ranking2S4VyACSi_SitcfC : $@convention(method) (Int, Int, @thin S4.Type) -> S4
_ = S4()
}
}

//--------------------------------------------------------------------
// Pointer conversions
//--------------------------------------------------------------------
Expand Down
27 changes: 27 additions & 0 deletions test/Constraints/ranking_ambiguities.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: %target-typecheck-verify-swift

// We have a special ranking rule that only currently applies to constructors,
// and compares the concrete parameter types.

protocol P {
init()
}

// We currently only apply the constructor ranking rule to X() and not X.init().
struct S<T : P> {
init(_ x: T = .init()) {} // expected-note {{found this candidate}}
init(_ x: T? = nil) {} // expected-note {{found this candidate}}
func testInitRanking() {
_ = S<T>() // Okay
_ = S<T>.init() // expected-error {{ambiguous use of 'init(_:)'}}
}
}
struct S1 {
init(x: Int = 0, y: Int = 0) {} // expected-note {{found this candidate}}
init(_ x: Int = 0, _ y: Int = 0) {} // expected-note {{found this candidate}}

func testInitRanking() {
_ = S1() // Okay
_ = S1.init() // expected-error {{ambiguous use of 'init'}}
}
}