Skip to content

Conversation

@kovdan01
Copy link
Contributor

@kovdan01 kovdan01 commented Oct 2, 2025

In #83926, part of the changes resolving #68944 is submitted. The AutoDiff closure specialization optimizer pass relies on several AST-level bridges not implemented yet.

This patch introduces these missing bridges. See the list of the changes below.

TODO: Update description when the final set of bridges is establishes after review

AST:

  • Define .asValueDecl on each BridgedXXXDecl type that's also a ValueDecl.

  • Define .asNominalTypeDecl on each BridgedXXXDecl type that's also a NominalTypeDecl.

  • Define .asGenericContext on each BridgedXXXDecl type that's also a GenericContext.

  • class BridgedSourceFile:

    • Make nullable
    • func addTopLevelDecl(_ decl: BridgedDecl)
  • class BridgedFileUnit:

    • func castToSourceFile() -> BridgedNullableSourceFile
  • class BridgedDecl:

    • func getDeclContext() -> BridgedDeclContext
  • class BridgedParamDecl:

    • func cloneWithoutType() -> BridgedParamDecl
    • func setInterfaceType(_ type : BridgedASTType)
  • Define BridgedDecl.setImplicit() instead of BridgedParamDecl.setImplicit()

  • class BridgedGenericContext:

    • setGenericSignature(_ genSig: BridgedGenericSignature)
  • Change return type of BridgedEnumDecl.createParsed(/*...*/) from BridgedNominalTypeDecl to BridgedEnumDecl

  • class BridgedValueDecl:

    • func setAccess(_ accessLevel: swift.AccessLevel)
  • class BridgedNominalTypeDecl:

    • func addMember(_ member: BridgedDecl)
  • class BridgedGenericTypeParamDecl:

    • func createImplicit(declContext: BridgedDeclContext, name: swift.Identifier, depth: UInt, index: UInt, paramKind: swift.GenericTypeParamKind)
  • class ValueDecl:

    • var baseIdentifier: swift.Identifier
  • class NominalTypeDecl:

    • var declaredInterfaceType: Type
  • class EnumElementDecl:

    • var parameterList: BridgedParameterList
    • var nameStr: StringRef
  • struct GenericSignature:

    • var canonicalSignature: CanGenericSignature
  • struct CanGenericSignature:

    • var isEmpty: Bool
    • var genericSignature: GenericSignature
  • struct Type:

    • func mapTypeOutOfContext() -> Type
    • func getReducedType(sig: GenericSignature) -> CanonicalType
    • func GenericTypeParam_getName() -> swift.Identifier
    • func GenericTypeParam_getDepth() -> UInt
    • func GenericTypeParam_getIndex() -> UInt
    • func GenericTypeParam_getParamKind() -> swift.GenericTypeParamKind
  • struct CanonicalType:

    • func SILFunctionType_getSubstGenericSignature() -> CanGenericSignature
    • func loweredType(in function: SIL.Function) -> SIL.Type

SIL:

  • class Argument:

    • func replaceAllUsesWith(newArg: Argument)
  • class BasicBlock:

    • func insertPhiArgument(atPosition: Int, type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument
  • struct Builder:

    • func createTuple(elements: [Value]) -> TupleInst
  • protocol Context:

    • func getTupleType(elements: [AST.Type]) -> AST.Type
    • func getTupleTypeWithLabels(elements: [AST.Type], labels: [swift.Identifier]) -> AST.Type
  • class Function:

    • var sourceFile: BridgedNullableSourceFile
    • func mapTypeIntoContext(_ type: Type) -> Type
  • class PartialApplyInst:

    • var substitutionMap: SubstitutionMap
  • class SwitchEnumInst:

    • var numCases: Int
    • public func getSuccessorForDefault() -> BasicBlock?
  • Type:

    • var category: ValueCategory
    • func getEnumCasePayload(caseIdx: Int, function: Function) -> Type
    • func mapTypeOutOfContext() -> Type
    • static func getPrimitiveType(canType: CanonicalType, silValueCategory: ValueCategory) -> Type
  • struct EnumCase:

    • let enumElementDecl: EnumElementDecl
  • struct TupleElementArray:

    • func label(at index: Int) -> swift.Identifier
  • Define enum ValueCategory with address and object elements

@kovdan01 kovdan01 requested a review from asl October 2, 2025 14:49
@kovdan01
Copy link
Contributor Author

kovdan01 commented Oct 2, 2025

Tagging @JaapWijnen

@asl
Copy link
Contributor

asl commented Oct 2, 2025

@kovdan01 Will you please summarize the list of changes in the PR description? Overall, while these are prerequisites for autodiff-related closure specialization pass, overall these bridges are not autodiff-specific.

In #83926, part of the changes resolving #68944 is submitted. The AutoDiff
closure specialization optimizer pass relies on several bridges not
implemented yet.

This patch introduces these missing bridges. See the list of the changes below.

**AST:**

* Define `.asValueDecl` on each BridgedXXXDecl type that's also a ValueDecl.

* Define `.asNominalTypeDecl` on each BridgedXXXDecl type that's also a NominalTypeDecl.

* Define `.asGenericContext` on each BridgedXXXDecl type that's also a GenericContext.

* `class BridgedSourceFile`:
  - Make nullable
  - `func addTopLevelDecl(_ decl: BridgedDecl)`

* `class BridgedFileUnit`:
  - `func castToSourceFile() -> BridgedNullableSourceFile`

* `class BridgedDecl`:
  - `func getDeclContext() -> BridgedDeclContext`

* `class BridgedParamDecl`:
  - `func cloneWithoutType() -> BridgedParamDecl`
  - `func setInterfaceType(_ type : BridgedASTType)`

* Define `BridgedDecl.setImplicit()` instead of `BridgedParamDecl.setImplicit()`

* `class BridgedGenericContext`:
  - `setGenericSignature(_ genSig: BridgedGenericSignature)`

* Change return type of `BridgedEnumDecl.createParsed(/*...*/)` from `BridgedNominalTypeDecl` to `BridgedEnumDecl`

* `class BridgedValueDecl`:
  - `func setAccess(_ accessLevel: swift.AccessLevel)`

* `class BridgedNominalTypeDecl`:
  - `func addMember(_ member: BridgedDecl)`

* `class BridgedGenericTypeParamDecl`:
  - `func createImplicit(declContext: BridgedDeclContext, name: swift.Identifier, depth: UInt, index: UInt, paramKind: swift.GenericTypeParamKind)`

* `class ValueDecl`:
  - `var baseIdentifier: swift.Identifier`

* `class NominalTypeDecl`:
  - `var declaredInterfaceType: Type`

* `class EnumElementDecl`:
  - `var parameterList: BridgedParameterList`
  - `var nameStr: StringRef`

* `struct GenericSignature`:
  - `var canonicalSignature: CanGenericSignature`

* `struct CanGenericSignature`:
  - `var isEmpty: Bool`
  - `var genericSignature: GenericSignature`

* `struct Type`:
  - `func mapTypeOutOfContext() -> Type`
  - `func getReducedType(sig: GenericSignature) -> CanonicalType`
  - `func GenericTypeParam_getName() -> swift.Identifier`
  - `func GenericTypeParam_getDepth() -> UInt`
  - `func GenericTypeParam_getIndex() -> UInt`
  - `func GenericTypeParam_getParamKind() -> swift.GenericTypeParamKind`

* `struct CanonicalType`:
  - `func SILFunctionType_getSubstGenericSignature() -> CanGenericSignature`
  - `func loweredType(in function: SIL.Function) -> SIL.Type`

**SIL:**

* `class Argument`:
  - `func replaceAllUsesWith(newArg: Argument)`

* `class BasicBlock`:
  - `func insertPhiArgument(atPosition: Int, type: Type, ownership: Ownership, _ context: some MutatingContext) -> Argument`

* `struct Builder`:
  - `func createTuple(elements: [Value]) -> TupleInst`

* `protocol Context`:
  - `func getTupleType(elements: [AST.Type]) -> AST.Type`
  - `func getTupleTypeWithLabels(elements: [AST.Type], labels: [swift.Identifier]) -> AST.Type`

* `class Function`:
  - `var sourceFile: BridgedNullableSourceFile`
  - `func mapTypeIntoContext(_ type: Type) -> Type`

* `class PartialApplyInst`:
  - `var substitutionMap: SubstitutionMap`

* `class SwitchEnumInst`:
  - `var numCases: Int`
  - `public func getSuccessorForDefault() -> BasicBlock?`

* `Type`:
  - `var category: ValueCategory`
  - `func getEnumCasePayload(caseIdx: Int, function: Function) -> Type`
  - `func mapTypeOutOfContext() -> Type`
  - `static func getPrimitiveType(canType: CanonicalType, silValueCategory: ValueCategory) -> Type`

* `struct EnumCase`:
  - `let enumElementDecl: EnumElementDecl`

* `struct TupleElementArray`:
  - `func label(at index: Int) -> swift.Identifier`

* Define `enum ValueCategory` with `address` and `object` elements
@kovdan01 kovdan01 force-pushed the users/kovdan01/ast-bridges-for-autodiff-closure-spec branch from 10085d6 to b3d31c7 Compare October 6, 2025 14:58
@kovdan01 kovdan01 added the bridging Feature → casting: type bridging label Oct 6, 2025
@kovdan01
Copy link
Contributor Author

kovdan01 commented Oct 6, 2025

@kovdan01 Will you please summarize the list of changes in the PR description? Overall, while these are prerequisites for autodiff-related closure specialization pass, overall these bridges are not autodiff-specific.

@asl Thanks for suggestion, updated the comment

@kovdan01 kovdan01 marked this pull request as ready for review October 6, 2025 15:09
@kovdan01
Copy link
Contributor Author

kovdan01 commented Oct 6, 2025

@swift-ci please test

@eeckstein
Copy link
Contributor

@kovdan01 I'll review this tomorrow

@eeckstein eeckstein marked this pull request as draft October 6, 2025 16:23

final public class EnumElementDecl: ValueDecl {
public var hasAssociatedValues: Bool { bridged.EnumElementDecl_hasAssociatedValues() }
public var parameterList: BridgedParameterList { bridged.EnumElementDecl_getParameterList() }
Copy link
Contributor

Choose a reason for hiding this comment

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

Please don't expose bridged data structures in APIs. Create a native swift ParameterList containing a var bridged: BridgedParameterList

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've defined a public typealias ParameterList = BridgedParameterList. Is this considered OK or it's required to create a native swift ParameterList containing a var bridged: BridgedParameterList?

Copy link
Contributor

Choose a reason for hiding this comment

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

It depends if you need APIs for ParameterList. E.g. if you want to access the elements, it makes sense to add a native ParameterList, conforming to Sequence, etc.

return decl;
}

BridgedGenericTypeParamDecl BridgedGenericTypeParamDecl_createImplicit(
Copy link
Contributor

Choose a reason for hiding this comment

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

and this?

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 is needed to mimic behavior of cloneGenericParameters - see

/// Clone the generic parameters of the given generic signature and return a new
/// `GenericParamList`.
static GenericParamList *cloneGenericParameters(ASTContext &ctx,
DeclContext *dc,
CanGenericSignature sig) {
SmallVector<GenericTypeParamDecl *, 2> clonedParams;
for (auto paramType : sig.getGenericParams()) {
auto *clonedParam = GenericTypeParamDecl::createImplicit(
dc, paramType->getName(), paramType->getDepth(), paramType->getIndex(),
paramType->getParamKind());
clonedParam->setDeclContext(dc);
clonedParams.push_back(clonedParam);
}
return GenericParamList::create(ctx, SourceLoc(), clonedParams, SourceLoc());
}

Copy link
Contributor Author

@kovdan01 kovdan01 left a comment

Choose a reason for hiding this comment

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

@eeckstein Thanks for a detailed review! I've tried to address all the feedback.

  1. I've resolved the threads which seem trivial enough to avoid cluttering the PR (feel free to unresolve if things do not look fixed from your point of view).
  2. Remaining unresolved threads contain some questions on implementation details - would be glad to continue discussion and finish corresponding fixes after additional clarification.

And here is one more big overall comment on this PR.

I've introduced a bunch of new public typealiases for bridged types which need to be exposed to the AutoDiff closure specialization pass in order to resolve #68944 (to avoid exposing bridges directly as requested in feedback).

Unfortunately, we have a conflict of two different approaches to implementing AST-level bridges.

  1. On the one hand, we have BridgedDeclObj which is accessible via bridged member of Decl class - see SwiftCompilerSources/Sources/AST/Declarations.swift. We have a bunch of Swift classes derived from that, and BridgedDeclObj contains methods which we call from all such derived classes.

  2. On the other hand, we have automatically generated BridgedXXX bridges, where XXX is a name of C++ type: BridgedDecl, BridgedASTContext, BridgedParameterList, etc. Swift is not aware of how these are derived from each other, instead, we have asXXX fields defined where needed, like asDecl, asNominalTypeDecl, etc. These allow derived objects to call methods of bases objects even though Swift is not aware of inheritance structure. For example: newED.asNominalTypeDecl.addMember(newEED.asDecl), where newED and newEED are instances of BridgedEnumDecl and BridgedEnumElementDecl correspondingly.

Bridges from p.2 are primarily used in ASTGen (see lib/ASTGen). We need them for AutoDiff closure specialization pass since we need to create a new specialized branch tracing enum decl. In other words, we literally need to generate AST, not only look at existing AST :)

A conflict which we hit is name collision for some bridges. For example, we already have EnumDecl and EnumElementDecl classes in Swift, which are derived from Decl (with multiple intermediate classes), while Decl contains bridged: BridgedDeclObj field. We also need to use BridgedEnumDecl and BridgedEnumElementDecl, but we can't just typealias them to EnumDecl and EnumElementDecl because these names are already occupied by existing classes.

Right now, I've just temporarily exposed such bridged names "as is" with Bridged prefix.

Given that, what is the correct way of combining two types of bridges mentioned before? Also, I guess that mixing two types of bridges is not very desirable, but I'm not sure how we can avoid that.

return BoxFieldsArray(boxType: self, function: function)
}

public func loweredType(in function: Function) -> Type {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've introduced a new bridge because existing ones (see C++ implementation below) do not take into account AbstractionPattern constructed with function->getLoweredFunctionType()->getSubstGenericSignature().

See existing bridges:

BridgedType BridgedFunction::getLoweredType(BridgedASTType type, bool maximallyAbstracted) const {
if (maximallyAbstracted) {
return BridgedType(getFunction()->getLoweredType(swift::Lowering::AbstractionPattern::getOpaque(), type.type));
}
return BridgedType(getFunction()->getLoweredType(type.type));
}
BridgedType BridgedFunction::getLoweredType(BridgedType type) const {
return BridgedType(getFunction()->getLoweredType(type.unbridged()));
}

I implemented a new bridge in order to be able to mimic behavior of getBranchingTraceEnumLoweredType:

/// Returns the lowered SIL type of the branching trace enum associated with
/// the given original block.
SILType getBranchingTraceEnumLoweredType(SILBasicBlock *origBB) const {
auto *traceDecl = getBranchingTraceDecl(origBB);
auto traceDeclType =
traceDecl->getDeclaredInterfaceType()->getCanonicalType();
Lowering::AbstractionPattern pattern(
derivative->getLoweredFunctionType()->getSubstGenericSignature(),
traceDeclType);
return typeConverter.getLoweredType(pattern, traceDeclType,
TypeExpansionContext::minimal());
}

Should I somehow modify the behavior of existing bridges instead of introducing a new one? E.g. add a new flag with meaning "use this behavior" or smth like that?

return decl;
}

BridgedGenericTypeParamDecl BridgedGenericTypeParamDecl_createImplicit(
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 is needed to mimic behavior of cloneGenericParameters - see

/// Clone the generic parameters of the given generic signature and return a new
/// `GenericParamList`.
static GenericParamList *cloneGenericParameters(ASTContext &ctx,
DeclContext *dc,
CanGenericSignature sig) {
SmallVector<GenericTypeParamDecl *, 2> clonedParams;
for (auto paramType : sig.getGenericParams()) {
auto *clonedParam = GenericTypeParamDecl::createImplicit(
dc, paramType->getName(), paramType->getDepth(), paramType->getIndex(),
paramType->getParamKind());
clonedParam->setDeclContext(dc);
clonedParams.push_back(clonedParam);
}
return GenericParamList::create(ctx, SourceLoc(), clonedParams, SourceLoc());
}

@kovdan01 kovdan01 requested review from eeckstein and rintaro October 15, 2025 18:07
Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

Great progress! I'm happy to see all this APIs being made available.

This is my next set of comments

#define ABSTRACT_DECL(Id, Parent) DECL(Id, Parent)
#include "swift/AST/DeclNodes.def"

// Declare `.asValueDecl` on each BridgedXXXDecl type that's also a
Copy link
Contributor

Choose a reason for hiding this comment

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

you don't need this (see my other comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted .asValueDecl declaration and definition as no longer needed

#define ABSTRACT_CONTEXT_DECL(Id, Parent) CONTEXT_DECL(Id, Parent)
#include "swift/AST/DeclNodes.def"

// Declare `.asGenericContext` on each BridgedXXXDecl type that's also a
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's model GenericContext correctly in swift:

  • add a protocol GenericContext: Decl
  • let all classes which are generic contexts conform to GenericContext
  • implement all the GenericContext APIs as default methods in a protocol extension (no need to do it for each conforming Decl class)

This is similar to what we do with ApplySite or ForwardingInstruction for SIL instructions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created GenericContext protocol, as suggested

void BridgedDecl_forEachDeclToHoist(BridgedDecl decl,
BridgedSwiftClosure closure);

SWIFT_NAME("getter:BridgedDecl.declContext(self:)")
Copy link
Contributor

Choose a reason for hiding this comment

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

The same for DeclContext. Let's make this a protocol in swift

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've introduced DeclContext protocol and made some classes derived from Decl conforming to it (for decls which are also decl contexts). But not only decls might be decl contexts, so I've implemented a fileprivate class DeclContextObj to have a dummy instantiation of DeclContext protocol.

Unfortunately this does not look very nice. Particularly, this is error-prone since one might wrap BridgedDeclContext in DeclContextObj, and trying to access that as Decl would result in nil even if the initial object was indeed a Decl which is also a DeclContext.

What should be the correct way to do this?

Copy link
Contributor

Choose a reason for hiding this comment

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

that's the right way to do it. Just rename DeclContextObj to UnknownDeclContext.
Alternatively we could bridge all the other DeclContext classes to swift. But some expressions are DeclContexts and bridging the whole expression class hierarchy is out of scope for this PR.

return BoxFieldsArray(boxType: self, function: function)
}

public func loweredType(in function: Function) -> Type {
Copy link
Contributor

Choose a reason for hiding this comment

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

I see. Please

  • put this new function next to the existing loweredType in TypeProperties
  • give it another name which points out the difference
  • Add a comment explaining the difference, ideally with a small example

return Location(bridged: bridged.getLocation())
}

public var sourceFile: SourceFile? { SourceFile(bridged: bridged.getSourceFile()) }
Copy link
Contributor

Choose a reason for hiding this comment

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

better:

  • add var declRef: DeclRef? in Function
  • add var sourceFile: SourceFile? in DeclRef`

or even better:

  • add var innermostDeclContext in DeclRef (once you added the protocol DeclContext)
  • add var sourceFile: SourceFile? in DeclContext`

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adopted the first approach. I would be happy to adopt the second one if it's better, but dealing with DeclContext protocol is a bit painful since we have two types of things which should conform to this: some derivatives Decl (which have native swift classes) and several other entities which do not have native swift classes (so we need to instantiate them as some dummy thing like DeclContextObj - see my other comment)

return EnumCases(enumType: self, function: function)
}

public func getEnumCase(in function: Function, at index: Int) -> EnumCase? {
Copy link
Contributor

Choose a reason for hiding this comment

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

add this API as a subscript operator on EnumCases.
With a comment warning about O(n) complexity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added as subscript operator, thanks

Copy link
Contributor Author

@kovdan01 kovdan01 left a comment

Choose a reason for hiding this comment

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

@eeckstein Thanks for a details feedback! I've rebased the PR resolving merge conflicts and addressed the comments. Sometimes I've slightly modified your suggestions - see my replies in corresponding threads.

Also I would be glad to discuss proper DeclContext implementation just in case the current one is not suitable - I personally find it pretty ugly, but I'm not sure how proper implementation should look like keeping inheritance structure of corresponding C++ classes in mind. See my reply corresponding thread.


public typealias FileUnit = BridgedFileUnit

public typealias GenericParamList = BridgedGenericParamList
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Introduced native GenericParamList with corresponding bridged field


public typealias TrailingWhereClause = BridgedTrailingWhereClause

public typealias BridgedParamDecl = ASTBridging.BridgedParamDecl
Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, please do not add this public typealiases for bridging classes for which we already have a native Swift type

Deleted such typealiases

}

extension BridgedEnumDecl {
public static func createParsed(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In order to avoid cluttering BridgedDeclObj with many createXXX methods, I've decided to directly call create static methods of BridgedXXXDecl classes, and then cast results to swift-native XXXDecl classes. Please let me know if this is applicable.

return BoxFieldsArray(boxType: self, function: function)
}

public func loweredType(in function: Function) -> Type {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to loweredTypeWithAbstractionPattern and added a comment.

#define ABSTRACT_DECL(Id, Parent) DECL(Id, Parent)
#include "swift/AST/DeclNodes.def"

// Declare `.asValueDecl` on each BridgedXXXDecl type that's also a
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted .asValueDecl declaration and definition as no longer needed

#define ABSTRACT_CONTEXT_DECL(Id, Parent) CONTEXT_DECL(Id, Parent)
#include "swift/AST/DeclNodes.def"

// Declare `.asGenericContext` on each BridgedXXXDecl type that's also a
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created GenericContext protocol, as suggested

void BridgedDecl_forEachDeclToHoist(BridgedDecl decl,
BridgedSwiftClosure closure);

SWIFT_NAME("getter:BridgedDecl.declContext(self:)")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've introduced DeclContext protocol and made some classes derived from Decl conforming to it (for decls which are also decl contexts). But not only decls might be decl contexts, so I've implemented a fileprivate class DeclContextObj to have a dummy instantiation of DeclContext protocol.

Unfortunately this does not look very nice. Particularly, this is error-prone since one might wrap BridgedDeclContext in DeclContextObj, and trying to access that as Decl would result in nil even if the initial object was indeed a Decl which is also a DeclContext.

What should be the correct way to do this?

@kovdan01 kovdan01 requested a review from eeckstein November 10, 2025 17:03
Copy link
Contributor Author

@kovdan01 kovdan01 left a comment

Choose a reason for hiding this comment

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

@eeckstein Thanks for your feedback! I've submitted updates addressing most of your comments, but I'm still not sure how to properly adopt one of your suggestions. See my reply #84648 (comment).

@kovdan01 kovdan01 requested a review from eeckstein November 17, 2025 11:25
@kovdan01
Copy link
Contributor Author

@eeckstein Thanks for your feedback and detailed explanation for your suggestions! I believe the latest changes I've just submitted should address your comments.

@kovdan01 kovdan01 requested a review from eeckstein November 17, 2025 22:50
Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

lgtm, nice work!

@kovdan01 kovdan01 marked this pull request as ready for review November 18, 2025 15:04
@kovdan01
Copy link
Contributor Author

@swift-ci please test

@kovdan01
Copy link
Contributor Author

@swift-ci please test

@kovdan01
Copy link
Contributor Author

@swift-ci please test

@kovdan01
Copy link
Contributor Author

@swift-ci please test Linux platform

1 similar comment
@kovdan01
Copy link
Contributor Author

@swift-ci please test Linux platform

@kovdan01
Copy link
Contributor Author

@swift-ci please test Linux platform

@aidan-hall
Copy link
Contributor

I'm working on some changes that depend on this PR, so I'm going to merge it. I hope that's OK. Thanks for the contribution!

@aidan-hall aidan-hall merged commit 2c9013b into main Nov 20, 2025
5 checks passed
@aidan-hall aidan-hall deleted the users/kovdan01/ast-bridges-for-autodiff-closure-spec branch November 20, 2025 14:45
@kovdan01
Copy link
Contributor Author

I'm working on some changes that depend on this PR, so I'm going to merge it. I hope that's OK. Thanks for the contribution!

@aidan-hall Ah, I've just finished an updated version of the PR description, but it was anyway too long and probably not that useful. So yeah, I hope that nobody is too worried about this being merged with a short description w/o too much details.

@aidan-hall aidan-hall restored the users/kovdan01/ast-bridges-for-autodiff-closure-spec branch November 21, 2025 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bridging Feature → casting: type bridging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants