Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
md5: 7e5c282beaaefdc99de4b06445d4bbb6
Issue Description:
When SILGen reads a captured ‘let’ stored property from a struct it loads the entire struct and then extracts the property value from the struct.
This causes unexpected exclusivity violations because to the programmer it looks like they are loading just the stored property.
Here is an example inspired by the Foundation overlay's Data Iterator:
func takesInoutAndClosure(_ p1: inout Int, _ p2: () -> ()) { }
public struct Iterator { {{ private let _data: Int}} {{ private var _buffer: Int}}
public struct Iterator {
{{ public mutating func next() {}} {{ takesInoutAndClosure(&_buffer) { // error: overlapping accesses to 'self._buffer'}} {{ let _ = _data; // conflicting access (to all of ‘self’)}} {{ }}} {{ }}} {{}}}
The closure in next() gets SILGen'd to:
// closure #​1 in Iterator.next()``sil private @$S1t8IteratorV4nextyyFyyXEfU_ : $@convention(thin) (@inout_aliasable Iterator) -> () {``// %0 // users: %2, %1``bb0(%0 : $*Iterator):{{ debug_value_addr %0 : $*Iterator, var, name "self", argno 1 // id: %1}}{{ %2 = begin_access [read] [unknown] %0 : $*Iterator // users: %4, %3}}{{ %3 = load [trivial] %2 : $*Iterator // user: %5}}{{ end_access %2 : $*Iterator // id: %4}}{{ %5 = struct_extract %3 : $Iterator, #Iterator._data}}{{ %6 = tuple () // user: %7}}{{ return %6 : $() // id: %7}}{{}}}
// closure #​1 in Iterator.next()``sil private @$S1t8IteratorV4nextyyFyyXEfU_ : $@convention(thin) (@inout_aliasable Iterator) -> () {``// %0 // users: %2, %1``bb0(%0 : $*Iterator):
From John in an email: > I think we could pretty easily change SILGen to only load the specific stored property here.
To prevent these exclusivity violations, the SILGen should instead look something like:
bb0(%0 : $*Iterator): {{ %2 = begin_access [read] [unknown] %0 : $*Iterator}} {{ %3 = struct_element_addr %6 : $*Iterator, #Iterator._data}} {{ %4 = load [trivial] %23: $*Int}} {{ end_access %2 : $*Iterator}} {{ %6 = tuple ()}} {{ return %6 : $()}}
bb0(%0 : $*Iterator):
In the Foundation overlay I've changed the let-bound variables in Data.Iterator to be 'var' to avoid the violation with #15823 We should revert that when this issue is fixed.
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Additional Detail from JIRA
md5: 7e5c282beaaefdc99de4b06445d4bbb6
Issue Description:
When SILGen reads a captured ‘let’ stored property from a struct it loads the entire struct and then extracts the property value from the struct.
This causes unexpected exclusivity violations because to the programmer it looks like they are loading just the stored property.
Here is an example inspired by the Foundation overlay's Data Iterator:
func takesInoutAndClosure(_ p1: inout Int, _ p2: () -> ()) { }
public struct Iterator {
{{ private let _data: Int}}
{{ private var _buffer: Int}}
{{ public mutating func next() {}}
{{ takesInoutAndClosure(&_buffer) { // error: overlapping accesses to 'self._buffer'}}
{{ let _ = _data; // conflicting access (to all of ‘self’)}}
{{ }}}
{{ }}}
{{}}}
The closure in next() gets SILGen'd to:
// closure #​1 in Iterator.next()``sil private @$S1t8IteratorV4nextyyFyyXEfU_ : $@convention(thin) (@inout_aliasable Iterator) -> () {``// %0 // users: %2, %1``bb0(%0 : $*Iterator):
{{ debug_value_addr %0 :From John in an email:
> I think we could pretty easily change SILGen to only load the specific stored property here.
To prevent these exclusivity violations, the SILGen should instead look something like:
bb0(%0 : $*Iterator):
{{ %2 = begin_access [read] [unknown] %0 : $*Iterator}}
{{ %3 = struct_element_addr %6 : $*Iterator, #Iterator._data}}
{{ %4 = load [trivial] %23: $*Int}}
{{ end_access %2 : $*Iterator}}
{{ %6 = tuple ()}}
{{ return %6 : $()}}
In the Foundation overlay I've changed the let-bound variables in Data.Iterator to be 'var' to avoid the violation with #15823 We should revert that when this issue is fixed.
The text was updated successfully, but these errors were encountered: