Skip to content

Commit df73eec

Browse files
committed
Sema: generalize findSyntacticErrorForConsume
Since this function is being called from the constraint solver now, we need to generalize the way it obtains the Type of an Expression, as the expression itself may not know its own type, only the solver does. resolves rdar://134371893 / swiftlang#75999
1 parent 34def0e commit df73eec

File tree

6 files changed

+35
-12
lines changed

6 files changed

+35
-12
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6534,7 +6534,8 @@ ForcedCheckedCastExpr *findForcedDowncast(ASTContext &ctx, Expr *expr);
65346534
/// can I add `consume` around this expression?
65356535
///
65366536
/// \param module represents the module in which the expr appears
6537-
bool canAddExplicitConsume(ModuleDecl *module, Expr *expr);
6537+
bool canAddExplicitConsume(constraints::Solution &sol,
6538+
ModuleDecl *module, Expr *expr);
65386539

65396540
// Count the number of overload sets present
65406541
// in the expression and all of the children.

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5620,18 +5620,18 @@ namespace {
56205620

56215621
/// Check if it needs an explicit consume, due to this being a cast.
56225622
auto *module = dc->getParentModule();
5623-
auto origType = cs.getType(injection->getSubExpr());
5623+
auto origType = solution.getResolvedType(injection->getSubExpr());
56245624
if (willHaveConfusingConsumption(origType, locator, cs) &&
5625-
canAddExplicitConsume(module, injection->getSubExpr()))
5625+
canAddExplicitConsume(solution, module, injection->getSubExpr()))
56265626
ConsumingCoercions.push_back(injection);
56275627
}
56285628

56295629
void diagnoseExistentialErasureOf(Expr *fromExpr, Expr *toExpr,
56305630
ConstraintLocatorBuilder locator) {
56315631
auto *module = dc->getParentModule();
5632-
auto fromType = cs.getType(fromExpr);
5632+
auto fromType = solution.getResolvedType(fromExpr);
56335633
if (willHaveConfusingConsumption(fromType, locator, cs) &&
5634-
canAddExplicitConsume(module, fromExpr)) {
5634+
canAddExplicitConsume(solution, module, fromExpr)) {
56355635
ConsumingCoercions.push_back(toExpr);
56365636
}
56375637
}

lib/Sema/MiscDiagnostics.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,12 +1478,13 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
14781478
}
14791479

14801480
DeferredDiags swift::findSyntacticErrorForConsume(
1481-
ModuleDecl *module, SourceLoc loc, Expr *subExpr) {
1481+
ModuleDecl *module, SourceLoc loc, Expr *subExpr,
1482+
llvm::function_ref<Type(Expr *)> getType) {
14821483
assert(!isa<ConsumeExpr>(subExpr) && "operates on the sub-expr of a consume");
14831484

14841485
DeferredDiags result;
14851486
const bool noncopyable =
1486-
subExpr->getType()->getCanonicalType()->isNoncopyable();
1487+
getType(subExpr)->isNoncopyable();
14871488

14881489
bool partial = false;
14891490
Expr *current = subExpr;

lib/Sema/MiscDiagnostics.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Basic/LLVM.h"
2222
#include "swift/Basic/SourceLoc.h"
2323
#include "llvm/ADT/ArrayRef.h"
24+
#include "llvm/ADT/STLFunctionalExtras.h"
2425
#include <optional>
2526

2627
namespace swift {
@@ -162,10 +163,18 @@ namespace swift {
162163
/// \param loc corresponds to the location of the 'consume' for which
163164
/// diagnostics should be collected, if any.
164165
///
166+
/// \param getType is a function that can correctly determine the type of
167+
/// an expression. This is to support calls from the
168+
/// constraint solver.
169+
///
165170
/// \returns an empty collection if there are no errors.
166-
DeferredDiags findSyntacticErrorForConsume(ModuleDecl *module,
167-
SourceLoc loc,
168-
Expr *subExpr);
171+
DeferredDiags findSyntacticErrorForConsume(
172+
ModuleDecl *module,
173+
SourceLoc loc,
174+
Expr *subExpr,
175+
llvm::function_ref<Type(Expr *)> getType = [](Expr *E) {
176+
return E->getType();
177+
});
169178
} // namespace swift
170179

171180
#endif // SWIFT_SEMA_MISC_DIAGNOSTICS_H

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,15 +2338,18 @@ ForcedCheckedCastExpr *swift::findForcedDowncast(ASTContext &ctx, Expr *expr) {
23382338
return nullptr;
23392339
}
23402340

2341-
bool swift::canAddExplicitConsume(ModuleDecl *module, Expr *expr) {
2341+
bool swift::canAddExplicitConsume(constraints::Solution &sol,
2342+
ModuleDecl *module,
2343+
Expr *expr) {
23422344
expr = expr->getSemanticsProvidingExpr();
23432345

23442346
// Is it already wrapped in a `consume`?
23452347
if (isa<ConsumeExpr>(expr))
23462348
return false;
23472349

23482350
// Is this expression valid to wrap inside a `consume`?
2349-
auto diags = findSyntacticErrorForConsume(module, SourceLoc(), expr);
2351+
auto diags = findSyntacticErrorForConsume(module, SourceLoc(), expr,
2352+
[&](Expr *e) { return sol.getResolvedType(e); });
23502353
return diags.empty();
23512354
}
23522355

test/Sema/moveonly_casts.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,12 @@ struct ImplicitInit: ~Copyable {
131131
func test(_ nc: consuming NC) -> ImplicitInit {
132132
return .init(x: nc)
133133
}
134+
135+
136+
// rdar://134371893 (optional chaining on ~Copyable type)
137+
struct NonCopyable: ~Copyable {
138+
var shared: Self { .init() }
139+
}
140+
func f() {
141+
_ = (Optional<NonCopyable>.none)?.shared
142+
}

0 commit comments

Comments
 (0)