diff --git a/lib/SILGen/SILGenFunction.cpp b/lib/SILGen/SILGenFunction.cpp index db567b68fc624..68580e9410807 100644 --- a/lib/SILGen/SILGenFunction.cpp +++ b/lib/SILGen/SILGenFunction.cpp @@ -807,10 +807,15 @@ void SILGenFunction::emitCaptures(SILLocation loc, // If we have a mutable binding for a 'let', such as 'self' in an // 'init' method, load it. if (val->getType().isMoveOnly()) { - val = B.createMarkUnresolvedNonCopyableValueInst( - loc, val, - MarkUnresolvedNonCopyableValueInst::CheckKind:: - NoConsumeOrAssign); + auto *moveOnlyIntroducer = dyn_cast_or_null(val); + if (!moveOnlyIntroducer || moveOnlyIntroducer->getCheckKind() != + MarkUnresolvedNonCopyableValueInst:: + CheckKind::NoConsumeOrAssign) { + val = B.createMarkUnresolvedNonCopyableValueInst( + loc, val, + MarkUnresolvedNonCopyableValueInst::CheckKind:: + NoConsumeOrAssign); + } } val = emitLoad(loc, val, tl, SGFContext(), IsNotTake).forward(*this); } diff --git a/test/SILGen/addressable_read.swift b/test/SILGen/addressable_read.swift new file mode 100644 index 0000000000000..8937646b7f4e4 --- /dev/null +++ b/test/SILGen/addressable_read.swift @@ -0,0 +1,21 @@ +// RUN: %target-swift-frontend -emit-sil -verify -enable-experimental-feature AddressableParameters %s + +public struct Container: ~Copyable { + var _storage: UnsafeMutableBufferPointer + var _count: Int + + public subscript(index: Int) -> Element { + @_addressableSelf + _read { + precondition(index >= 0 && index < _count, "Index out of bounds") + yield _storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee + } + _modify { + precondition(index >= 0 && index < _count, "Index out of bounds") + yield &_storage.baseAddress.unsafelyUnwrapped.advanced(by: index).pointee + } + } +} + +extension Container: Copyable where Element: Copyable {} +