Skip to content

Conversation

@j-hui
Copy link
Contributor

@j-hui j-hui commented Nov 7, 2025

Prior to this patch, we eagerly imported template type arguments.
A consequence of doing so is that we over-instantiate (potentially
unused) type arguments, which causes unnecessary errors. This patch
skips importing those types.

These types were previously used to determine whether an imported
type is unsafe. This patch moves that check into the request that
checks for Clang decl safety.

rdar://145238539
rdar://163196609

@hnrklssn
Copy link
Member

hnrklssn commented Nov 7, 2025

Could you elaborate on the differences between this and the previous patches?

@j-hui j-hui marked this pull request as draft November 7, 2025 08:07
j-hui added 2 commits November 7, 2025 00:12
Checking this upon import may overlook annotations that explicitly
mark a type as safe (or unsafe). Instead, we consolidate this logic in
the ClangDeclExplicitSafety request.

rdar://163196609
Prior to this patch, we eagerly imported template type arguments.
A consequence of doing so is that we over-instantiate (potentially
unused) type arguments, which causes unnecessary errors.

The only apparent use we have for these type arguments are to check
whether they are unsafe, so that we can mark the instantiated type as
unsafe as well... even if the instantiated type does not use its unsafe
template type argument at all.

Using un-instantiatable types in template type arguments is supported
in C++. The test case included in this patch validates this behavior,
for both missing member and incomplete type errors.

Note, also, that as of this patch, dumping the module interface of
CxxModule actually causes swift-ide-test to emit compiler errors, since
it tries to instantiate the invalid types MissingMember<Empty> and
IncompleteField<Incomplete>. However, these errors are simply swallowed
by swift-ide-test, so they should be harmless, though we should probably
get rid of them entirely in future work.

rdar://145238539
@j-hui j-hui force-pushed the dont-import-template-type-arguments-round-2 branch from c24d10f to 3255ffb Compare November 7, 2025 08:13
@j-hui
Copy link
Contributor Author

j-hui commented Nov 7, 2025

This patch re-lands the patches reverted in #85296. Note that there were no known issues with that patch.

The main difference in this patch is that it eliminates the ClangTypeExplicitSafety request, which ended up being unnecessary because I no longer needed to expose the logic that checks types to the decl importer.

@j-hui
Copy link
Contributor Author

j-hui commented Nov 7, 2025

@swift-ci please test

@hnrklssn
Copy link
Member

hnrklssn commented Nov 7, 2025

The main difference in this patch is that it eliminates the ClangTypeExplicitSafety request, which ended up being unnecessary because I no longer needed to expose the logic that checks types to the decl importer.

Was it this request that caused the cycle mentioned in #85296, or was it some other patch that has now been fixed?

}
auto req = ClangDeclExplicitSafety({recordDecl, false});
if (evaluator.hasActiveRequest(req))
// Normally, using hasActiveRequest() to avoid cycles is an anti-pattern
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It’s still an anti-pattern and nothing else outside of some old hacks in lib/AST and lib/Sema calls it today. Did you get a chance to investigate the possibility of plumbing a DenseSet<…> visited through here instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if the doc comment for hasActiveRequest mentioned this and explained what the issue with it is, so that new contributors are guided in the right direction. Right now it's really unclear that it's not meant to be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you get a chance to investigate the possibility of plumbing a DenseSet<…> visited through here instead?

I did, but that ended up causing more problems of its own, e.g., whether/how to cache the DenseSet<...> that now needs to be part of the request descriptor, etc.

I've rewritten the request to be non-recursive.

It would be good if the doc comment for hasActiveRequest mentioned this and explained what the issue with it is, so that new contributors are guided in the right direction. Right now it's really unclear that it's not meant to be used.

I agree. I've added a comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did, but that ended up causing more problems of its own, e.g., whether/how to cache the DenseSet<...> that now needs to be part of the request descriptor, etc.

I've rewritten the request to be non-recursive.

Rewriting it to be non-recursive is what I meant, not passing the visited set as a parameter to the request. Sorry for the confusion. Thanks!

j-hui added 2 commits November 7, 2025 15:02
Doing so reduces opportunities for caching, but it's not obvious to me
that we benefit from such fine-grained caching. The benefit here is that
we also avoid the pitfalls of incremental caching, as illustrated by the
added test case. Finally, we eliminate the use of hasActiveRequest(),
which is an anti-pattern.
@j-hui j-hui marked this pull request as ready for review November 7, 2025 23:15
@j-hui j-hui requested a review from CodaFi as a code owner November 7, 2025 23:15
@j-hui
Copy link
Contributor Author

j-hui commented Nov 7, 2025

Was it this request that caused the cycle mentioned in #85296, or was it some other patch that has now been fixed?

This request was not at fault. The issue ended up being the patches reverted in #85331.

@j-hui
Copy link
Contributor Author

j-hui commented Nov 7, 2025

@swift-ci please test

@j-hui j-hui requested a review from DougGregor November 7, 2025 23:16
j-hui added 2 commits November 7, 2025 15:22
…icitSafetyDescriptor

Keep the naming convention consistent; this isn't specific to Cxx
@j-hui
Copy link
Contributor Author

j-hui commented Nov 7, 2025

@swift-ci please test

@egorzhdan egorzhdan added the c++ interop Feature: Interoperability with C++ label Nov 7, 2025
Comment on lines +8875 to +8876
// If desc.decl doesn't have a definition, safety is unspecified.
return ExplicitSafety::Unspecified;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a decl has a field that has unspecified safety, and another field that is explicitly unsafe, is ExplicitSafety::Unspecified the right value to return?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This early return only triggers when decl == desc.decl, i.e., when the "origin" decl of the request lacks a definition.

Here, if decl is from a field, it should not equal desc.decl.

@j-hui
Copy link
Contributor Author

j-hui commented Nov 8, 2025

TIMEOUT: lldb-shell :: Breakpoint/jit-loader_jitlink_elf.test (2475 of 2475)
******************** TEST 'lldb-shell :: Breakpoint/jit-loader_jitlink_elf.test' FAILED ********************
Exit Code: 1
Timeout: Reached timeout of 900 seconds

Seems unrelated

@j-hui
Copy link
Contributor Author

j-hui commented Nov 8, 2025

@swift-ci please test windows platform

stack.push_back(desc.decl);
seen.insert(desc.decl);
while (!stack.empty()) {
const clang::Decl *decl = stack.back();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we end up visiting the same decl multiple time across different requests?

I wonder if we should also cache the responses explicitly for all the decls that we visited and computed safety for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ interop Feature: Interoperability with C++

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants