You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Allow passing MutableSpan 'inout' without an experimental feature.
This adds a new lifetime inference rule, loosening the requirement for @Lifetime
annotations even when the experimental LifetimeDependence mode is
enabled. Additionally, it enables this new inference rule even when the
experimental mode is disabled. All other inference rules continue to require the
experimental feature. The rule is:
If a function or method has a single inout non-Escapable parameter other than
'self' and has no other non-Escapable parameters including 'self', then infer a
single @Lifetime(copy) dependency on the inout parameter from its own incoming
value.
This supports the common case in which the user of a non-Escapable type,
such as MutableSpan, wants to modify the span's contents without modifying
the span value itself. It should be possible to use MutableSpan this way
without requiring any knowledge of lifetime annotations. The tradeoff is
that it makes authoring non-Escapable types less safe. For example, a
MutableSpan method could update the underlying unsafe pointer and forget to
declare a dependence on the incoming pointer.
Disallowing other non-Escapable parameters rules out the easy mistake of
programmers attempting to trivially reassign the inout parameter. There's
is no way to rule out the possibility that they derive another
non-Escapable value from an Escapable parameteter. So users can still write
the following:
func reassign(s: inout MutableSpan<Int>, a: [Int]) {
s = a.mutableSpan
}
The 'reassign' declaration will type check, but it's implementation will
diagnose a lifetime error on 's'.
Fixes rdar://150557314 ([nonescapable] Declaration of inout MutableSpan
parameter requires LifetimeDependence experimental feature)
func neReturn(span:RawSpan)->RawSpan{ span } // expected-error{{a function with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'}}
13
13
14
-
func neInout(span:inoutRawSpan){} // expected-error{{a function with a ~Escapable 'inout' parameter requires '-enable-experimental-feature LifetimeDependence'}}
14
+
func neInout(span:inoutRawSpan){} // OK
15
+
16
+
func neInoutNEParam(span:inoutRawSpan, _:RawSpan){} // expected-error{{a function with a ~Escapable 'inout' parameter requires '-enable-experimental-feature LifetimeDependence'}}
15
17
16
18
structS{
17
19
func neReturn(span:RawSpan)->RawSpan{ span } // expected-error{{a method with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'}}
18
20
19
-
func neInout(span:inoutRawSpan){} // expected-error{{a method with a ~Escapable 'inout' parameter requires '-enable-experimental-feature LifetimeDependence'}}
21
+
func neInout(span:inoutRawSpan){} // OK
22
+
23
+
func neInoutNEParam(span:inoutRawSpan, _:RawSpan){} // expected-error{{a method with a ~Escapable 'inout' parameter requires '-enable-experimental-feature LifetimeDependence'}}
24
+
25
+
mutatingfunc mutatingNEInout(span:inoutRawSpan){} // OK
26
+
27
+
mutatingfunc mutatingNEInoutParam(span:inoutRawSpan, _:RawSpan){} // expected-error{{a mutating method with a ~Escapable 'inout' parameter requires '-enable-experimental-feature LifetimeDependence'}}
20
28
}
21
29
22
30
classC{
23
31
func neReturn(span:RawSpan)->RawSpan{ span } // expected-error{{a method with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'}}
func neReturn(span:RawSpan)->RawSpan{ span } // expected-error{{a method with a ~Escapable result requires '-enable-experimental-feature LifetimeDependence'}}
42
+
25
43
func neInout(span:inoutRawSpan){} // expected-error{{a method with a ~Escapable 'inout' parameter requires '-enable-experimental-feature LifetimeDependence'}}
0 commit comments