Skip to content

Conversation

@allevato
Copy link
Member

  1. Don't attempt to compute type USR for ModuleTypes.

    ModuleTypes show up in some rare places, like the left-hand-side of a DotSyntaxBaseIgnoredExpr for a module-qualified function call. ASTMangler does not support these because they're not real types.

  2. Print decl-refs, not full decls, for function captures.

    This avoids infinite recursion when a function captures itself; e.g.,

    func foo() {
      func bar() {
        bar()
      }
      bar()
    }

    It also just avoids printing unnecessarily verbose information, since those decls would have already been dumped elsewhere in the tree.

`ModuleType`s show up in some rare places, like the left-hand-side of
a `DotSyntaxBaseIgnoredExpr` for a module-qualified function call.
ASTMangler does not support these because they're not real types.
This avoids infinite recursion when a function captures itself; e.g.,

```swift
func foo() {
  func bar() {
    bar()
  }
  bar()
}
```

It also just avoids printing unnecessarily verbose information,
since those decls would have already been dumped elsewhere in the
tree.
@allevato
Copy link
Member Author

@swift-ci Please smoke test

return "";

if (isa<ModuleDecl>(D)) {
// ASTMangler does not support "module types". This can appear, for
Copy link
Contributor

Choose a reason for hiding this comment

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

You could conceivably plumb this through, because the ASTMangler does know how to mangle a ModuleDecl when it's a context of another decl. You could mangle a bare ModuleDecl as just that without anything else. Up to you

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that would violate the invariants about the kinds of USRs we generate in the AST output. We have declaration USRs, which are the "s:..." prefixed form used by indexstore and SourceKit, and type USRs, the standard "$s...D" symbol mangling that ends in the TypeMangling operator.

In this case, it's taking the ModuleDecl and wants to print the corresponding type USR, which I don't think we have a way to generate. Or am I misunderstanding?

Side question that came up while I was exploring this: what is the reason for leaving the DotSyntaxBaseIgnoredExpr in the already type-checked AST after resolving the function call? I noticed that only a few kinds of expressions still produce those, like Swift.print(). For type constructors (e.g., Swift.Int(), it just becomes a ConstructorRefCallExpr and the decl ref knows the exact decl, including the owning module, that Int comes from. But I would expect that to be true for the print() call, too.

// We print the decl ref, not the full decl, to avoid infinite
// recursion when a function captures itself (and also because
// those decls are already printed elsewhere, so we don't need to
// print what could be a very large amount of information twice).
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, that definitely makes sense even for VarDecl captures. Also, the same decl can be captured more than once, etc.

Copy link
Member Author

@allevato allevato Nov 24, 2025

Choose a reason for hiding this comment

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

One downside (which was already present before this PR, too) is that because local decls don't get USRs, it's not as easy to match the capture decl ref back to the exact original decl. But the decl ref still contains the name, so it can still be tracked down with a little bit more bookkeeping, and knowing that it's local constrains the search space.

Copy link
Member Author

@allevato allevato left a comment

Choose a reason for hiding this comment

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

Thanks for the quick review!

// We print the decl ref, not the full decl, to avoid infinite
// recursion when a function captures itself (and also because
// those decls are already printed elsewhere, so we don't need to
// print what could be a very large amount of information twice).
Copy link
Member Author

@allevato allevato Nov 24, 2025

Choose a reason for hiding this comment

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

One downside (which was already present before this PR, too) is that because local decls don't get USRs, it's not as easy to match the capture decl ref back to the exact original decl. But the decl ref still contains the name, so it can still be tracked down with a little bit more bookkeeping, and knowing that it's local constrains the search space.

return "";

if (isa<ModuleDecl>(D)) {
// ASTMangler does not support "module types". This can appear, for
Copy link
Member Author

Choose a reason for hiding this comment

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

I think that would violate the invariants about the kinds of USRs we generate in the AST output. We have declaration USRs, which are the "s:..." prefixed form used by indexstore and SourceKit, and type USRs, the standard "$s...D" symbol mangling that ends in the TypeMangling operator.

In this case, it's taking the ModuleDecl and wants to print the corresponding type USR, which I don't think we have a way to generate. Or am I misunderstanding?

Side question that came up while I was exploring this: what is the reason for leaving the DotSyntaxBaseIgnoredExpr in the already type-checked AST after resolving the function call? I noticed that only a few kinds of expressions still produce those, like Swift.print(). For type constructors (e.g., Swift.Int(), it just becomes a ConstructorRefCallExpr and the decl ref knows the exact decl, including the owning module, that Int comes from. But I would expect that to be true for the print() call, too.

@allevato
Copy link
Member Author

@swift-ci please smoke test macOS platform

@allevato
Copy link
Member Author

allevato commented Dec 1, 2025

@swift-ci please smoke test

@allevato
Copy link
Member Author

allevato commented Dec 2, 2025

@swift-ci please smoke test Windows platform

@allevato allevato merged commit a437c6d into swiftlang:main Dec 2, 2025
3 checks passed
@allevato allevato deleted the more-json-ast-fixes branch December 2, 2025 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants