Skip to content

Commit c83e890

Browse files
authored
Merge pull request #18319 from slavapestov/di-try-apply
DI: Don't forget to check inout uses for try_apply too
2 parents 14f7799 + c7fff66 commit c83e890

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,9 @@ void ElementUseCollector::collectUses(SILValue Pointer, unsigned BaseEltNo) {
819819
//
820820
// Note that partial_apply instructions always close over their argument.
821821
//
822-
if (auto *Apply = dyn_cast<ApplyInst>(User)) {
823-
auto substConv = Apply->getSubstCalleeConv();
822+
auto Apply = FullApplySite::isa(User);
823+
if (Apply) {
824+
auto substConv = Apply.getSubstCalleeConv();
824825
unsigned ArgumentNumber = Op->getOperandNumber() - 1;
825826

826827
// If this is an out-parameter, it is like a store.

lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,14 +1087,15 @@ void LifetimeChecker::handleInOutUse(const DIMemoryUse &Use) {
10871087
// Otherwise, we produce a generic error.
10881088
FuncDecl *FD = nullptr;
10891089
bool isAssignment = false;
1090-
1091-
if (auto *Apply = dyn_cast<ApplyInst>(Use.Inst)) {
1090+
1091+
auto Apply = FullApplySite::isa(Use.Inst);
1092+
if (Apply) {
10921093
// If this is a method application, produce a nice, specific, error.
1093-
if (auto *WMI = dyn_cast<MethodInst>(Apply->getOperand(0)))
1094+
if (auto *WMI = dyn_cast<MethodInst>(Apply.getCallee()))
10941095
FD = dyn_cast<FuncDecl>(WMI->getMember().getDecl());
10951096

10961097
// If this is a direct/devirt method application, check the location info.
1097-
if (auto *Fn = Apply->getReferencedFunction()) {
1098+
if (auto *Fn = Apply.getReferencedFunction()) {
10981099
if (Fn->hasLocation()) {
10991100
auto SILLoc = Fn->getLocation();
11001101
FD = SILLoc.getAsASTNode<FuncDecl>();
@@ -1104,9 +1105,9 @@ void LifetimeChecker::handleInOutUse(const DIMemoryUse &Use) {
11041105
// If we failed to find the decl a clean and principled way, try hacks:
11051106
// map back to the AST and look for some common patterns.
11061107
if (!FD) {
1107-
if (Apply->getLoc().getAsASTNode<AssignExpr>())
1108+
if (Apply.getLoc().getAsASTNode<AssignExpr>())
11081109
isAssignment = true;
1109-
else if (auto *CE = Apply->getLoc().getAsASTNode<ApplyExpr>()) {
1110+
else if (auto *CE = Apply.getLoc().getAsASTNode<ApplyExpr>()) {
11101111
if (auto *DSCE = dyn_cast<SelfApplyExpr>(CE->getFn()))
11111112
// Normal method calls are curried, so they are:
11121113
// (call_expr (dot_syntax_call_expr (decl_ref_expr METHOD)))

test/SILOptimizer/definite_init_diagnostics.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,8 @@ extension Int {
758758
}
759759

760760

761+
func throwingSwap<T>(_ a: inout T, _ b: inout T) throws {}
762+
761763
// <rdar://problem/19035287> let properties should only be initializable, not reassignable
762764
struct LetProperties {
763765
// expected-note @+1 {{change 'let' to 'var' to make it mutable}} {{3-6=var}}
@@ -771,6 +773,9 @@ struct LetProperties {
771773
let y : Int
772774
let z : Int? // expected-note{{'self.z' not initialized}}
773775

776+
func methodTakesInOut(_ x: inout Int) {}
777+
func throwingMethodTakesInOut(_ x: inout Int) throws {}
778+
774779
// Let properties can be initialized naturally exactly once along any given
775780
// path through an initializer.
776781
init(cond : Bool) {
@@ -810,19 +815,23 @@ struct LetProperties {
810815
} // expected-error {{return from initializer without initializing all stored properties}}
811816

812817
// inout uses of let properties are an error.
813-
init() {
818+
init() throws {
814819
u = 1; v = 13; w = (1,2); y = 1 ; z = u
815820

816821
var variable = 42
817822
swap(&u, &variable) // expected-error {{immutable value 'self.u' must not be passed inout}}
818-
823+
try throwingSwap(&u, &variable) // expected-error {{immutable value 'self.u' must not be passed inout}}
824+
819825
u.inspect() // ok, non mutating.
820826
u.mutate() // expected-error {{mutating method 'mutate' may not be used on immutable value 'self.u'}}
821827

822828
arr = []
823829
arr += [] // expected-error {{mutating operator '+=' may not be used on immutable value 'self.arr'}}
824830
arr.append(4) // expected-error {{mutating method 'append' may not be used on immutable value 'self.arr'}}
825831
arr[12] = 17 // expected-error {{mutating subscript 'subscript' may not be used on immutable value 'self.arr'}}
832+
833+
methodTakesInOut(&u) // expected-error {{mutating method 'methodTakesInOut' may not be used on immutable value 'self.u'}}
834+
try throwingMethodTakesInOut(&u) // expected-error {{mutating method 'throwingMethodTakesInOut' may not be used on immutable value 'self.u'}}
826835
}
827836
}
828837

0 commit comments

Comments
 (0)