Skip to content
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
2 changes: 1 addition & 1 deletion lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5875,7 +5875,7 @@ ASTContext::getOpenedExistentialSignature(Type type, GenericSignature parentSig)
return found->second;

auto genericParam = OpenedArchetypeType::getSelfInterfaceTypeFromContext(
canParentSig, type->getASTContext())
canParentSig, *this)
->castTo<GenericTypeParamType>();
Requirement requirement(RequirementKind::Conformance, genericParam,
constraint);
Expand Down
7 changes: 5 additions & 2 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,7 @@ namespace {
printField(PD->getDefaultArgumentKind(), "default_arg");
}
if (PD->hasDefaultExpr() &&
PD->getDefaultArgumentCaptureInfo().hasBeenComputed() &&
!PD->getDefaultArgumentCaptureInfo().isTrivial()) {
printFieldRaw([&](raw_ostream &OS) {
PD->getDefaultArgumentCaptureInfo().print(OS);
Expand Down Expand Up @@ -1488,7 +1489,8 @@ namespace {

void printCommonAFD(AbstractFunctionDecl *D, const char *Type, StringRef Label) {
printCommon(D, Type, Label, FuncColor);
if (!D->getCaptureInfo().isTrivial()) {
if (D->getCaptureInfo().hasBeenComputed() &&
!D->getCaptureInfo().isTrivial()) {
printFlagRaw([&](raw_ostream &OS) {
D->getCaptureInfo().print(OS);
});
Expand Down Expand Up @@ -2826,7 +2828,8 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, StringRef>,
break;
}

if (!E->getCaptureInfo().isTrivial()) {
if (E->getCaptureInfo().hasBeenComputed() &&
!E->getCaptureInfo().isTrivial()) {
printFieldRaw([&](raw_ostream &OS) {
E->getCaptureInfo().print(OS);
}, "", CapturesColor);
Expand Down
11 changes: 4 additions & 7 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1683,14 +1683,11 @@ void PrintAST::printGenericSignature(GenericSignature genericSig,
static void eraseInvertibleProtocolConformances(
SmallVectorImpl<Requirement> &requirements) {
llvm::erase_if(requirements, [&](Requirement req) {
if (req.getKind() == RequirementKind::Conformance) {
if (auto protoType = req.getSecondType()->getAs<ProtocolType>()) {
auto proto = protoType->getDecl();
return proto->getInvertibleProtocolKind().has_value();
}
}
if (req.getKind() != RequirementKind::Conformance)
return false;

return false;
return req.getProtocolDecl()
->getInvertibleProtocolKind().has_value();
});
}

Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ Type TypeBase::stripConcurrency(bool recurse, bool dropGlobalActor) {
// If it's a Sendable requirement, skip it.
const auto &req = requirements[reqIdx];
if (req.getKind() == RequirementKind::Conformance &&
req.getSecondType()->castTo<ProtocolType>()->getDecl()
req.getProtocolDecl()
->isSpecificProtocol(KnownProtocolKind::Sendable))
continue;

Expand Down
10 changes: 3 additions & 7 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10256,13 +10256,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
if (req.getKind() != RequirementKind::Conformance)
return false;

if (auto protocolTy =
req.getSecondType()->template getAs<ProtocolType>()) {
return req.getFirstType()->hasTypeVariable() &&
protocolTy->getDecl()->isSpecificProtocol(
KnownProtocolKind::Sendable);
}
return false;
return (req.getFirstType()->hasTypeVariable() &&
req.getProtocolDecl()->isSpecificProtocol(
KnownProtocolKind::Sendable));
})) {
result.OverallResult = MemberLookupResult::Unsolved;
return result;
Expand Down
24 changes: 19 additions & 5 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2624,9 +2624,23 @@ namespace {
return MacroWalking::Expansion;
}

PreWalkResult<Pattern *> walkToPatternPre(Pattern *pattern) override {
// Walking into patterns leads to nothing good because then we
// end up visiting the AccessorDecls of a top-level
// PatternBindingDecl twice.
return Action::SkipNode(pattern);
}

PreWalkAction walkToDeclPre(Decl *decl) override {
// Don't walk into local types because nothing in them can
// change the outcome of our analysis, and we don't want to
// assume things there have been type checked yet.
if (isa<TypeDecl>(decl)) {
return Action::SkipChildren();
}

if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
if (func->isLocalContext()) {
if (func->getDeclContext()->isLocalContext()) {
checkLocalCaptures(func);
}

Expand Down Expand Up @@ -4249,7 +4263,9 @@ void swift::checkFunctionActorIsolation(AbstractFunctionDecl *decl) {
ActorIsolationChecker checker(decl);
if (auto body = decl->getBody()) {
body->walk(checker);
if(ctx.LangOpts.hasFeature(Feature::GroupActorErrors)){ checker.diagnoseIsolationErrors(); }
if (ctx.LangOpts.hasFeature(Feature::GroupActorErrors)) {
checker.diagnoseIsolationErrors();
}
}
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
if (auto superInit = ctor->getSuperInitCall())
Expand Down Expand Up @@ -5375,11 +5391,9 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
return ActorIsolation::forUnspecified();

auto i = pbd->getPatternEntryIndexForVarDecl(var);
if (!pbd->isInitializerChecked(i))
TypeChecker::typeCheckPatternBinding(pbd, i);

dc = cast<Initializer>(pbd->getInitContext(i));
initExpr = pbd->getInit(i);
initExpr = pbd->getCheckedAndContextualizedInit(i);
enclosingIsolation = getActorIsolation(var);
} else if (auto *param = dyn_cast<ParamDecl>(var)) {
// If this parameter corresponds to a stored property for a
Expand Down
11 changes: 10 additions & 1 deletion lib/Sema/TypeCheckDeclPrimary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2722,7 +2722,16 @@ class DeclChecker : public DeclVisitor<DeclChecker> {

// Trigger a request that will complete typechecking for the
// initializer.
(void)PBD->getCheckedAndContextualizedInit(i);
(void) PBD->getCheckedAndContextualizedInit(i);

if (auto *var = PBD->getSingleVar()) {
if (var->hasAttachedPropertyWrapper())
return;
}

if (!PBD->getDeclContext()->isLocalContext()) {
(void) PBD->getInitializerIsolation(i);
}
}
}

Expand Down
6 changes: 2 additions & 4 deletions lib/Sema/TypeCheckStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2994,12 +2994,10 @@ bool TypeChecker::typeCheckTapBody(TapExpr *expr, DeclContext *DC) {
}

void TypeChecker::typeCheckTopLevelCodeDecl(TopLevelCodeDecl *TLCD) {
// We intentionally use typeCheckStmt instead of typeCheckBody here
// because we want to contextualize all the TopLevelCode
// declarations simultaneously.
BraceStmt *Body = TLCD->getBody();
StmtChecker(TLCD).typeCheckStmt(Body);
StmtChecker(TLCD).typeCheckBody(Body);
TLCD->setBody(Body);

checkTopLevelActorIsolation(TLCD);
checkTopLevelEffects(TLCD);
performTopLevelDeclDiagnostics(TLCD);
Expand Down
1 change: 0 additions & 1 deletion lib/Sema/TypeCheckStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,6 @@ static void checkAndContextualizePatternBindingInit(PatternBindingDecl *binding,
if (auto *initContext = binding->getInitContext(i)) {
auto *init = binding->getInit(i);
TypeChecker::contextualizeInitializer(initContext, init);
(void)binding->getInitializerIsolation(i);
TypeChecker::checkInitializerEffects(initContext, init);
}
}
Expand Down
1 change: 0 additions & 1 deletion lib/Sema/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@ TypeCheckSourceFileRequest::evaluate(Evaluator &eval, SourceFile *SF) const {
for (auto D : SF->getTopLevelDecls()) {
if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
TypeChecker::typeCheckTopLevelCodeDecl(TLCD);
TypeChecker::contextualizeTopLevelCode(TLCD);
} else {
TypeChecker::typeCheckDecl(D);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Serialization/Deserialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -987,7 +987,7 @@ ProtocolConformanceDeserializer::readNormalProtocolConformance(

assert(!isa<ClangModuleUnit>(dc->getModuleScopeContext())
&& "should not have serialized a conformance from a clang module");
Type conformingType = dc->getDeclaredInterfaceType();
Type conformingType = dc->getSelfInterfaceType();
PrettyStackTraceType trace(ctx, "reading conformance for", conformingType);

auto protoOrError = MF.getDeclChecked(protoID);
Expand Down
25 changes: 25 additions & 0 deletions test/Concurrency/sendable_checking_captures.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %target-typecheck-verify-swift -swift-version 6

class NonSendable {} // expected-note 3{{class 'NonSendable' does not conform to the 'Sendable' protocol}}

func callee(_: @Sendable () -> NonSendable) {}

var testLocalCaptures: Int {
let ns = NonSendable()

@Sendable func localFunc() -> NonSendable {
return ns // expected-error {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` local function}}
}

callee { return ns } // expected-error {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure}}

return 3
}

struct Bad {
var c: Int = {
let ns = NonSendable()
callee { return ns } // expected-error {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure}}
return 3
}()
}