Skip to content

Commit 905a392

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents 2f5e641 + b60c826 commit 905a392

File tree

8 files changed

+138
-13
lines changed

8 files changed

+138
-13
lines changed

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2246,7 +2246,7 @@ namespace {
22462246
Type subPatternType = getTypeForPattern(
22472247
subPattern,
22482248
locator.withPathElement(LocatorPathElt::PatternMatch(subPattern)),
2249-
openedType, bindPatternVarsOneWay);
2249+
openedType, /*bindPatternVarsOneWay*/false);
22502250

22512251
if (!subPatternType)
22522252
return Type();

lib/Sema/ConstraintSystem.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3911,6 +3911,16 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
39113911
}
39123912
}
39133913

3914+
// If there either no fixes at all or all of the are warnings,
3915+
// let's diagnose this as regular ambiguity.
3916+
if (llvm::all_of(solutions, [](const Solution &solution) {
3917+
return llvm::all_of(solution.Fixes, [](const ConstraintFix *fix) {
3918+
return fix->isWarning();
3919+
});
3920+
})) {
3921+
return diagnoseAmbiguity(solutions);
3922+
}
3923+
39143924
// Algorithm is as follows:
39153925
//
39163926
// a. Aggregate all of the available fixes based on callee locator;

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,27 @@ bool WitnessChecker::findBestWitness(
13561356
}
13571357
}
13581358

1359+
// If there are multiple viable matches, drop any that are less available than the
1360+
// requirement.
1361+
if (numViable > 1) {
1362+
SmallVector<RequirementMatch, 2> checkedMatches;
1363+
bool foundCheckedMatch = false;
1364+
1365+
for (auto match : matches) {
1366+
if (!match.isViable()) {
1367+
checkedMatches.push_back(match);
1368+
} else if (checkWitness(requirement, match).Kind != CheckKind::Availability) {
1369+
foundCheckedMatch = true;
1370+
checkedMatches.push_back(match);
1371+
}
1372+
}
1373+
1374+
// If none of the matches were at least as available as the requirement, don't
1375+
// drop any of them; this will produce better diagnostics.
1376+
if (foundCheckedMatch)
1377+
std::swap(checkedMatches, matches);
1378+
}
1379+
13591380
if (numViable == 0) {
13601381
// Assume any missing value witnesses for a conformance in a module
13611382
// interface can be treated as opaque.

test/Sema/availability_versions.swift

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,7 @@ protocol ProtocolWithRequirementMentioningUnavailable {
13851385

13861386
protocol HasMethodF {
13871387
associatedtype T
1388-
func f(_ p: T) // expected-note 4{{protocol requirement here}}
1388+
func f(_ p: T) // expected-note 3{{protocol requirement here}}
13891389
}
13901390

13911391
class TriesToConformWithFunctionIntroducedOn10_51 : HasMethodF {
@@ -1499,17 +1499,14 @@ extension TakesClassAvailableOn10_51_B : HasTakesClassAvailableOn10_51 {
14991499
}
15001500

15011501

1502-
// We do not want potential unavailability to play a role in picking a witness for a
1503-
// protocol requirement. Rather, the witness should be chosen, regardless of its
1504-
// potential unavailability, and then it should be diagnosed if it is less available
1505-
// than the protocol requires.
1506-
class TestAvailabilityDoesNotAffectWitnessCandidacy : HasMethodF {
1507-
// Test that we choose the more specialized witness even though it is
1508-
// less available than the protocol requires and there is a less specialized
1509-
// witness that has suitable availability.
1502+
// We want conditional availability to play a role in picking a witness for a
1503+
// protocol requirement.
1504+
class TestAvailabilityAffectsWitnessCandidacy : HasMethodF {
1505+
// Test that we choose the less specialized witness, because the more specialized
1506+
// witness is conditionally unavailable.
15101507

15111508
@available(OSX, introduced: 10.51)
1512-
func f(_ p: Int) { } // expected-error {{protocol 'HasMethodF' requires 'f' to be available in macOS 10.50.0 and newer}}
1509+
func f(_ p: Int) { }
15131510

15141511
func f<T>(_ p: T) { }
15151512
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s | %FileCheck %s
2+
3+
// REQUIRES: OS=macosx
4+
5+
public protocol Potato {
6+
func eat()
7+
}
8+
9+
public protocol Fried {}
10+
11+
extension Potato {
12+
public func eat() {}
13+
}
14+
15+
@available(macOS 100, *)
16+
extension Potato where Self : Fried {
17+
public func eat() {}
18+
}
19+
20+
// We ought to pick the unconstrained Potato.eat(), not
21+
// the one from the extension, because the extension has
22+
// narrower availability than the conformance.
23+
public struct CurlyFries : Potato, Fried {}
24+
25+
public struct TaterTots {}
26+
27+
// This conformance on the other hand should use the
28+
// constrained Potato.eat(), since the generic signature
29+
// is more specific than the unconstrained protocol
30+
// extension.
31+
@available(macOS 100, *)
32+
extension TaterTots : Potato, Fried {}
33+
34+
// We FileCheck the SILGen output to verify that the correct
35+
// witnesses were chosen above.
36+
37+
// CHECK-LABEL: sil shared [transparent] [thunk] @$s37conformance_availability_disambiguate10CurlyFriesVAA6PotatoA2aDP3eatyyFTW : $@convention(witness_method: Potato) (@in_guaranteed CurlyFries) -> () {
38+
// CHECK: function_ref @$s37conformance_availability_disambiguate6PotatoPAAE3eatyyF : $@convention(method) <τ_0_0 where τ_0_0 : Potato> (@in_guaranteed τ_0_0) -> ()
39+
// CHECK: return
40+
41+
// sil shared [transparent] [thunk] @$s37conformance_availability_disambiguate9TaterTotsVAA6PotatoA2aDP3eatyyFTW : $@convention(witness_method: Potato) (@in_guaranteed TaterTots) -> () {
42+
// CHECK: function_ref @$s37conformance_availability_disambiguate6PotatoPA2A5FriedRzrlE3eatyyF : $@convention(method) <τ_0_0 where τ_0_0 : Fried, τ_0_0 : Potato> (@in_guaranteed τ_0_0) -> ()
43+
// CHECK: return

test/stdlib/UnsafePointerDiagnostics_warning.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,10 @@ func unsafePointerInitEphemeralConversions() {
201201
// expected-note@-2 {{use the 'withUnsafeMutableBytes' method on Array in order to explicitly convert argument to buffer pointer valid for a defined scope}}
202202

203203
// FIXME: This is currently ambiguous.
204-
_ = OpaquePointer(&foo) // expected-error {{no exact matches in call to initializer}}
204+
_ = OpaquePointer(&foo) // expected-error {{ambiguous use of 'init(_:)'}}
205205

206206
// FIXME: This is currently ambiguous.
207-
_ = OpaquePointer(&arr) // expected-error {{no exact matches in call to initializer}}
207+
_ = OpaquePointer(&arr) // expected-error {{ambiguous use of 'init(_:)'}}
208208

209209
_ = OpaquePointer(arr) // expected-warning {{initialization of 'OpaquePointer' results in a dangling pointer}}
210210
// expected-note@-1 {{implicit argument conversion from '[Int]' to 'UnsafeRawPointer' produces a pointer valid only for the duration of the call to 'init(_:)'}}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
@resultBuilder
4+
struct MyResultBuilder {
5+
static func buildBlock(_ elements: Int...) -> Int { fatalError() }
6+
}
7+
8+
struct VariableDecl2 {
9+
init( // expected-note {{found this candidate}}
10+
paramClosure: () -> Int? = { nil },
11+
paramInt: Int,
12+
@MyResultBuilder paramResultBuilder: () -> Int? = { nil }
13+
) { fatalError() }
14+
15+
init( // expected-note {{found this candidate}}
16+
paramInt: Int,
17+
paramClosure: () -> Int? = { nil },
18+
@MyResultBuilder paramResultBuilder: () -> Int? = { nil }
19+
) {
20+
fatalError()
21+
}
22+
}
23+
24+
let buildable = VariableDecl2(paramInt: 1) { // expected-error {{ambiguous use of 'init'}}
25+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5
2+
3+
// REQUIRES: OS=macosx
4+
5+
enum Category {
6+
case first
7+
}
8+
9+
protocol View {}
10+
11+
extension View {
12+
func test(_ tag: Category) -> some View {
13+
Image()
14+
}
15+
}
16+
17+
@resultBuilder struct ViewBuilder {
18+
static func buildBlock<Content>(_ content: Content) -> Content where Content : View { fatalError() }
19+
}
20+
21+
struct Image : View {
22+
}
23+
24+
struct MyView {
25+
@ViewBuilder var body: some View {
26+
let icon: Category! = Category.first // expected-error {{using '!' is not allowed here; perhaps '?' was intended?}} {{23-24=?}}
27+
Image().test(icon)
28+
}
29+
}

0 commit comments

Comments
 (0)