ManualOwnership: provide ability to apply to entire compilation unit

With this patch, I'm flipping the polarity of things.

The flag `-enable-experimental-feature ManualOwnership` now turns on the diagnostics,
but they're all silenced by default. So, you need to add -Wwarning or -Werror to
your build settings to turn on the specific diagnostics you care about.

These are the diagnostic groups relevant to the feature:

- SemanticCopies aka "explicit copies mode"
- DynamicExclusivity

For example, the build setting `-Werror SemanticCopies` now gives you errors about
explicit copies, just as before, but now you can make them just warnings with -Wwarning.

To opt-out a declaration from everything when using the feature, use @_noManualOwnership.

@_manualOwnership is no longer an attribute as a result.

resolves rdar://163372569
This commit is contained in:
Kavon Farvardin
2025-10-24 16:46:42 -07:00
parent 135e02c1d9
commit 2d881bdc9c
13 changed files with 46 additions and 103 deletions

View File

@@ -815,7 +815,7 @@ SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
155)
SIMPLE_DECL_ATTR(_manualOwnership, ManualOwnership,
SIMPLE_DECL_ATTR(_noManualOwnership, NoManualOwnership,
OnAbstractFunction | OnSubscript,
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
156)

View File

@@ -2145,9 +2145,7 @@ ERROR(attr_static_exclusive_only_mutating,none,
ERROR(attr_static_exclusive_no_setters,none,
"variable of type %0 must not have a setter", (Type))
// @_manualOwnership
ERROR(attr_manual_ownership_experimental,none,
"'@_manualOwnership' requires '-enable-experimental-feature ManualOwnership'", ())
// ManualOwnership
ERROR(attr_manual_ownership_noimplicitcopy,none,
"'@_noImplicitCopy' cannot be used with ManualOwnership", ())

View File

@@ -449,7 +449,9 @@ EXPERIMENTAL_FEATURE(LifetimeDependence, true)
/// Enable the `@_staticExclusiveOnly` attribute.
EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)
/// Enable the `@_manualOwnership` attribute.
/// Enable the ManualOwnership diagnostic groups:
/// * -Wwarning SemanticCopies
/// * -Wwarning DynamicExclusivity
EXPERIMENTAL_FEATURE(ManualOwnership, false)
/// Enable the @extractConstantsFromMembers attribute.

View File

@@ -5024,7 +5024,7 @@ public:
TRIVIAL_ATTR_PRINTER(NoLocks, no_locks)
TRIVIAL_ATTR_PRINTER(NoMetadata, no_metadata)
TRIVIAL_ATTR_PRINTER(NoObjCBridging, no_objc_bridging)
TRIVIAL_ATTR_PRINTER(ManualOwnership, manual_ownership)
TRIVIAL_ATTR_PRINTER(NoManualOwnership, no_manual_ownership)
TRIVIAL_ATTR_PRINTER(NoRuntime, no_runtime)
TRIVIAL_ATTR_PRINTER(NonEphemeral, non_ephemeral)
TRIVIAL_ATTR_PRINTER(NonEscapable, non_escapable)

View File

@@ -265,7 +265,6 @@ extension ASTGenVisitor {
.LexicalLifetimes,
.LLDBDebuggerFunction,
.MainType,
.ManualOwnership,
.Marker,
.MoveOnly,
.NeverEmitIntoClient,
@@ -276,6 +275,7 @@ extension ASTGenVisitor {
.NoRuntime,
.NoImplicitCopy,
.NoLocks,
.NoManualOwnership,
.NoMetadata,
.NoObjCBridging,
.NonEphemeral,

View File

@@ -208,7 +208,9 @@ void SILFunctionBuilder::addFunctionAttributes(
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
} else if (Attrs.hasAttribute<ManualOwnershipAttr>()) {
} else if (M.getASTContext().LangOpts.hasFeature(Feature::ManualOwnership) &&
constant && constant.hasDecl() && !constant.isImplicit() &&
!Attrs.hasAttribute<NoManualOwnershipAttr>()) {
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
}

View File

@@ -1368,15 +1368,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
//
// If ManualOwnership ends up subsuming those prior mechanisms for an
// explicit-copy mode, we can move this somewhere else, like postEmitFunction.
if (auto *ace = constant.getAbstractClosureExpr()) {
if (auto *dc = ace->getOutermostFunctionContext()) {
if (auto *decl = dc->getAsDecl()) {
if (decl->getAttrs().hasAttribute<ManualOwnershipAttr>()) {
//
// FIXME: maybe this should happen in SILFunctionBuilder::getOrCreateFunction
if (getASTContext().LangOpts.hasFeature(Feature::ManualOwnership))
if (auto *ace = constant.getAbstractClosureExpr())
if (auto *dc = ace->getOutermostFunctionContext())
if (auto *decl = dc->getAsDecl())
if (!decl->isImplicit() &&
!decl->getAttrs().hasAttribute<NoManualOwnershipAttr>())
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
}
}
}
}
LLVM_DEBUG(llvm::dbgs() << "lowering ";
F->printName(llvm::dbgs());

View File

@@ -183,6 +183,7 @@ public:
IGNORED_ATTR(NoAllocation)
IGNORED_ATTR(NoRuntime)
IGNORED_ATTR(NoExistentials)
IGNORED_ATTR(NoManualOwnership)
IGNORED_ATTR(NoObjCBridging)
IGNORED_ATTR(EmitAssemblyVisionRemarks)
IGNORED_ATTR(ShowInInterface)
@@ -476,7 +477,6 @@ public:
void visitUnsafeNonEscapableResultAttr(UnsafeNonEscapableResultAttr *attr);
void visitStaticExclusiveOnlyAttr(StaticExclusiveOnlyAttr *attr);
void visitManualOwnershipAttr(ManualOwnershipAttr *attr);
void visitWeakLinkedAttr(WeakLinkedAttr *attr);
void visitSILGenNameAttr(SILGenNameAttr *attr);
void visitLifetimeAttr(LifetimeAttr *attr);
@@ -8408,13 +8408,6 @@ void AttributeChecker::visitStaticExclusiveOnlyAttr(
}
}
void AttributeChecker::visitManualOwnershipAttr(ManualOwnershipAttr *attr) {
if (Ctx.LangOpts.hasFeature(Feature::ManualOwnership))
return;
diagnoseAndRemoveAttr(attr, diag::attr_manual_ownership_experimental);
}
void AttributeChecker::visitWeakLinkedAttr(WeakLinkedAttr *attr) {
if (!Ctx.LangOpts.Target.isOSBinFormatCOFF())
return;

View File

@@ -1620,8 +1620,8 @@ namespace {
UNINTERESTING_ATTR(NoAllocation)
UNINTERESTING_ATTR(NoRuntime)
UNINTERESTING_ATTR(NoExistentials)
UNINTERESTING_ATTR(NoManualOwnership)
UNINTERESTING_ATTR(NoObjCBridging)
UNINTERESTING_ATTR(ManualOwnership)
UNINTERESTING_ATTR(Inlinable)
UNINTERESTING_ATTR(Effects)
UNINTERESTING_ATTR(Expose)

View File

@@ -14,7 +14,6 @@ public struct Pair {
var x: Int
var y: Int
@_manualOwnership
consuming func midpoint(_ other: borrowing Pair) -> Pair {
return Pair(x: (x + other.x) / 2, y: (y + other.y) / 2)
}
@@ -27,10 +26,8 @@ public class Triangle {
var nontrivial = Whatever()
@_manualOwnership
consuming func consuming() {}
@_manualOwnership
borrowing func borrowing() {}
}
@@ -44,51 +41,41 @@ func borrow_generic<T>(_ t: borrowing T) {}
/// MARK: return statements
@_manualOwnership
public func basic_return1() -> Triangle {
let x = Triangle()
return x
}
@_manualOwnership
public func basic_return2(t: Triangle) -> Triangle {
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
}
@_manualOwnership
public func basic_return2_fixed(t: Triangle) -> Triangle {
return copy t
}
@_manualOwnership
public func basic_return3() -> Triangle {
return Triangle()
}
@_manualOwnership
func return_borrowed(_ t: borrowing Triangle) -> Triangle {
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
}
@_manualOwnership
func return_borrowed_fixed(_ t: borrowing Triangle) -> Triangle {
return copy t
}
// FIXME: there's no workaround to this; it acts like a var so it's the same class of problem (rdar://161359163)
@_manualOwnership
func return_consumingParam(_ t: consuming Triangle) -> Triangle {
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
}
@_manualOwnership
func return_consumingParam_no_workaround(_ t: consuming Triangle) -> Triangle {
return copy t
}
@_manualOwnership
func return_owned(_ t: __owned Triangle) -> Triangle {
return t
}
@_manualOwnership
func reassign_with_lets() -> Triangle {
let x = Triangle()
let y = x
@@ -96,7 +83,6 @@ func reassign_with_lets() -> Triangle {
return z
}
@_manualOwnership
func renamed_return(_ cond: Bool, _ a: Triangle) -> Triangle {
let b = a
let c = b
@@ -105,7 +91,6 @@ func renamed_return(_ cond: Bool, _ a: Triangle) -> Triangle {
return c // expected-warning {{independent copy of 'c' is required}}
}
@_manualOwnership
func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
let b = copy a
let c = copy b // FIXME: not needed! Is explicit_copy_value is blocking propagation? (rdar://161359163)
@@ -114,8 +99,7 @@ func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
}
// FIXME: this crashes CopyPropagation! (rdar://161360764)
//@_manualOwnership
//func renamed_return_fix2(_ cond: Bool, _ a: Triangle) -> Triangle {
////func renamed_return_fix2(_ cond: Bool, _ a: Triangle) -> Triangle {
// let b = a
// let c = b
// if cond { return copy b }
@@ -124,20 +108,17 @@ func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
/// MARK: method calls
@_manualOwnership
func basic_methods_borrowing(_ t1: Triangle) {
let t2 = Triangle()
t1.borrowing()
t2.borrowing()
}
@_manualOwnership
func basic_methods_consuming(_ t1: Triangle) {
let t2 = Triangle()
t1.consuming() // expected-warning {{independent copy of 't1' is required}}
t2.consuming()
}
@_manualOwnership
func basic_methods_consuming_fixed(_ t1: Triangle) {
let t2 = Triangle()
@@ -148,19 +129,15 @@ func basic_methods_consuming_fixed(_ t1: Triangle) {
open class OpenClass {
open func classMethod() {}
}
@_manualOwnership
func callOpenMethod(_ c: OpenClass) {
return c.classMethod()
}
@_manualOwnership
@discardableResult
func consumingFunc(_ t0: consuming Triangle) -> Bool { return false }
@_manualOwnership
func plainFunc(_ t0: Triangle) {}
@_manualOwnership
func basic_function_call(_ t1: Triangle) {
consumingFunc(t1) // expected-warning {{independent copy of 't1' is required}}
consumingFunc(copy t1)
@@ -169,13 +146,11 @@ func basic_function_call(_ t1: Triangle) {
/// MARK: control-flow
@_manualOwnership
func check_vars(_ t: Triangle, _ b: Bool) -> Triangle {
var x = Triangle()
if b { x = t } // expected-warning {{independent copy of 't' is required}}
return x // expected-warning {{independent copy of 'x' is required}}
}
@_manualOwnership
func check_vars_fixed(_ t: Triangle, _ b: Bool) -> Triangle {
var x = Triangle()
if b { x = copy t }
@@ -185,45 +160,38 @@ func check_vars_fixed(_ t: Triangle, _ b: Bool) -> Triangle {
// FIXME: var's still have some issues
// (1) MandatoryRedundantLoadElimination introduces a 'copy_value' in place of a 'load [copy]' (rdar://161359163)
@_manualOwnership
func reassignments_0() -> Triangle {
var t3 = Triangle()
t3 = Triangle()
return t3 // expected-warning {{independent copy of 't3' is required}}
}
@_manualOwnership
func reassignments_0_fixed_1() -> Triangle {
var t3 = Triangle()
t3 = Triangle()
return copy t3
}
@_manualOwnership
func reassignments_0_fixed_2() -> Triangle {
var t3 = Triangle()
t3 = Triangle()
return consume t3
}
@_manualOwnership
func reassignments_1() {
var t3 = Triangle()
t3 = Triangle()
t3.borrowing() // expected-warning {{accessing 't3' may produce a copy; write 'copy' to acknowledge or 'consume' to elide}}
}
@_manualOwnership
func reassignments_1_fixed_1() {
var t3 = Triangle()
t3 = Triangle()
(copy t3).borrowing()
}
@_manualOwnership
func reassignments_1_fixed_2() {
var t3 = Triangle()
t3 = Triangle()
(consume t3).borrowing()
}
@_manualOwnership
public func basic_loop_trivial_values(_ t: Triangle, _ xs: [Triangle]) {
var p: Pair = t.a
for x in xs { // expected-warning {{independent copy of 'xs' is required}}
@@ -231,7 +199,6 @@ public func basic_loop_trivial_values(_ t: Triangle, _ xs: [Triangle]) {
}
t.a = p
}
@_manualOwnership
public func basic_loop_trivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
var p: Pair = t.a
for x in copy xs {
@@ -246,7 +213,6 @@ public func basic_loop_trivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
// There's complexity in auto-generating a read accessor for classes, but if it's provided
// we could then allow someone to elide the copy with a `borrow x` expression.
@_manualOwnership
public func basic_loop_nontrivial_values(_ t: Triangle, _ xs: [Triangle]) {
var p: Pair = t.nontrivial.a // expected-warning {{accessing 't.nontrivial' may produce a copy}}
for x in xs { // expected-warning {{independent copy of 'xs' is required}}
@@ -255,7 +221,6 @@ public func basic_loop_nontrivial_values(_ t: Triangle, _ xs: [Triangle]) {
t.nontrivial.a = p // expected-warning {{accessing 't.nontrivial' may produce a copy}}
}
@_manualOwnership
public func basic_loop_nontrivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
var p: Pair = (copy t.nontrivial).a
for x in copy xs {
@@ -264,7 +229,6 @@ public func basic_loop_nontrivial_values_fixed(_ t: Triangle, _ xs: [Triangle])
(copy t.nontrivial).a = p
}
@_manualOwnership
public func basic_loop_nontrivial_values_reduced_copies(_ t: Triangle, _ xs: [Triangle]) {
// FIXME: confusing variable names are chosen (rdar://161360537)
let nt = t.nontrivial // expected-warning {{accessing 'nt' may produce a copy}}
@@ -275,7 +239,6 @@ public func basic_loop_nontrivial_values_reduced_copies(_ t: Triangle, _ xs: [Tr
}
nt.a = p
}
@_manualOwnership
public func basic_loop_nontrivial_values_reduced_copies_fixed(_ t: Triangle, _ xs: [Triangle]) {
let nt = copy t.nontrivial
var p: Pair = nt.a
@@ -292,24 +255,20 @@ let ref_result = [5, 13, 29]
// FIXME: if we had a borrow operator, we could allow people to elide these simple copies that
// are present to avoid exclusivity issues. We'd need to start generating read coroutines.
@_manualOwnership
func access_global_1() -> Int {
return ref_result[2] // expected-warning {{accessing 'ref_result' may produce a copy}}
}
@_manualOwnership
func access_global_1_fixed() -> Int {
return (copy ref_result)[2]
}
/// MARK: closures
@_manualOwnership
func closure_basic(_ t: Triangle) -> () -> Triangle {
return { // expected-warning {{closure capture of 't' requires independent copy of it; write [t = copy t]}}
return t // expected-warning {{independent copy of 't' is required}}
}
}
@_manualOwnership
func closure_basic_almost_fixed_1(_ t: Triangle) -> () -> Triangle {
// FIXME: Closure capture lists need to support the short-hand [copy t] that makes the
// closure capture parameter @owned, rather than @guaranteed. Only can work for Copyable types!
@@ -318,21 +277,18 @@ func closure_basic_almost_fixed_1(_ t: Triangle) -> () -> Triangle {
}
}
@_manualOwnership
func closure_basic_almost_fixed_2(_ x: Triangle) -> () -> Triangle {
return { // expected-warning {{closure capture of 'x' requires independent copy of it; write [x = copy x]}}
return copy x
}
}
@_manualOwnership
func closure_basic_fixed(_ t: Triangle) -> () -> Triangle {
return { [x = copy t] in
return copy x
}
}
@_manualOwnership
func closure_copies_in_body(_ t: Triangle) -> () -> Triangle {
return { [x = copy t] in
eat(x) // expected-warning {{independent copy of 'x' is required}}
@@ -342,7 +298,6 @@ func closure_copies_in_body(_ t: Triangle) -> () -> Triangle {
}
}
@_manualOwnership
func closure_copies_in_body_noescape(_ t: Triangle) -> Triangle {
let f = { [x = copy t] in
eat(x) // expected-warning {{independent copy of 'x' is required}}
@@ -353,25 +308,20 @@ func closure_copies_in_body_noescape(_ t: Triangle) -> Triangle {
return f()
}
@_manualOwnership
func simple_assert(_ f: @autoclosure () -> Bool) {
guard f() else { fatalError() }
}
@_manualOwnership
func try_to_assert(_ n: Int, _ names: [String]) {
simple_assert(names.count == n)
}
@_manualOwnership
func copy_in_autoclosure(_ t: Triangle) {
simple_assert(consumingFunc(t)) // expected-warning {{independent copy of 't' is required}}
}
@_manualOwnership
func copy_in_autoclosure_fixed(_ t: Triangle) {
simple_assert(consumingFunc(copy t))
}
@_manualOwnership
func nested_closures(_ t: Triangle) -> () -> (() -> Triangle) {
return { // expected-warning {{closure capture of 't' requires independent copy of it; write [t = copy t]}}
{ eat(t) }() // expected-warning {{independent copy of 't' is required}}
@@ -381,7 +331,6 @@ func nested_closures(_ t: Triangle) -> () -> (() -> Triangle) {
}
}
}
@_manualOwnership
func nested_closures_fixed(_ t: Triangle) -> () -> (() -> Triangle) {
return { [a = copy t] in
{ eat(copy a) }()
@@ -391,19 +340,26 @@ func nested_closures_fixed(_ t: Triangle) -> () -> (() -> Triangle) {
}
}
}
@_noManualOwnership
func nested_closures_DISABLED(_ t: Triangle) -> () -> (() -> Triangle) {
return {
{ eat(t) }()
return {
simple_assert(consumingFunc(t))
return t
}
}
}
/// MARK: generics
@_manualOwnership
func return_generic<T>(_ t: T) -> T {
return t // expected-warning {{accessing 't' may produce a copy}}
}
@_manualOwnership
func return_generic_fixed<T>(_ t: T) -> T {
return copy t
}
@_manualOwnership
func reassign_with_lets<T>(_ t: T) -> T {
let x = t // expected-warning {{accessing 't' may produce a copy}}
let y = x // expected-warning {{accessing 'x' may produce a copy}}
@@ -412,7 +368,6 @@ func reassign_with_lets<T>(_ t: T) -> T {
}
// FIXME: copy propagation has no effect on address-only types, so this is quite verbose.
@_manualOwnership
func reassign_with_lets_fixed<T>(_ t: T) -> T {
let x = copy t
let y = copy x
@@ -420,21 +375,25 @@ func reassign_with_lets_fixed<T>(_ t: T) -> T {
return copy z
}
@_manualOwnership
func copy_generic<T>(_ t: T) {
consume_generic(t) // expected-warning {{accessing 't' may produce a copy}}
borrow_generic(t)
consume_generic(t) // expected-warning {{accessing 't' may produce a copy}}
}
@_manualOwnership
@_noManualOwnership
func copy_generic_DISABLED<T>(_ t: T) {
consume_generic(t)
borrow_generic(t)
consume_generic(t)
}
func copy_generic_fixed<T>(_ t: T) {
consume_generic(copy t)
borrow_generic(t)
consume_generic(copy t)
}
@_manualOwnership
func benchCaptureProp<S : Sequence>(
_ s: S, _ f: (S.Element, S.Element) -> S.Element) -> S.Element {
@@ -444,7 +403,6 @@ func benchCaptureProp<S : Sequence>(
IteratorSequence(it) // expected-warning {{accessing 'it' may produce a copy}}
.reduce(initial, f)
}
@_manualOwnership
func benchCaptureProp_fixed<S : Sequence>(
_ s: S, _ f: (S.Element, S.Element) -> S.Element) -> S.Element {
@@ -456,12 +414,10 @@ func benchCaptureProp_fixed<S : Sequence>(
}
extension FixedWidthInteger {
@_manualOwnership
func leftRotate(_ distance: Int) -> Self {
return (self << distance) | (self >> (Self.bitWidth - distance))
}
@_manualOwnership
mutating func rotatedLeft(_ distance: Int) {
self = (copy self).leftRotate(distance)
}
@@ -470,7 +426,6 @@ extension FixedWidthInteger {
struct CollectionOf32BitLittleEndianIntegers<BaseCollection: Collection> where BaseCollection.Element == UInt8 {
var baseCollection: BaseCollection
@_manualOwnership
init(_ baseCollection: BaseCollection) {
precondition(baseCollection.count % 4 == 0)
self.baseCollection = baseCollection // expected-warning {{accessing 'baseCollection' may produce a copy}}

View File

@@ -18,12 +18,12 @@ public class Donut : Food {
override init() {
super.init()
self.calories = 100
self.calories = 100 // expected-warning {{exclusive access here will be checked at runtime}}
}
convenience init(calories c: Int) {
self.init()
self.calories = c
self.calories = c // expected-warning {{exclusive access here will be checked at runtime}}
}
}
@@ -31,19 +31,21 @@ extension Int { func greaterThanZero() -> Bool { self > 0 } }
var expectedCalories: Array<Int> = [120, 203, 1502]
@_manualOwnership
func accessGlobal_map() -> Array<Donut> {
return expectedCalories.map(Donut.init(calories:)) // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
}
@_manualOwnership
func accessGlobal_member() -> Int {
return expectedCalories.count // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
}
@_noManualOwnership
func accessGlobal_member_DISABLED() -> Int {
return expectedCalories.count
}
var globalDonut: Donut = Donut()
@_manualOwnership
func accessGlobalClass() {
let x = globalDonut.calories // expected-warning {{accessing 'globalDonut' here may incur runtime exclusivity check, because it involves a global variable}}
// expected-warning@-1 {{exclusive access here will be checked at runtime}}
@@ -51,20 +53,17 @@ func accessGlobalClass() {
expectedCalories.append(x) // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
}
@_manualOwnership
func accessClassSimple(_ d2: Donut) -> Int {
let d1 = Donut()
return d1.calories // expected-warning {{exclusive access here will be checked at runtime}}
+ d2.calories // expected-warning {{exclusive access here will be checked at runtime}}
}
@_manualOwnership
func accessClassParam_chain(_ donut: Donut) -> Int {
return donut.next?.next?.calories ?? Int.max
// expected-warning@-1 {{exclusive access here will be checked at runtime}}
}
@_manualOwnership
func accessClassLocal_chain() -> Int {
let donut = Donut()
return donut.next?.next?.calories ?? Int.max

View File

@@ -19,7 +19,6 @@ class TriangleClass {
// CHECK-NEXT: destroy_value [[SHAPE]]
// CHECK-NEXT: return [[COPY]]
// CHECK-NEXT: } // end sil function 'basic_access_of_loadable'
@_manualOwnership
@_silgen_name("basic_access_of_loadable")
func basic_access_of_loadable(_ t: TriangleClass) -> ShapeClass {
return copy t.shape
@@ -41,7 +40,6 @@ func basic_access_of_loadable(_ t: TriangleClass) -> ShapeClass {
// CHECK-NEXT: end_access [[ADDR2]]
// CHECK: return [[X_COPY]]
// CHECK-NEXT: } // end sil function 'var_assign'
@_manualOwnership
@_silgen_name("var_assign")
func var_assign(_ t: TriangleClass, _ b: Bool) -> TriangleClass {
var x = TriangleClass()
@@ -55,7 +53,6 @@ func var_assign(_ t: TriangleClass, _ b: Bool) -> TriangleClass {
// CHECK-NEXT: [[IMPL_COPY:%.*]] = copy_value %0
// CHECK-NEXT: return [[IMPL_COPY]]
// CHECK-NEXT: } // end sil function 'return_borrowed'
@_manualOwnership
@_silgen_name("return_borrowed")
func return_borrowed(_ t: borrowing TriangleClass) -> TriangleClass {
return t
@@ -74,7 +71,6 @@ func return_borrowed(_ t: borrowing TriangleClass) -> TriangleClass {
// CHECK-NEXT: destroy_value
// CHECK-NEXT: return [[IMPL_COPY]]
// CHECK-NEXT: } // end sil function 'return_consumingParam'
@_manualOwnership
@_silgen_name("return_consumingParam")
func return_consumingParam(_ t: consuming TriangleClass) -> TriangleClass {
return t
@@ -89,7 +85,6 @@ func return_consumingParam(_ t: consuming TriangleClass) -> TriangleClass {
// CHECK-NEXT: destroy_value %0
// CHECK-NEXT: return [[IMPL_COPY]]
// CHECK-NEXT: } // end sil function 'return_owned'
@_manualOwnership
@_silgen_name("return_owned")
func return_owned(_ t: __owned TriangleClass) -> TriangleClass {
return t

View File

@@ -7,7 +7,6 @@
class C {}
@_manualOwnership
func hello() -> (C, C) {
@_noImplicitCopy let x = C() // expected-error {{'@_noImplicitCopy' cannot be used with ManualOwnership}}
return (x, x)