diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 352808d332a41..cf5c3e1409c45 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -2434,6 +2434,16 @@ static CanSILFunctionType getSILFunctionTypeForInitAccessor( ParameterConvention::Indirect_Inout)); } + // Make a new 'self' parameter. + auto selfInterfaceType = MetatypeType::get( + accessor->getDeclContext()->getSelfInterfaceType()); + AbstractionPattern origSelfType(genericSig, + selfInterfaceType->getCanonicalType()); + auto loweredSelfType = TC.getLoweredType( + origSelfType, selfInterfaceType->getCanonicalType(), context); + inputs.push_back(SILParameterInfo(loweredSelfType.getASTType(), + ParameterConvention::Direct_Unowned)); + SmallVector results; // initialized properties appear as `@out` results because they are diff --git a/lib/SILGen/SILGenConstructor.cpp b/lib/SILGen/SILGenConstructor.cpp index 714c15eb606eb..820ad973ad5a5 100644 --- a/lib/SILGen/SILGenConstructor.cpp +++ b/lib/SILGen/SILGenConstructor.cpp @@ -91,29 +91,23 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF, } static SILValue emitConstructorMetatypeArg(SILGenFunction &SGF, - ValueDecl *ctor) { + ValueDecl *decl) { // In addition to the declared arguments, the constructor implicitly takes // the metatype as its first argument, like a static function. - auto ctorFnType = ctor->getInterfaceType()->castTo(); - assert(ctorFnType->getParams().size() == 1 && - "more than one self parameter?"); - auto param = ctorFnType->getParams()[0]; - assert(!param.isVariadic() && !param.isInOut()); - Type metatype = param.getPlainType(); - auto *DC = ctor->getInnermostDeclContext(); - auto &AC = SGF.getASTContext(); + auto metatypeTy = MetatypeType::get( + decl->getDeclContext()->getSelfInterfaceType()); + auto *DC = decl->getInnermostDeclContext(); + auto &ctx = SGF.getASTContext(); auto VD = - new (AC) ParamDecl(SourceLoc(), SourceLoc(), - AC.getIdentifier("$metatype"), SourceLoc(), - AC.getIdentifier("$metatype"), DC); + new (ctx) ParamDecl(SourceLoc(), SourceLoc(), + ctx.getIdentifier("$metatype"), SourceLoc(), + ctx.getIdentifier("$metatype"), DC); VD->setSpecifier(ParamSpecifier::Default); - VD->setInterfaceType(metatype); + VD->setInterfaceType(metatypeTy); - SGF.AllocatorMetatype = SGF.F.begin()->createFunctionArgument( - SGF.getLoweredTypeForFunctionArgument(DC->mapTypeIntoContext(metatype)), + return SGF.F.begin()->createFunctionArgument( + SGF.getLoweredTypeForFunctionArgument(DC->mapTypeIntoContext(metatypeTy)), VD); - - return SGF.AllocatorMetatype; } // FIXME: Consolidate this with SILGenProlog @@ -273,7 +267,8 @@ static RValue maybeEmitPropertyWrapperInitFromValue( static void emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc, AccessorDecl *accessor, SILValue selfValue, - SILType selfTy, RValue &&initialValue) { + Type selfIfaceTy, SILType selfTy, + RValue &&initialValue) { SmallVector arguments; auto emitFieldReference = [&](VarDecl *field, bool forInit = false) { @@ -297,6 +292,10 @@ emitApplyOfInitAccessor(SILGenFunction &SGF, SILLocation loc, arguments.push_back(emitFieldReference(property)); } + // The `self` metatype. + auto metatypeTy = MetatypeType::get(accessor->mapTypeIntoContext(selfIfaceTy)); + arguments.push_back(SGF.B.createMetatype(loc, SGF.getLoweredType(metatypeTy))); + SubstitutionMap subs; if (auto *env = accessor->getDeclContext()->getGenericEnvironmentOfContext()) { @@ -387,7 +386,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF, loweredParams)); } - emitConstructorMetatypeArg(SGF, ctor); + SGF.AllocatorMetatype = emitConstructorMetatypeArg(SGF, ctor); (void) loweredParams.claimNext(); loweredParams.finish(); @@ -418,8 +417,8 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF, assert(elti != eltEnd && "number of args does not match number of fields"); - emitApplyOfInitAccessor(SGF, Loc, initAccessor, resultSlot, selfTy, - std::move(*elti)); + emitApplyOfInitAccessor(SGF, Loc, initAccessor, resultSlot, + selfIfaceTy, selfTy, std::move(*elti)); ++elti; continue; } @@ -666,7 +665,7 @@ void SILGenFunction::emitValueConstructor(ConstructorDecl *ctor) { ctor->getEffectiveThrownErrorType(), ctor->getThrowsLoc(), /*ignored parameters*/ 1); - emitConstructorMetatypeArg(*this, ctor); + AllocatorMetatype = emitConstructorMetatypeArg(*this, ctor); // Make sure we've hopped to the right global actor, if any. if (ctor->hasAsync()) { @@ -897,7 +896,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) { } // Emit the metatype argument. - emitConstructorMetatypeArg(*this, element); + AllocatorMetatype = emitConstructorMetatypeArg(*this, element); (void) loweredParams.claimNext(); loweredParams.finish(); @@ -957,7 +956,8 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) { if (ctor->requiresUnavailableDeclABICompatibilityStubs()) emitApplyOfUnavailableCodeReached(); - SILValue selfMetaValue = emitConstructorMetatypeArg(*this, ctor); + AllocatorMetatype = emitConstructorMetatypeArg(*this, ctor); + SILValue selfMetaValue = AllocatorMetatype; // Allocate the "self" value. VarDecl *selfDecl = ctor->getImplicitSelfDecl(); @@ -1758,18 +1758,20 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) { // Emit `newValue` argument. emitBasicProlog(accessor, - accessor->getParameters(), /*selfParam=*/nullptr, + accessor->getParameters(), + /*selfParam=*/nullptr, TupleType::getEmpty(F.getASTContext()), /*errorType=*/llvm::None, /*throwsLoc=*/SourceLoc(), /*ignored parameters*/ - accessedProperties.size()); + accessedProperties.size() + 1); // Emit arguments for all `accesses` properties. if (!accessedProperties.empty()) { auto propertyIter = accessedProperties.begin(); auto propertyArgs = accessorTy->getParameters().slice( - accessorTy->getNumParameters() - accessedProperties.size()); + accessorTy->getNumParameters() - accessedProperties.size() - 1, + accessedProperties.size()); for (const auto &argument : propertyArgs) { createArgument(*propertyIter, getSILTypeInContext(argument, accessorTy)); @@ -1777,6 +1779,9 @@ void SILGenFunction::emitInitAccessor(AccessorDecl *accessor) { } } + // Emit `self` argument. + emitConstructorMetatypeArg(*this, accessor); + prepareEpilog(accessor, accessor->getResultInterfaceType(), accessor->getEffectiveThrownErrorType(), diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index d573c55777916..41eb49cd53e50 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -1882,26 +1882,49 @@ void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue, if (!substitutions.empty()) fieldTy = fieldTy.subst(substitutions); + auto *initAccessor = field->getOpaqueAccessor(AccessorKind::Init); + // Emit the init accessor function partially applied to the base. SILValue initFRef = emitGlobalFunctionRef( - loc, getAccessorDeclRef(field->getOpaqueAccessor(AccessorKind::Init))); + loc, getAccessorDeclRef(initAccessor)); auto initTy = initFRef->getType().castTo(); - if (!substitutions.empty()) { - // If there are substitutions we need to emit partial apply to - // apply substitutions to the init accessor reference type. - initTy = initTy->substGenericArgs(SGM.M, substitutions, - getTypeExpansionContext()); + // If there are substitutions we need to emit partial apply to + // apply substitutions to the init accessor reference type. + initTy = initTy->substGenericArgs(SGM.M, substitutions, + getTypeExpansionContext()); + + // Emit partial apply with self metatype argument to produce a substituted + // init accessor reference. + auto selfTy = selfValue.getType().getASTType(); + auto metatypeTy = MetatypeType::get(selfTy); - // Emit partial apply without argument to produce a substituted - // init accessor reference. - PartialApplyInst *initPAI = - B.createPartialApply(loc, initFRef, substitutions, ArrayRef(), - ParameterConvention::Direct_Guaranteed); - initFRef = emitManagedRValueWithCleanup(initPAI).getValue(); + SILValue selfMetatype; + if (selfTy->getClassOrBoundGenericClass()) { + selfMetatype = B.createValueMetatype(loc, getLoweredType(metatypeTy), + selfValue).getValue(); + } else { + selfMetatype = B.createMetatype(loc, getLoweredType(metatypeTy)); } + auto expectedSelfTy = initAccessor->getDeclContext()->getSelfInterfaceType() + .subst(substitutions); + + // This should only happen in the invalid case where we attempt to initialize + // superclass storage from a subclass initializer. However, we shouldn't + // crash, so emit the appropriate cast so that we can recover and diagnose + // later. + if (!expectedSelfTy->isEqual(selfTy)) { + selfMetatype = B.createUpcast(loc, selfMetatype, + getLoweredType(MetatypeType::get(expectedSelfTy))); + } + PartialApplyInst *initPAI = + B.createPartialApply(loc, initFRef, substitutions, selfMetatype, + ParameterConvention::Direct_Guaranteed, + PartialApplyInst::OnStackKind::OnStack); + initFRef = emitManagedRValueWithCleanup(initPAI).getValue(); + // Check whether value is supposed to be passed indirectly and // materialize if required. { diff --git a/test/IRGen/init_accessor_dynamic_self.swift b/test/IRGen/init_accessor_dynamic_self.swift new file mode 100644 index 0000000000000..1835ef9e0e890 --- /dev/null +++ b/test/IRGen/init_accessor_dynamic_self.swift @@ -0,0 +1,21 @@ +// RUN: %target-swift-frontend -emit-ir %s + +public class C { + private var _count: Int + + var count: Int { + @storageRestrictions(initializes: _count) + init { + print(Self.self) // crash here + _count = newValue + } + get { _count } + set { } + } + + init() { + count = 0 + } +} + +let c = C() diff --git a/test/Interpreter/init_accessors.swift b/test/Interpreter/init_accessors.swift index dcbed65b7256e..d8e2ee7c2bc64 100644 --- a/test/Interpreter/init_accessors.swift +++ b/test/Interpreter/init_accessors.swift @@ -922,3 +922,35 @@ do { // CHECK-NEXT: init accessor is called: 42 // CHECK-NEXT: nonmutating set called: 0 // CHECK-NEXT: test-nonmutating-set-4: TestNonMutatingSetCustom(_count: 42) + +do { + class Base { + var _count: Int + + var count: Int { + @storageRestrictions(initializes: _count) + init { + print("init accessor with Self = \(Self.self)") + _count = newValue + } + + get { _count } + + set {} + } + + init() { + count = 42 + } + } + + class Sub: Base {} + + print("- init accessor vs dynamic Self") + _ = Base() + _ = Sub() +} + +// CHECK-NEXT: - init accessor vs dynamic Self +// CHECK-NEXT: init accessor with Self = Base +// CHECK-NEXT: init accessor with Self = Sub \ No newline at end of file diff --git a/test/SILOptimizer/init_accessor_raw_sil_lowering.swift b/test/SILOptimizer/init_accessor_raw_sil_lowering.swift index 653eb70c552fe..44be314b81420 100644 --- a/test/SILOptimizer/init_accessor_raw_sil_lowering.swift +++ b/test/SILOptimizer/init_accessor_raw_sil_lowering.swift @@ -47,11 +47,11 @@ final class TestIndirectionThroughStorage { // CHECK: [[STORAGE_INIT:%.*]] = function_ref @$s23assign_or_init_lowering29TestIndirectionThroughStorageC8_storage33_DE106275C2F16FB3D05881E72FBD87C8LLAA0H0_pAC1TAaFPRts_XPvpfi : $@convention(thin) () -> @out any Storage // CHECK-NEXT: {{.*}} = apply [[STORAGE_INIT]]([[STORAGE_REF]]) : $@convention(thin) () -> @out any Storage // Initialization: - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@convention(thin) (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@convention(thin) (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@noescape @callee_guaranteed (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () // Explicit set: - // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@convention(thin) (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () - // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@convention(thin) (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () + // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: assign_or_init [set] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@noescape @callee_guaranteed (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () init(name: String, age: Int) { self.name = name self.age = age @@ -63,8 +63,8 @@ final class TestIndirectionThroughStorage { // CHECK: [[STORAGE_INIT:%.*]] = function_ref @$s23assign_or_init_lowering29TestIndirectionThroughStorageC8_storage33_DE106275C2F16FB3D05881E72FBD87C8LLAA0H0_pAC1TAaFPRts_XPvpfi : $@convention(thin) () -> @out any Storage // CHECK-NEXT: {{.*}} = apply [[STORAGE_INIT]]([[STORAGE_REF]]) : $@convention(thin) () -> @out any Storage // Initialization: - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@convention(thin) (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () - // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@convention(thin) (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.name, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: assign_or_init [init] #TestIndirectionThroughStorage.age, self [[SELF]] : $TestIndirectionThroughStorage, value {{.*}} : $Optional, init {{.*}} : $@noescape @callee_guaranteed (Optional, @inout any Storage) -> (), set {{.*}} : $@noescape @callee_guaranteed (Optional) -> () // Explicit set: // CHECK: [[STORAGE_SETTER:%.*]] = function_ref @$s23assign_or_init_lowering29TestIndirectionThroughStorageC7storageAA0H0_pAC1TAaEPRts_XPvs : $@convention(method) (@in any Storage, @guaranteed TestIndirectionThroughStorage) -> () // CHECK-NEXT: {{.*}} = apply [[STORAGE_SETTER]]({{.*}}, [[SELF]]) : $@convention(method) (@in any Storage, @guaranteed TestIndirectionThroughStorage) -> () @@ -104,8 +104,8 @@ struct TestAccessOfOnePatternVars { // CHECK-NEXT: {{.*}} = apply [[Y_INIT]]() : $@convention(thin) () -> @owned String // CHECK-NOT: [[X_REF:%.*]] = struct_element_addr %3 : $*TestAccessOfOnePatternVars, #TestAccessOfOnePatternVars.x // CHECK-NOT: [[Y_REF:%.*]] = struct_element_addr {{.*}} : $*TestAccessOfOnePatternVars, #TestAccessOfOnePatternVars.y - // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.data, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $(Int, String), init {{.*}} : $@convention(thin) (Int, @owned String, @inout Int, @inout String) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int, @owned String) -> () - // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.other, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $Bool, init {{.*}} : $@convention(thin) (Bool, @inout Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Bool) -> () + // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.data, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $(Int, String), init {{.*}} : $@noescape @callee_guaranteed (Int, @owned String, @inout Int, @inout String) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int, @owned String) -> () + // CHECK: assign_or_init [init] #TestAccessOfOnePatternVars.other, self {{.*}} : $*TestAccessOfOnePatternVars, value {{.*}} : $Bool, init {{.*}} : $@noescape @callee_guaranteed (Bool, @inout Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Bool) -> () init(x: Int, y: String) { self.x = x self.y = y @@ -139,15 +139,18 @@ struct Test1 { // CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering5Test1V1aACSi_tcfC : $@convention(method) (Int, @thin Test1.Type) -> @owned Test1 init(a: Int) { - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int) -> @out Int - // CHECK: assign_or_init [init] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: assign_or_init [init] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () self.a = a - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1bSSvi : $@convention(thin) (@owned String) -> (@out Int, @out String) - // CHECK: assign_or_init [init] [assign=0] #Test1.b, self {{.*}}, value [[VALUE:%.*]] : $String, init [[INIT_REF]] : $@convention(thin) (@owned String) -> (@out Int, @out String), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1bSSvi : $@convention(thin) (@owned String, @thin Test1.Type) -> (@out Int, @out String) + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (@owned String, @thin Test1.Type) -> (@out Int, @out String) + // CHECK: assign_or_init [init] [assign=0] #Test1.b, self {{.*}}, value [[VALUE:%.*]] : $String, init [[INIT_REF]] : $@noescape @callee_guaranteed (@owned String) -> (@out Int, @out String), set {{.*}} : $@noescape @callee_guaranteed (@owned String) -> () self.a = -1 self.b = "" - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int) -> @out Int - // CHECK: assign_or_init [set] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering5Test1V1aSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: assign_or_init [set] #Test1.a, self {{.*}}, value [[VALUE:%.*]] : $Int, init [[INIT_REF]] : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () self.a = a } } @@ -170,18 +173,18 @@ struct Test2 { // CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering5Test2V1a1bACyxGSi_xtcfC : $@convention(method) (Int, @in T, @thin Test2.Type) -> @out Test2 init(a: Int, b: T) { - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [[INIT_REF]]() : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK: assign_or_init [init] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () + // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF]](%3) : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK: assign_or_init [init] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@noescape @callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () self.pair = (a, b) - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [[INIT_REF]]() : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK: assign_or_init [init] [assign=0] [assign=1] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () + // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF]](%3) : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK: assign_or_init [init] [assign=0] [assign=1] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@noescape @callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () self.pair = (0, b) self._c = "" - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [[INIT_REF]]() : $@convention(thin) <τ_0_0> (Int, @in τ_0_0) -> (@out Int, @out τ_0_0) - // CHECK: assign_or_init [set] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () + // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering5Test2V4pairSi_xtvi : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF]](%3) : $@convention(thin) <τ_0_0> (Int, @in τ_0_0, @thin Test2<τ_0_0>.Type) -> (@out Int, @out τ_0_0) + // CHECK: assign_or_init [set] #Test2.pair, self {{.*}}, value [[VALUE:%.*]] : $*(Int, T), init [[SUBST_INIT_REF]] : $@noescape @callee_guaranteed (Int, @in T) -> (@out Int, @out T), set {{.*}} : $@noescape @callee_guaranteed (Int, @in T) -> () self.pair = (1, b) } } @@ -197,8 +200,9 @@ struct Test { // CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering4TestV1vACSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test init(v: Int) { - // CHECK: [[INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering4TestV4testSivi : $@convention(thin) (Int) -> () - // CHECK: assign_or_init [init] #Test.test, self {{.*}}, value %0 : $Int, init [[INIT_REF]] : $@convention(thin) (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s23assign_or_init_lowering4TestV4testSivi : $@convention(thin) (Int, @thin Test.Type) -> () + // CHECK-NEXT: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%1) : $@convention(thin) (Int, @thin Test.Type) -> () + // CHECK: assign_or_init [init] #Test.test, self {{.*}}, value %0 : $Int, init [[INIT_REF]] : $@noescape @callee_guaranteed (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> () self.test = v } } @@ -225,10 +229,11 @@ func test_default_inits() { // CHECK: [[DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[INIT_VAL:%.*]] = apply [[DEFAULT]]() : $@convention(thin) () -> Int // CHECK-NEXT: [[SELF_REF:%.*]] = begin_access [modify] [static] [[SELF]] : $*Test1 - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%0) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivs : $@convention(method) (Int, @inout Test1) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF_REF]]) : $@convention(method) (Int, @inout Test1) -> () - // CHECK-NEXT: assign_or_init [init] #Test1.x, self %2 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@convention(thin) (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () + // CHECK-NEXT: assign_or_init [init] #Test1.x, self %2 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () // CHECK-NEXT: end_access [[SELF_REF]] : $*Test1 // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () init() { @@ -239,14 +244,15 @@ func test_default_inits() { // CHECK: [[DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[INIT_VAL:%.*]] = apply [[DEFAULT]]() : $@convention(thin) () -> Int // CHECK-NEXT: [[SELF_REF:%.*]] = begin_access [modify] [static] [[SELF]] : $*Test1 - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivi : $@convention(thin) (Int, @thin Test1.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%1) : $@convention(thin) (Int, @thin Test1.Type) -> @out Int // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test1L_V1xSivs : $@convention(method) (Int, @inout Test1) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF_REF]]) : $@convention(method) (Int, @inout Test1) -> () - // CHECK-NEXT: assign_or_init [init] #Test1.x, self %3 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@convention(thin) (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () + // CHECK-NEXT: assign_or_init [init] #Test1.x, self %3 : $*Test1, value [[INIT_VAL]] : $Int, init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () // CHECK-NEXT: end_access [[SELF_REF]] : $*Test1 // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (Int) -> () // - // CHECK: assign_or_init [set] #Test1.x, self {{.*}} : $*Test1, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [set] #Test1.x, self {{.*}} : $*Test1, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () init(x: Int) { self.x = x } @@ -276,13 +282,14 @@ func test_default_inits() { // CHECK-NEXT: [[NEW_VALUE_1:%.*]] = tuple_element_addr [[NEW_VALUE]] : $*(T, String), 1 // CHECK-NEXT: copy_addr [take] [[T]] to [init] [[NEW_VALUE_0]] : $*T // CHECK-NEXT: store [[STR]] to [init] [[NEW_VALUE_1]] : $*String - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) - // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [[INIT_ACCESSOR_REF]]() : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) + // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick Test2.Type, {{%.*}} + // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_REF]]([[METATYPE]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvs : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () - // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () - // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String) + // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String) // CHECK-NEXT: dealloc_stack [[NEW_VALUE]] : $*(T, String) // CHECK-NEXT: dealloc_stack [[T]] : $*T init() { @@ -299,19 +306,20 @@ func test_default_inits() { // CHECK-NEXT: [[NEW_VALUE_1:%.*]] = tuple_element_addr [[NEW_VALUE]] : $*(T, String), 1 // CHECK-NEXT: copy_addr [take] [[T]] to [init] [[NEW_VALUE_0]] : $*T // CHECK-NEXT: store [[STR]] to [init] [[NEW_VALUE_1]] : $*String - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) - // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [[INIT_ACCESSOR_REF]]() : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String) -> @out (τ_0_0, String) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvi : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) + // CHECK-NEXT: [[METATYPE:%.*]] = value_metatype $@thick Test2.Type, {{%.*}} + // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_REF]]([[METATYPE]]) : $@convention(thin) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @thick Test2<τ_0_0>.Type) -> @out (τ_0_0, String) // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test2L_C1xx_SStvs : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () // CHECK-NEXT: [[SETTER:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) <τ_0_0 where τ_0_0 : Initializable> (@in τ_0_0, @owned String, @guaranteed Test2<τ_0_0>) -> () - // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK-NEXT: assign_or_init [init] #Test2.x, self [[SELF]] : $Test2, value [[NEW_VALUE]] : $*(T, String), init [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () // CHECK-NEXT: destroy_value [[SETTER]] : $@noescape @callee_guaranteed (@in T, @owned String) -> () - // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@callee_guaranteed (@in T, @owned String) -> @out (T, String) + // CHECK-NEXT: destroy_value [[INIT_ACCESSOR]] : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String) // CHECK-NEXT: dealloc_stack [[NEW_VALUE]] : $*(T, String) // CHECK-NEXT: dealloc_stack [[T]] : $*T // - // CHECK: assign_or_init [init] [assign=0] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK: assign_or_init [init] [assign=0] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () // CHECK: assign %2 to [init] [[Y_REF:%.*]] : $*Int - // CHECK: assign_or_init [set] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () + // CHECK: assign_or_init [set] #Test2.x, self [[SELF]] : $Test2, value {{.*}} : $*(T, String), init {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> @out (T, String), set {{.*}} : $@noescape @callee_guaranteed (@in T, @owned String) -> () init(x: (T, String), y: Int) { self.x = x self.y = y @@ -371,10 +379,10 @@ func test_default_inits() { // CHECK: [[SL:%.*]] = mark_uninitialized [rootself] %0 // CHECK: [[X_DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test4L_C1xSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[X_VALUE:%.*]] = apply [[X_DEFAULT]]() : $@convention(thin) () -> Int - // CHECK: assign_or_init [init] #Test4.x, self [[SL]] : $Test4, value [[X_VALUE]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set undef : $@convention(thin) (Int) -> @out Int + // CHECK: assign_or_init [init] #Test4.x, self [[SL]] : $Test4, value [[X_VALUE]] : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set undef : $@noescape @callee_guaranteed (Int) -> @out Int // CHECK: [[Y_DEFAULT:%.*]] = function_ref @$s23assign_or_init_lowering18test_default_initsyyF5Test4L_C1ySSvpfi : $@convention(thin) () -> @owned String // CHECK-NEXT: [[Y_VALUE:%.*]] = apply [[Y_DEFAULT]]() : $@convention(thin) () -> @owned String - // CHECK: assign_or_init [init] #Test4.y, self [[SL]] : $Test4, value [[Y_VALUE]] : $String, init {{.*}} : $@convention(thin) (@owned String) -> @out String, set undef : $@convention(thin) (@owned String) -> @out String + // CHECK: assign_or_init [init] #Test4.y, self [[SL]] : $Test4, value [[Y_VALUE]] : $String, init {{.*}} : $@noescape @callee_guaranteed (@owned String) -> @out String, set undef : $@noescape @callee_guaranteed (@owned String) -> @out String } } @@ -423,9 +431,9 @@ func test_handling_of_nonmutating_set() { // CHECK-LABEL: sil private [ossa] @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF4TestL_V5countADSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test // CHECK: [[INIT_VALUE:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF4TestL_V5countSivpfi : $@convention(thin) () -> Int // CHECK-NEXT: [[VALUE:%.*]] = apply [[INIT_VALUE]]() : $@convention(thin) () -> Int - // CHECK: assign_or_init [init] #Test.count, self %3 : $*Test, value [[VALUE]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () - // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () - // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value [[ZERO:%.*]] : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [init] #Test.count, self %3 : $*Test, value [[VALUE]] : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () + // CHECK: assign_or_init [set] #Test.count, self %3 : $*Test, value [[ZERO:%.*]] : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set {{.*}} : $@noescape @callee_guaranteed (Int) -> () init(count: Int) { self.count = count self.count = 0 @@ -448,9 +456,7 @@ func test_handling_of_nonmutating_set() { // CHECK: [[SELF:%.*]] = load [copy] {{.*}} : $*TestWithStored // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF14TestWithStoredL_V5countSivs : $@convention(method) (Int, @guaranteed TestWithStored) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) (Int, @guaranteed TestWithStored) -> () - // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SELF]] : $TestWithStored + // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () init(count: Int) { self.count = count } @@ -461,16 +467,12 @@ func test_handling_of_nonmutating_set() { // // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF14TestWithStoredL_V5countSivs : $@convention(method) (Int, @guaranteed TestWithStored) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) (Int, @guaranteed TestWithStored) -> () - // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value {{.*}} : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SELF]] : $TestWithStored + // CHECK-NEXT: assign_or_init [init] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value {{.*}} : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () // // CHECK: [[SELF:%.*]] = load [copy] {{.*}} : $*TestWithStored // CHECK: [[SETTER_REF:%.*]] = function_ref @$s23assign_or_init_lowering32test_handling_of_nonmutating_setyyF14TestWithStoredL_V5countSivs : $@convention(method) (Int, @guaranteed TestWithStored) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF]]) : $@convention(method) (Int, @guaranteed TestWithStored) -> () - // CHECK-NEXT: assign_or_init [set] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@convention(thin) (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () - // CHECK-NEXT: destroy_value [[SELF]] : $TestWithStored + // CHECK-NEXT: assign_or_init [set] #TestWithStored.count, self [[SELF_REF]] : $*TestWithStored, value %0 : $Int, init {{.*}} : $@noescape @callee_guaranteed (Int) -> @out Int, set [[SETTER_CLOSURE]] : $@noescape @callee_guaranteed (Int) -> () init(value: Int) { self.count = 0 self.count = value diff --git a/test/SILOptimizer/init_accessors.swift b/test/SILOptimizer/init_accessors.swift index 47a1959bbc7e9..a1a6bb01b27c0 100644 --- a/test/SILOptimizer/init_accessors.swift +++ b/test/SILOptimizer/init_accessors.swift @@ -10,8 +10,8 @@ struct TestInit { var full: (Int, Int) var point: (Int, Int) { - // CHECK-LABEL: sil private [ossa] @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) - // CHECK: bb0([[Y_REF:%.*]] : $*Int, [[FULL_REF:%.*]] : $*(Int, Int), [[X_VAL:%.*]] : $Int, [[Y_VAL:%.*]] : $Int, [[X_REF:%.*]] : $*Int): + // CHECK-LABEL: sil private [ossa] @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int)) + // CHECK: bb0([[Y_REF:%.*]] : $*Int, [[FULL_REF:%.*]] : $*(Int, Int), [[X_VAL:%.*]] : $Int, [[Y_VAL:%.*]] : $Int, [[X_REF:%.*]] : $*Int, [[METATYPE:%.*]] : $@thin TestInit.Type): // // CHECK: [[INITIAL_VALUE:%.*]] = tuple ([[X_VAL]] : $Int, [[Y_VAL]] : $Int) // CHECK: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple [[INITIAL_VALUE]] : $(Int, Int) @@ -42,13 +42,14 @@ struct TestInit { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors8TestInitV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestInit.Type) -> TestInit // CHECK: // function_ref TestInit.point.init - // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) + // CHECK-NEXT: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors8TestInitV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int)) + // CHECK-NEXT: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @inout Int, @thin TestInit.Type) -> (@out Int, @out (Int, Int)) // CHECK: [[SELF_VALUE:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestInit // CHECK: [[Y_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.y // CHECK-NEXT: [[FULL_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.full // CHECK-NEXT: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, Int) // CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestInit, #TestInit.x - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[Y_REF]], [[FULL_REF]], [[X_VAL]], [[Y_VAL]], [[X_REF]]) : $@convention(thin) (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[Y_REF]], [[FULL_REF]], [[X_VAL]], [[Y_VAL]], [[X_REF]]) : $@noescape @callee_guaranteed (Int, Int, @inout Int) -> (@out Int, @out (Int, Int)) // CHECK-NEXT: end_access [[SELF_VALUE]] : $*TestInit init(x: Int, y: Int) { self.x = x @@ -70,12 +71,13 @@ struct TestSetter { } // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors10TestSetterV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestSetter.Type) -> TestSetter - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors10TestSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @inout Int) -> () + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors10TestSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @inout Int, @inout Int, @thin TestSetter.Type) -> () + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @inout Int, @inout Int, @thin TestSetter.Type) -> () // CHECK: [[SELF:%.*]] = begin_access [modify] [dynamic] %14 : $*TestSetter // CHECK-NEXT: ([[X:%.*]], [[Y:%.*]]) = destructure_tuple {{.*}} : $(Int, Int) // CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF]] : $*TestSetter, #TestSetter.x // CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr [[SELF]] : $*TestSetter, #TestSetter.y - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X]], [[Y]], [[X_REF]], [[Y_REF]]) : $@convention(thin) (Int, Int, @inout Int, @inout Int) -> () + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X]], [[Y]], [[X_REF]], [[Y_REF]]) : $@noescape @callee_guaranteed (Int, Int, @inout Int, @inout Int) -> () init(x: Int, y: Int) { self.x = x self.y = y @@ -99,10 +101,11 @@ struct TestInitThenSetter { } // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors18TestInitThenSetterV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestInitThenSetter.Type) -> TestInitThenSetter - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors18TestInitThenSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors18TestInitThenSetterV5pointSi_Sitvi : $@convention(thin) (Int, Int, @thin TestInitThenSetter.Type) -> (@out Int, @out Int) + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @thin TestInitThenSetter.Type) -> (@out Int, @out Int) // CHECK: [[X_REF:%.*]] = struct_element_addr {{.*}} : $*TestInitThenSetter, #TestInitThenSetter.x // CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr {{.*}} : $*TestInitThenSetter, #TestInitThenSetter.y - // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], {{.*}}) : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], {{.*}}) : $@noescape @callee_guaranteed (Int, Int) -> (@out Int, @out Int) // // CHECK: [[SETTER_REF:%.*]] = function_ref @$s14init_accessors18TestInitThenSetterV5pointSi_Sitvs : $@convention(method) (Int, Int, @inout TestInitThenSetter) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER_REF]]([[SELF_VALUE:%.*]]) : $@convention(method) (Int, Int, @inout TestInitThenSetter) -> () @@ -143,13 +146,15 @@ struct TestPartialInt { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors14TestPartialIntV1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestPartialInt.Type) -> TestPartialInt // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointXSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointXSivi : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int // CHECK: [[X_REF:%.*]] = struct_element_addr {{.*}} : $*TestPartialInt, #TestPartialInt.x - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[X_REF]], %0) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[X_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointYSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointYSivi : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestPartialInt.Type) -> @out Int // CHECK: [[Y_REF:%.*]] = struct_element_addr {{.*}} : $*TestPartialInt, #TestPartialInt.y - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@noescape @callee_guaranteed (Int) -> @out Int // // CHECK: [[BUILTIN_ONE:%.*]] = integer_literal $Builtin.IntLiteral, 1 // CHECK: [[SETTER_REF:%.*]] = function_ref @$s14init_accessors14TestPartialIntV6pointXSivs : $@convention(method) (Int, @inout TestPartialInt) -> () @@ -199,16 +204,18 @@ struct TestNoInitAndInit { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors013TestNoInitAndE0V1x1yACSi_SitcfC : $@convention(method) (Int, Int, @thin TestNoInitAndInit.Type) -> TestNoInitAndInit // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointXSivi : $@convention(thin) (Int, @inout Int) -> () + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointXSivi : $@convention(thin) (Int, @inout Int, @thin TestNoInitAndInit.Type) -> () + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @inout Int, @thin TestNoInitAndInit.Type) -> () // CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestNoInitAndInit // CHECK-NEXT: [[X_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.x - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]](%0, [[X_REF]]) : $@convention(thin) (Int, @inout Int) -> () + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]](%0, [[X_REF]]) : $@noescape @callee_guaranteed (Int, @inout Int) -> () // CHECK-NEXT: end_access [[SELF_REF]] : $*TestNoInitAndInit // - // CHECK: [[INIT_REF:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointYSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_REF_FN:%.*]] = function_ref @$s14init_accessors013TestNoInitAndE0V6pointYSivi : $@convention(thin) (Int, @thin TestNoInitAndInit.Type) -> @out Int + // CHECK: [[INIT_REF:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_REF_FN]](%2) : $@convention(thin) (Int, @thin TestNoInitAndInit.Type) -> @out Int // CHECK: [[SELF_REF:%.*]] = begin_access [modify] [dynamic] {{.*}} : $*TestNoInitAndInit // CHECK-NEXT: [[Y_REF:%.*]] = struct_element_addr [[SELF_REF]] : $*TestNoInitAndInit, #TestNoInitAndInit.y - // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_REF]]([[Y_REF]], %1) : $@noescape @callee_guaranteed (Int) -> @out Int // CHECK-NEXT: end_access [[SELF_REF]] : $*TestNoInitAndInit init(x: Int, y: Int) { self.x = x @@ -223,8 +230,8 @@ class TestClass { var y: (Int, [String]) var data: (Int, (Int, [String])) { - // CHECK-LABEL: sil private [ossa] @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) - // CHECK: bb0([[X_REF:%.*]] : $*Int, [[Y_REF:%.*]] : $*(Int, Array), [[X_VAL:%.*]] : $Int, [[Y_VAL_0:%.*]] : $Int, [[Y_VAL_1:%.*]] : @owned $Array): + // CHECK-LABEL: sil private [ossa] @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array, @thick TestClass.Type) -> (@out Int, @out (Int, Array)) + // CHECK: bb0([[X_REF:%.*]] : $*Int, [[Y_REF:%.*]] : $*(Int, Array), [[X_VAL:%.*]] : $Int, [[Y_VAL_0:%.*]] : $Int, [[Y_VAL_1:%.*]] : @owned $Array, [[METATYPE:%.*]] : $@thick TestClass.Type): // // CHECK: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, (Int, Array)) // CHECK: [[X_ACCESS:%.*]] = begin_access [modify] [static] [[X_REF]] : $*Int @@ -250,14 +257,16 @@ class TestClass { } // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors9TestClassC1x1yACSi_Si_SaySSGttcfc : $@convention(method) (Int, Int, @owned Array, @owned TestClass) -> @owned TestClass - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors9TestClassC4dataSi_Si_SaySSGttvi : $@convention(thin) (Int, Int, @owned Array, @thick TestClass.Type) -> (@out Int, @out (Int, Array)) + // CHECK: [[METATYPE:%.*]] = value_metatype $@thick TestClass.Type, {{%.*}} + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]]([[METATYPE]]) : $@convention(thin) (Int, Int, @owned Array, @thick TestClass.Type) -> (@out Int, @out (Int, Array)) // CHECK: [[SELF_REF:%.*]] = begin_borrow [[SELF_VALUE:%.*]] : $TestClass // CHECK: [[X_REF:%.*]] = ref_element_addr [[SELF_REF]] : $TestClass, #TestClass.x // CHECK-NEXT: [[Y_REF:%.*]] = ref_element_addr [[SELF_REF]] : $TestClass, #TestClass.y // // CHECK-NEXT: ([[X_VAL:%.*]], [[Y_VAL:%.*]]) = destructure_tuple {{.*}} : $(Int, (Int, Array)) // CHECK-NEXT: ([[Y_VAL_0:%.*]], [[Y_VAL_1:%.*]]) = destructure_tuple [[Y_VAL]] : $(Int, Array) - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], [[X_VAL]], [[Y_VAL_0]], [[Y_VAL_1]]) : $@convention(thin) (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[X_REF]], [[Y_REF]], [[X_VAL]], [[Y_VAL_0]], [[Y_VAL_1]]) : $@noescape @callee_guaranteed (Int, Int, @owned Array) -> (@out Int, @out (Int, Array)) init(x: Int, y: (Int, [String])) { self.data = (x, y) } @@ -268,9 +277,9 @@ struct TestGeneric { var b: T var c: U - // CHECK-LABEL: sil private [ossa] @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) (@in T, @in T, @inout U) -> (@out T, @out T) + // CHECK-LABEL: sil private [ossa] @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) (@in T, @in T, @inout U, @thin TestGeneric.Type) -> (@out T, @out T) // - // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*T, [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_REF:%.*]] : $*U): + // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*T, [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_REF:%.*]] : $*U, [[METATYPE:%.*]] : $@thin TestGeneric.Type): // // CHECK: [[A_ACCESS:%.*]] = begin_access [modify] [static] [[A_REF]] : $*T // CHECK-NEXT: copy_addr [take] {{.*}} to [init] [[A_ACCESS]] : $*T @@ -298,9 +307,9 @@ struct TestGeneric { // CHECK-LABEL: sil hidden [ossa] @$s14init_accessors11TestGenericV1a1b1cACyxq_Gx_xq_tcfC : $@convention(method) (@in T, @in T, @in U, @thin TestGeneric.Type) -> @out TestGeneric // - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1) -> (@out τ_0_0, @out τ_0_0) - // CHECK-NEXT: [[SUBST_INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [[INIT_ACCESSOR]]() : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1) -> (@out τ_0_0, @out τ_0_0) - // CHECK: {{.*}} = apply [[SUBST_INIT_ACCESSOR]]({{.*}}) : $@callee_guaranteed (@in T, @in T, @inout U) -> (@out T, @out T) + // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors11TestGenericV4datax_xtvi : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1, @thin TestGeneric<τ_0_0, τ_0_1>.Type) -> (@out τ_0_0, @out τ_0_0) + // CHECK-NEXT: [[SUBST_INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR]](%4) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout τ_0_1, @thin TestGeneric<τ_0_0, τ_0_1>.Type) -> (@out τ_0_0, @out τ_0_0) + // CHECK: {{.*}} = apply [[SUBST_INIT_ACCESSOR]]({{.*}}) : $@noescape @callee_guaranteed (@in T, @in T, @inout U) -> (@out T, @out T) // // CHECK: [[SETTER:%.*]] = function_ref @$s14init_accessors11TestGenericV4datax_xtvs : $@convention(method) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout TestGeneric<τ_0_0, τ_0_1>) -> () // CHECK-NEXT: [[SETTER_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[SETTER]]([[SELF_VALUE:%.*]]) : $@convention(method) <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_0, @inout TestGeneric<τ_0_0, τ_0_1>) -> () @@ -317,9 +326,9 @@ struct TestGenericTuple { var a: T var b: (T, U) - // CHECK-LABEL: sil private [ossa] @$s14init_accessors16TestGenericTupleV4datax_x_q_ttvi : $@convention(thin) (@in T, @in T, @in U) -> (@out T, @out (T, U)) { + // CHECK-LABEL: sil private [ossa] @$s14init_accessors16TestGenericTupleV4datax_x_q_ttvi : $@convention(thin) (@in T, @in T, @in U, @thin TestGenericTuple.Type) -> (@out T, @out (T, U)) { // - // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*(T, U), [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_VALUE:%.*]] : $*U): + // CHECK: bb0([[A_REF:%.*]] : $*T, [[B_REF:%.*]] : $*(T, U), [[A_VALUE:%.*]] : $*T, [[B_VALUE:%.*]] : $*T, [[C_VALUE:%.*]] : $*U, [[METATYPE:%.*]] : $@thin TestGenericTuple.Type): // // CHECK: [[INIT_VALUE_1:%.*]] = alloc_stack $(T, U), let, name "initialValue" // CHECK-NEXT: [[INIT_VALUE_1_0:%.*]] = tuple_element_addr [[INIT_VALUE_1]] : $*(T, U), 0 @@ -374,8 +383,8 @@ func test_local_with_memberwise() { // CHECK: [[SELF_VALUE:%.*]] = alloc_stack $TestMemberwiseConcrete // CHECK-NEXT: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseConcrete, #TestMemberwiseConcrete.a // CHECK-NEXT: [[B_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseConcrete, #TestMemberwiseConcrete.b - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF22TestMemberwiseConcreteL_V4pairSi_SStvi : $@convention(thin) (Int, @owned String) -> (@out Int, @out String) - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[B_REF]], %0, %1) : $@convention(thin) (Int, @owned String) -> (@out Int, @out String) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF22TestMemberwiseConcreteL_V4pairSi_SStvi : $@convention(thin) (Int, @owned String, @thin TestMemberwiseConcrete.Type) -> (@out Int, @out String) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[B_REF]], %0, %1, %3) : $@convention(thin) (Int, @owned String, @thin TestMemberwiseConcrete.Type) -> (@out Int, @out String) // CHECK-NEXT: [[C_REF:%.*]] = struct_element_addr %4 : $*TestMemberwiseConcrete, #TestMemberwiseConcrete.c // CHECK-NEXT: store %2 to [init] [[C_REF]] : $*Array // CHECK-NEXT: [[RESULT:%.*]] = load [take] [[SELF_VALUE]] : $*TestMemberwiseConcrete @@ -415,13 +424,13 @@ func test_local_with_memberwise() { // CHECK-LABEL: sil private [ossa] @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V1a4pairADyxq_Gx_SS_q_ttcfC : $@convention(method) (@in T, @owned String, @in C, @thin TestMemberwiseGeneric.Type) -> @out TestMemberwiseGeneric // CHECK: bb0([[SELF_VALUE:%.*]] : $*TestMemberwiseGeneric, [[A_VALUE:%*.]] : $*T, [[B_VALUE:%.*]] : @owned $String, [[C_VALUE:%.*]] : $*C, [[METATYPE:%.*]] : $@thin TestMemberwiseGeneric.Type): // CHECK-NEXT: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._a - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V1axvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0) -> @out τ_0_0 // user: %7 - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[A_VALUE]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0) -> @out τ_0_0 + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V1axvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> @out τ_0_0 // user: %7 + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[A_REF]], [[A_VALUE]], [[METATYPE]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@in τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> @out τ_0_0 // CHECK-NEXT: [[B_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._b // CHECK-NEXT: [[C_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._c // CHECK-NEXT: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*TestMemberwiseGeneric, #TestMemberwiseGeneric._a - // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V4pairSS_q_tvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0) -> (@out String, @out τ_0_1) - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[B_REF]], [[C_REF]], [[B_VALUE]], [[C_VALUE]], [[A_REF]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0) -> (@out String, @out τ_0_1) + // CHECK: [[INIT_ACCESSOR_REF:%.*]] = function_ref @$s14init_accessors26test_local_with_memberwiseyyF21TestMemberwiseGenericL_V4pairSS_q_tvi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> (@out String, @out τ_0_1) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR_REF]]([[B_REF]], [[C_REF]], [[B_VALUE]], [[C_VALUE]], [[A_REF]], [[METATYPE]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.Element, τ_0_1 : RangeReplaceableCollection> (@owned String, @in τ_0_1, @inout τ_0_0, @thin TestMemberwiseGeneric<τ_0_0, τ_0_1>.Type) -> (@out String, @out τ_0_1) // CHECK-NEXT: [[VOID:%.*]] = tuple () // CHECK-NEXT: return [[VOID]] : $() } @@ -430,12 +439,12 @@ func test_local_with_memberwise() { } // CHECK-LABEL: sil private [ossa] @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnADyxq_Gq_xc_tcfC : $@convention(method) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @thin Test.Type) -> @owned Test -// CHECK: {{.*}} = function_ref @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) <τ_0_0, τ_0_1> (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>> +// CHECK: {{.*}} = function_ref @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) <τ_0_0, τ_0_1> (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>, @thin Test<τ_0_0, τ_0_1>.Type) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <τ_0_0, τ_0_1>> func test_type_lowering_for_init_accessor() { struct Test { var _fn: ((T) -> U)? = nil - // CHECK-LABEL: sil private [ossa] @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for ) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for > + // CHECK-LABEL: sil private [ossa] @$s14init_accessors023test_type_lowering_for_A9_accessoryyF4TestL_V2fnyq_xcvi : $@convention(thin) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for , @thin Test.Type) -> @out Optional<@callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for > var fn: (T) -> U { @storageRestrictions(initializes: _fn) init { _fn = newValue } @@ -479,13 +488,15 @@ func test_assignments() { } // CHECK-LABEL: sil private [ossa] @$s14init_accessors16test_assignmentsyyF4TestL_V1aADSi_tcfC : $@convention(method) (Int, @thin Test.Type) -> Test - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int, @thin Test.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%1) : $@convention(thin) (Int, @thin Test.Type) -> @out Int // CHECK: [[A_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._a - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@convention(thin) (Int) -> @out Int - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int, @thin Test.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%1) : $@convention(thin) (Int, @thin Test.Type) -> @out Int // CHECK: [[A_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._a // CHECK-NEXT: destroy_addr [[A_REF]] : $*Int - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@convention(thin) (Int) -> @out Int + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int // CHECK: [[B_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._b // CHECK-NEXT: store {{.*}} to [trivial] [[B_REF]] : $*Int // CHECK: [[SETTER_REF:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivs : $@convention(method) (Int, @inout Test) -> () @@ -499,14 +510,16 @@ func test_assignments() { } // CHECK-LABEL: sil private [ossa] @$s14init_accessors16test_assignmentsyyF4TestL_V1a1bADSi_SitcfC : $@convention(method) (Int, Int, @thin Test.Type) -> Test - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V1aSivi : $@convention(thin) (Int, @thin Test.Type) -> @out Int + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, @thin Test.Type) -> @out Int // CHECK: [[A_REF:%.*]] = struct_element_addr {{.*}} : $*Test, #Test._a - // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@convention(thin) (Int) -> @out Int - // CHECK: [[INIT_ACCESSOR:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V4pairSi_Sitvi : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK-NEXT: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], %0) : $@noescape @callee_guaranteed (Int) -> @out Int + // CHECK: [[INIT_ACCESSOR_FN:%.*]] = function_ref @$s14init_accessors16test_assignmentsyyF4TestL_V4pairSi_Sitvi : $@convention(thin) (Int, Int, @thin Test.Type) -> (@out Int, @out Int) + // CHECK: [[INIT_ACCESSOR:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[INIT_ACCESSOR_FN]](%2) : $@convention(thin) (Int, Int, @thin Test.Type) -> (@out Int, @out Int) // CHECK: [[A_REF:%.*]] = struct_element_addr [[SELF_VALUE:%.*]] : $*Test, #Test._a // CHECK-NEXT: destroy_addr [[A_REF]] : $*Int // CHECK-NEXT: [[B_REF:%.*]] = struct_element_addr [[SELF_VALUE]] : $*Test, #Test._b - // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], [[B_REF]], {{.*}}) : $@convention(thin) (Int, Int) -> (@out Int, @out Int) + // CHECK: {{.*}} = apply [[INIT_ACCESSOR]]([[A_REF]], [[B_REF]], {{.*}}) : $@noescape @callee_guaranteed (Int, Int) -> (@out Int, @out Int) init(a: Int, b: Int) { self.a = a self.pair = (0, b) diff --git a/test/SILOptimizer/init_accessors_with_indirect_newValue.swift b/test/SILOptimizer/init_accessors_with_indirect_newValue.swift index 122a2a65a34a8..6d66a69e1877d 100644 --- a/test/SILOptimizer/init_accessors_with_indirect_newValue.swift +++ b/test/SILOptimizer/init_accessors_with_indirect_newValue.swift @@ -35,12 +35,12 @@ public class Test { // CHECK-NEXT: [[DEFAULT_VALUE:%.*]] = load [take] [[DEFAULT_VALUE_SLOT]] : $*Test.State // CHECK: [[NEW_VALUE:%.*]] = alloc_stack $Test.State // CHECK-NEXT: store [[DEFAULT_VALUE]] to [init] [[NEW_VALUE]] : $*Test.State - // CHECK: assign_or_init [init] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@convention(thin) (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () + // CHECK: assign_or_init [init] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () // // CHECK: [[START_STATE:%.*]] = enum $Test.State, #Test.State.start!enumelt // CHECK-NEXT: [[NEW_VALUE:%.*]] = alloc_stack $Test.State // CHECK-NEXT: store [[START_STATE]] to [trivial] [[NEW_VALUE]] : $*Test.State - // CHECK: assign_or_init [set] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@convention(thin) (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () + // CHECK: assign_or_init [set] #Test.state, self [[MU]] : $Test, value [[NEW_VALUE]] : $*Test.State, init {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> @out Test.State, set {{.*}} : $@noescape @callee_guaranteed (@in Test.State) -> () public init() { state = .start }