Skip to content

Sema: New syntax for @opened archetypes in textual SIL #60429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
4 changes: 4 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,10 @@ class ASTContext final {
bool isRecursivelyConstructingRequirementMachine(
const ProtocolDecl *proto);

/// Retrieve a generic parameter list with a single parameter named `Self`.
/// This is for parsing @opened archetypes in textual SIL.
GenericParamList *getSelfGenericParamList(DeclContext *dc) const;

/// Retrieve a generic signature with a single unconstrained type parameter,
/// like `<T>`.
CanGenericSignature getSingleGenericParameterSignature() const;
Expand Down
6 changes: 6 additions & 0 deletions include/swift/AST/Attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2493,6 +2493,9 @@ class TypeAttributes {
// For an opened existential type, the known ID.
Optional<UUID> OpenedID;

// For an opened existential type, the constraint type.
Optional<TypeRepr *> ConstraintType;

// For a reference to an opaque return type, the mangled name and argument
// index into the generic signature.
struct OpaqueReturnTypeRef {
Expand Down Expand Up @@ -2581,6 +2584,9 @@ class TypeAttributes {
bool hasOpenedID() const { return OpenedID.hasValue(); }
UUID getOpenedID() const { return *OpenedID; }

bool hasConstraintType() const { return ConstraintType.hasValue(); }
TypeRepr *getConstraintType() const { return *ConstraintType; }

/// Given a name like "autoclosure", return the type attribute ID that
/// corresponds to it. This returns TAK_Count on failure.
///
Expand Down
6 changes: 4 additions & 2 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5089,8 +5089,10 @@ ERROR(differentiable_function_type_no_differentiability_parameters,
(/*isLinear*/ bool))

// SIL
ERROR(opened_non_protocol,none,
"@opened cannot be applied to non-protocol type %0", (Type))
ERROR(opened_bad_constraint_type,none,
"@opened constraint type %0 is not a protocol or protocol composition", (Type))
ERROR(opened_bad_interface_type,none,
"@opened interface type %0 is not a type parameter", (Type))
ERROR(sil_function_ellipsis,PointsToFirstBadToken,
"SIL function types cannot be variadic", ())
ERROR(sil_function_input_label,PointsToFirstBadToken,
Expand Down
24 changes: 24 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ struct ASTContext::Implementation {
/// Stores information about lazy deserialization of various declarations.
llvm::DenseMap<const DeclContext *, LazyContextData *> LazyContexts;

/// A fake generic parameter list <Self> for parsing @opened archetypes
/// in textual SIL.
GenericParamList *SelfGenericParamList = nullptr;

/// The single-parameter generic signature with no constraints, <T>.
CanGenericSignature SingleGenericParameterSignature;

Expand Down Expand Up @@ -5152,6 +5156,26 @@ ASTContext::getClangTypeForIRGen(Type ty) {
return getClangTypeConverter().convert(ty).getTypePtrOrNull();
}

GenericParamList *ASTContext::getSelfGenericParamList(DeclContext *dc) const {
auto *theParamList = getImpl().SelfGenericParamList;
if (theParamList)
return theParamList;

// Note: we always return a GenericParamList rooted at the first
// DeclContext this was called with. Since this is just a giant
// hack for SIL mode, that should be OK.
auto *selfParam = GenericTypeParamDecl::create(
dc, Id_Self, SourceLoc(),
/*isTypeSequence=*/false, /*depth=*/0, /*index=*/0,
/*isOpaqueType=*/false, /*opaqueTypeRepr=*/nullptr);

theParamList = GenericParamList::create(
const_cast<ASTContext &>(*this), SourceLoc(), {selfParam}, SourceLoc());
getImpl().SelfGenericParamList = theParamList;

return theParamList;
}

CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
if (auto theSig = getImpl().SingleGenericParameterSignature)
return theSig;
Expand Down
26 changes: 19 additions & 7 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "swift/AST/ExistentialLayout.h"
#include "swift/AST/Expr.h"
#include "swift/AST/FileUnit.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/GenericParamList.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/Module.h"
Expand Down Expand Up @@ -6307,14 +6308,25 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
}

void visitOpenedArchetypeType(OpenedArchetypeType *T) {
if (auto parent = T->getParent()) {
printArchetypeCommon(T);
return;
}
if (Options.PrintForSIL) {
Printer << "@opened(\"" << T->getOpenedExistentialID() << "\", ";
visit(T->getGenericEnvironment()->getOpenedExistentialType());
Printer << ") ";

llvm::DenseMap<CanType, Identifier> newAlternativeTypeNames;
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like this DenseMap could be a SmallDenseMap since it doesn't escape, normally has one entry, and we regularly print giant .sil files (like up to 100MB)


if (Options.PrintForSIL)
Printer << "@opened(\"" << T->getOpenedExistentialID() << "\") ";
visit(T->getExistentialType());
auto interfaceTy = T->getInterfaceType();
auto selfTy = interfaceTy->getRootGenericParam();
auto &ctx = selfTy->getASTContext();
newAlternativeTypeNames[selfTy->getCanonicalType()] = ctx.Id_Self;

PrintOptions subOptions = Options;
subOptions.AlternativeTypeNames = &newAlternativeTypeNames;
TypePrinter sub(Printer, subOptions);
sub.visit(interfaceTy);
} else {
visit(T->getExistentialType());
}
}

void printDependentMember(DependentMemberType *T) {
Expand Down
11 changes: 11 additions & 0 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3715,6 +3715,17 @@ ParserStatus Parser::parseTypeAttribute(TypeAttributes &Attributes,
} else {
diagnose(Tok, diag::opened_attribute_id_value);
}

if (Tok.is(tok::comma)) {
consumeToken(tok::comma);

auto constraintType = parseType(diag::expected_type);
if (constraintType.isNonNull())
Attributes.ConstraintType = constraintType.getPtrOrNull();
} else {
diagnose(Tok, diag::attr_expected_comma, "@opened", false);
}

parseMatchingToken(tok::r_paren, endLoc,
diag::opened_attribute_expected_rparen,
beginLoc);
Expand Down
84 changes: 69 additions & 15 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,10 @@ namespace {
return diags.diagnose(std::forward<ArgTypes>(Args)...);
}

NeverNullType resolveOpenedExistentialArchetype(
TypeAttributes &attrs, TypeRepr *repr,
TypeResolutionOptions options);

NeverNullType resolveAttributedType(AttributedTypeRepr *repr,
TypeResolutionOptions options);
NeverNullType resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
Expand Down Expand Up @@ -2307,6 +2311,67 @@ TypeResolver::resolveAttributedType(AttributedTypeRepr *repr,
return resolveAttributedType(attrs, repr->getTypeRepr(), options);
}

/// In SIL, handle '@opened(UUID, constraintType) interfaceType',
/// which creates an opened archetype.
NeverNullType
TypeResolver::resolveOpenedExistentialArchetype(
TypeAttributes &attrs, TypeRepr *repr,
TypeResolutionOptions options) {
options.setContext(None);

auto *dc = getDeclContext();
auto &ctx = dc->getASTContext();

// The interface type is the type wrapped by the attribute. Resolve it
// with the fake <Self> generic parameter list uniquely stored in the
// ASTContext, and use structural resolution to avoid querying the
// DeclContext's generic signature, which is not the right signature
// for this.
auto structuralResolution = TypeResolution::forStructural(
dc, options,
/*unboundTyOpener*/ nullptr,
/*placeholderHandler*/ nullptr);
TypeResolver interfaceTypeResolver(structuralResolution,
ctx.getSelfGenericParamList(dc));
auto interfaceType = interfaceTypeResolver.resolveType(repr, options);

// The constraint type is stored inside the attribute. It is resolved
// normally, as if it were written in the current context.
auto constraintType = resolveType(attrs.getConstraintType(), options);

Type archetypeType;
if (!constraintType->isExistentialType()) {
diagnoseInvalid(repr, attrs.getLoc(TAK_opened),
diag::opened_bad_constraint_type,
constraintType);

archetypeType = ErrorType::get(constraintType->getASTContext());
} else if (!interfaceType->isTypeParameter()) {
diagnoseInvalid(repr, attrs.getLoc(TAK_opened),
diag::opened_bad_interface_type,
interfaceType);

archetypeType = ErrorType::get(interfaceType->getASTContext());
} {
// The constraint type is written with respect to the surrounding
// generic environment.
constraintType = GenericEnvironment::mapTypeIntoContext(
resolution.getGenericSignature().getGenericEnvironment(),
constraintType);

// The opened existential type is formed by mapping the interface type
// into a new opened generic environment.
archetypeType = OpenedArchetypeType::get(constraintType->getCanonicalType(),
interfaceType,
GenericSignature(),
attrs.getOpenedID());
}

attrs.clearAttribute(TAK_opened);

return archetypeType;
}

NeverNullType
TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
TypeResolutionOptions options) {
Expand Down Expand Up @@ -2715,6 +2780,10 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
attrs.clearAttribute(TAK_unchecked);
}

if (attrs.has(TAK_opened)) {
ty = resolveOpenedExistentialArchetype(attrs, repr, options);
}

auto instanceOptions = options;
instanceOptions.setContext(None);

Expand Down Expand Up @@ -2834,21 +2903,6 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
attrs.clearAttribute(TAK_noDerivative);
}

// In SIL, handle @opened (n), which creates an existential archetype.
if (attrs.has(TAK_opened)) {
if (!ty->isExistentialType()) {
diagnoseInvalid(repr, attrs.getLoc(TAK_opened), diag::opened_non_protocol,
ty);
} else {
ty = GenericEnvironment::mapTypeIntoContext(
resolution.getGenericSignature().getGenericEnvironment(), ty);
ty = OpenedArchetypeType::get(ty->getCanonicalType(),
resolution.getGenericSignature(),
attrs.OpenedID);
}
attrs.clearAttribute(TAK_opened);
}

// In SIL files *only*, permit @weak and @unowned to apply directly to types.
if (attrs.hasOwnership()) {
if (auto SF = getDeclContext()->getParentSourceFile()) {
Expand Down
24 changes: 12 additions & 12 deletions test/ClangImporter/serialization-sil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,38 @@
public func testPartialApply(_ obj: Test) {
// CHECK-LABEL: @$s4Test16testPartialApplyyySoAA_pF : $@convention(thin) (@guaranteed Test) -> () {
if let curried1 = obj.normalObject {
// CHECK: dynamic_method_br [[CURRIED1_OBJ:%.+]] : $@opened([[CURRIED1_EXISTENTIAL:.+]]) Test, #Test.normalObject!foreign, [[CURRIED1_TRUE:[^,]+]], [[CURRIED1_FALSE:[^,]+]]
// CHECK: dynamic_method_br [[CURRIED1_OBJ:%.+]] : $@opened([[CURRIED1_EXISTENTIAL:.+]], Test) Self, #Test.normalObject!foreign, [[CURRIED1_TRUE:[^,]+]], [[CURRIED1_FALSE:[^,]+]]
// CHECK: [[CURRIED1_FALSE]]:
// CHECK: [[CURRIED1_TRUE]]([[CURRIED1_METHOD:%.+]] : $@convention(objc_method) (@opened([[CURRIED1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject):
// CHECK: [[CURRIED1_TRUE]]([[CURRIED1_METHOD:%.+]] : $@convention(objc_method) (@opened([[CURRIED1_EXISTENTIAL]], Test) Self) -> @autoreleased AnyObject):
// CHECK: [[CURRIED1_OBJECT_COPY:%.*]] = copy_value [[CURRIED1_OBJ]]
// CHECK: [[CURRIED1_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[CURRIED1_METHOD]]([[CURRIED1_OBJECT_COPY]]) : $@convention(objc_method) (@opened([[CURRIED1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject
// CHECK: [[CURRIED1_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[CURRIED1_METHOD]]([[CURRIED1_OBJECT_COPY]]) : $@convention(objc_method) (@opened([[CURRIED1_EXISTENTIAL]], Test) Self) -> @autoreleased AnyObject
// CHECK: [[CURRIED1_THUNK:%.+]] = function_ref @$syXlIego_ypIegr_TR : $@convention(thin) (@guaranteed @callee_guaranteed () -> @owned AnyObject) -> @out Any
// CHECK: = partial_apply [callee_guaranteed] [[CURRIED1_THUNK]]([[CURRIED1_PARTIAL]])
curried1()
}
if let curried2 = obj.innerPointer {
// CHECK: dynamic_method_br [[CURRIED2_OBJ:%.+]] : $@opened([[CURRIED2_EXISTENTIAL:.+]]) Test, #Test.innerPointer!foreign, [[CURRIED2_TRUE:[^,]+]], [[CURRIED2_FALSE:[^,]+]]
// CHECK: dynamic_method_br [[CURRIED2_OBJ:%.+]] : $@opened([[CURRIED2_EXISTENTIAL:.+]], Test) Self, #Test.innerPointer!foreign, [[CURRIED2_TRUE:[^,]+]], [[CURRIED2_FALSE:[^,]+]]
// CHECK: [[CURRIED2_FALSE]]:
// CHECK: [[CURRIED2_TRUE]]([[CURRIED2_METHOD:%.+]] : $@convention(objc_method) (@opened([[CURRIED2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutableRawPointer):
// CHECK: [[CURRIED2_TRUE]]([[CURRIED2_METHOD:%.+]] : $@convention(objc_method) (@opened([[CURRIED2_EXISTENTIAL]], Test) Self) -> @unowned_inner_pointer UnsafeMutableRawPointer):
// CHECK: [[CURRIED2_OBJ_COPY:%.*]] = copy_value [[CURRIED2_OBJ]]
// CHECK: [[CURRIED2_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[CURRIED2_METHOD]]([[CURRIED2_OBJ_COPY]]) : $@convention(objc_method) (@opened([[CURRIED2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutableRawPointer
// CHECK: [[CURRIED2_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[CURRIED2_METHOD]]([[CURRIED2_OBJ_COPY]]) : $@convention(objc_method) (@opened([[CURRIED2_EXISTENTIAL]], Test) Self) -> @unowned_inner_pointer UnsafeMutableRawPointer
curried2()
}
if let prop1 = obj.normalObjectProp {
// CHECK: dynamic_method_br [[PROP1_OBJ:%.+]] : $@opened([[PROP1_EXISTENTIAL:.+]]) Test, #Test.normalObjectProp!getter.foreign, [[PROP1_TRUE:[^,]+]], [[PROP1_FALSE:[^,]+]]
// CHECK: dynamic_method_br [[PROP1_OBJ:%.+]] : $@opened([[PROP1_EXISTENTIAL:.+]], Test) Self, #Test.normalObjectProp!getter.foreign, [[PROP1_TRUE:[^,]+]], [[PROP1_FALSE:[^,]+]]
// CHECK: [[PROP1_FALSE]]:
// CHECK: [[PROP1_TRUE]]([[PROP1_METHOD:%.+]] : $@convention(objc_method) (@opened([[PROP1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject):
// CHECK: [[PROP1_TRUE]]([[PROP1_METHOD:%.+]] : $@convention(objc_method) (@opened([[PROP1_EXISTENTIAL]], Test) Self) -> @autoreleased AnyObject):
// CHECK: [[PROP1_OBJ_COPY:%.*]] = copy_value [[PROP1_OBJ]]
// CHECK: [[PROP1_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[PROP1_METHOD]]([[PROP1_OBJ_COPY]]) : $@convention(objc_method) (@opened([[PROP1_EXISTENTIAL]]) Test) -> @autoreleased AnyObject
// CHECK: [[PROP1_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[PROP1_METHOD]]([[PROP1_OBJ_COPY]]) : $@convention(objc_method) (@opened([[PROP1_EXISTENTIAL]], Test) Self) -> @autoreleased AnyObject
// CHECK: = apply [[PROP1_PARTIAL]]() : $@callee_guaranteed () -> @owned AnyObject
_ = prop1
}
if let prop2 = obj.innerPointerProp {
// CHECK: dynamic_method_br [[PROP2_OBJ:%.+]] : $@opened([[PROP2_EXISTENTIAL:.+]]) Test, #Test.innerPointerProp!getter.foreign, [[PROP2_TRUE:[^,]+]], [[PROP2_FALSE:[^,]+]]
// CHECK: dynamic_method_br [[PROP2_OBJ:%.+]] : $@opened([[PROP2_EXISTENTIAL:.+]], Test) Self, #Test.innerPointerProp!getter.foreign, [[PROP2_TRUE:[^,]+]], [[PROP2_FALSE:[^,]+]]
// CHECK: [[PROP2_FALSE]]:
// CHECK: [[PROP2_TRUE]]([[PROP2_METHOD:%.+]] : $@convention(objc_method) (@opened([[PROP2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutableRawPointer):
// CHECK: [[PROP2_TRUE]]([[PROP2_METHOD:%.+]] : $@convention(objc_method) (@opened([[PROP2_EXISTENTIAL]], Test) Self) -> @unowned_inner_pointer UnsafeMutableRawPointer):
// CHECK: [[PROP2_OBJ_COPY:%.*]] = copy_value [[PROP2_OBJ]]
// CHECK: [[PROP2_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[PROP2_METHOD]]([[PROP2_OBJ_COPY]]) : $@convention(objc_method) (@opened([[PROP2_EXISTENTIAL]]) Test) -> @unowned_inner_pointer UnsafeMutableRawPointer
// CHECK: [[PROP2_PARTIAL:%.+]] = partial_apply [callee_guaranteed] [[PROP2_METHOD]]([[PROP2_OBJ_COPY]]) : $@convention(objc_method) (@opened([[PROP2_EXISTENTIAL]], Test) Self) -> @unowned_inner_pointer UnsafeMutableRawPointer
// CHECK: = apply [[PROP2_PARTIAL]]() : $@callee_guaranteed () -> UnsafeMutableRawPointer
_ = prop2
}
Expand Down
22 changes: 11 additions & 11 deletions test/Constraints/ranking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,35 +32,35 @@ func genericNoOptional<T>(_: T) {}

// CHECK-LABEL: sil hidden [ossa] @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlF
func propertyVersusFunction<T : P>(_ p: P, _ t: T) {
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
let _ = p.p
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
let _: P = p.p
// CHECK: function_ref @$s7ranking22propertyVersusFunctionyyAA1P_p_xtAaCRzlFyAaC_pcAaC_pcfu_ : $@convention(thin) (@in_guaranteed P) -> @owned @callee_guaranteed (@in_guaranteed P) -> ()
let _: (P) -> () = p.p
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
let _: P? = p.p
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
let _: Any = p.p
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
let _: Any? = p.p

// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
// CHECK: function_ref @$s7ranking15genericOverloadyyxlF
genericOverload(p.p)
// CHECK: witness_method $@opened("{{.*}}") P, #P.q!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.q!getter
// CHECK: function_ref @$s7ranking15genericOverloadyyxSglF
genericOverload(p.q)
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
// CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
genericOptional(p.p)
// CHECK: witness_method $@opened("{{.*}}") P, #P.q!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.q!getter
// CHECK: function_ref @$s7ranking15genericOptionalyyxSglF
genericOptional(p.q)
// CHECK: witness_method $@opened("{{.*}}") P, #P.p!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.p!getter
// CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
genericNoOptional(p.p)
// CHECK: witness_method $@opened("{{.*}}") P, #P.q!getter
// CHECK: witness_method $@opened("{{.*}}", P) Self, #P.q!getter
// CHECK: function_ref @$s7ranking17genericNoOptionalyyxlF
genericNoOptional(p.q)

Expand Down
6 changes: 3 additions & 3 deletions test/IRGen/async/run-call-existential-to-void.sil
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ bb0(%int : $Int64, %S_type : $@thin S.Type):
// CHECK-LL: define hidden swift{{(tail)?}}cc void @existentialToVoid(
sil hidden @existentialToVoid : $@async @convention(thin) (@in_guaranteed P) -> () {
bb0(%existential : $*P):
%existential_addr = open_existential_addr immutable_access %existential : $*P to $*@opened("B2796A9C-FEBE-11EA-84BB-D0817AD71B77") P
%existential_addr = open_existential_addr immutable_access %existential : $*P to $*@opened("B2796A9C-FEBE-11EA-84BB-D0817AD71B77", P) Self
%any = alloc_stack $Any
%any_addr = init_existential_addr %any : $*Any, $@opened("B2796A9C-FEBE-11EA-84BB-D0817AD71B77") P
copy_addr %existential_addr to [initialization] %any_addr : $*@opened("B2796A9C-FEBE-11EA-84BB-D0817AD71B77") P
%any_addr = init_existential_addr %any : $*Any, $@opened("B2796A9C-FEBE-11EA-84BB-D0817AD71B77", P) Self
copy_addr %existential_addr to [initialization] %any_addr : $*@opened("B2796A9C-FEBE-11EA-84BB-D0817AD71B77", P) Self
%printAny = function_ref @printAny : $@convention(thin) (@in_guaranteed Any) -> ()
%result = apply %printAny(%any) : $@convention(thin) (@in_guaranteed Any) -> ()
destroy_addr %any : $*Any
Expand Down
Loading