@@ -1090,18 +1090,27 @@ namespace {
10901090 ManagedValue base) && override {
10911091 assert (!base && " value component must be root of lvalue path" );
10921092
1093- // See if we have a noncopyable address from a project_box or global, we
1094- // always eagerly reproject out.
1093+ // See if we have a noncopyable address from a project_box or global.
10951094 if (Value.getType ().isAddress () && Value.getType ().isMoveOnly ()) {
10961095 SILValue addr = Value.getValue ();
1097- if (isa<ProjectBoxInst>(addr) || isa<GlobalAddrInst>(addr)) {
1096+ auto box = dyn_cast<ProjectBoxInst>(addr);
1097+ if (box || isa<GlobalAddrInst>(addr)) {
10981098 if (Enforcement)
10991099 addr = enterAccessScope (SGF, loc, base, addr, getTypeData (),
11001100 getAccessKind (), *Enforcement,
11011101 takeActorIsolation ());
1102- addr = SGF.B .createMarkMustCheckInst (
1103- loc, addr,
1104- MarkMustCheckInst::CheckKind::AssignableButNotConsumable);
1102+ // LValue accesses to a `let` box are only ever going to make through
1103+ // definite initialization if they are initializations, which don't
1104+ // require checking since there's no former value to potentially
1105+ // misuse yet.
1106+ if (!box || box->getOperand ()->getType ().castTo <SILBoxType>()
1107+ ->getLayout ()->isMutable ()) {
1108+ addr = SGF.B .createMarkMustCheckInst (
1109+ loc, addr,
1110+ isReadAccess (getAccessKind ())
1111+ ? MarkMustCheckInst::CheckKind::NoConsumeOrAssign
1112+ : MarkMustCheckInst::CheckKind::AssignableButNotConsumable);
1113+ }
11051114 return ManagedValue::forLValue (addr);
11061115 }
11071116 }
@@ -3009,11 +3018,8 @@ void LValue::addNonMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
30093018 auto astAccessKind = mapAccessKind (this ->AccessKind );
30103019 auto address = SGF.maybeEmitValueOfLocalVarDecl (Storage, astAccessKind);
30113020
3012- // The only other case that should get here is a global variable or a
3013- // noncopyable value in a box.
3021+ // The only other case that should get here is a global variable.
30143022 if (!address) {
3015- address = SGF.maybeEmitAddressForBoxOfLocalVarDecl (Loc, Storage);
3016- if (!address)
30173023 address = SGF.emitGlobalVariableRef (Loc, Storage, ActorIso);
30183024 } else {
30193025 assert ((!ActorIso || Storage->isTopLevelGlobal ()) &&
@@ -3056,26 +3062,6 @@ void LValue::addNonMemberVarComponent(SILGenFunction &SGF, SILLocation loc,
30563062 emitter.emitUsingStrategy(strategy);
30573063}
30583064
3059- ManagedValue
3060- SILGenFunction::maybeEmitAddressForBoxOfLocalVarDecl (SILLocation loc,
3061- VarDecl *var) {
3062- auto It = VarLocs.find (var);
3063-
3064- // Wasn't a box.
3065- if (It == VarLocs.end ())
3066- return ManagedValue ();
3067-
3068- SILValue value = It->second .value ;
3069- SILValue box = It->second .box ;
3070-
3071- // We only want to do this if we only have a box without a value.
3072- if (!box || value)
3073- return ManagedValue ();
3074-
3075- SILValue addr = B.createProjectBox (loc, box, 0 );
3076- return ManagedValue::forLValue (addr);
3077- }
3078-
30793065ManagedValue
30803066SILGenFunction::maybeEmitValueOfLocalVarDecl (
30813067 VarDecl *var, AccessKind accessKind) {
@@ -3084,13 +3070,7 @@ SILGenFunction::maybeEmitValueOfLocalVarDecl(
30843070 if (It != VarLocs.end ()) {
30853071 SILValue ptr = It->second .value ;
30863072
3087- // If we do not have an actual value stored, then we must have a box.
3088- if (!ptr) {
3089- assert (It->second .box );
3090- return ManagedValue ();
3091- }
3092-
3093- // If this has an address, return it. By-value let's have no address.
3073+ // If this has an address, return it. By-value let bindings have no address.
30943074 if (ptr->getType ().isAddress ())
30953075 return ManagedValue::forLValue (ptr);
30963076
@@ -3101,7 +3081,7 @@ SILGenFunction::maybeEmitValueOfLocalVarDecl(
31013081 return ManagedValue::forUnmanaged (ptr);
31023082 }
31033083
3104- // Otherwise, it's non-local, not stored, or a box .
3084+ // Otherwise, it's non-local or not stored .
31053085 return ManagedValue ();
31063086}
31073087
@@ -3116,9 +3096,6 @@ SILGenFunction::emitAddressOfLocalVarDecl(SILLocation loc, VarDecl *var,
31163096 assert (!var->isAsyncLet () && " async let does not have an address" );
31173097
31183098 auto address = maybeEmitValueOfLocalVarDecl (var, astAccessKind);
3119- if (!address)
3120- address = maybeEmitAddressForBoxOfLocalVarDecl (loc, var);
3121- assert (address);
31223099 assert (address.isLValue ());
31233100 return address;
31243101}
@@ -3141,12 +3118,7 @@ RValue SILGenFunction::emitRValueForNonMemberVarDecl(SILLocation loc,
31413118
31423119 // If our localValue is a closure captured box of a noncopyable type, project
31433120 // it out eagerly and insert a no_consume_or_assign constraint.
3144- ManagedValue localValue;
3145- if (auto localAddr = maybeEmitAddressForBoxOfLocalVarDecl (loc, var)) {
3146- localValue = localAddr;
3147- } else {
3148- localValue = maybeEmitValueOfLocalVarDecl (var, AccessKind::Read);
3149- }
3121+ ManagedValue localValue = maybeEmitValueOfLocalVarDecl (var, AccessKind::Read);
31503122
31513123 // If this VarDecl is represented as an address, emit it as an lvalue, then
31523124 // perform a load to get the rvalue.
@@ -3169,9 +3141,11 @@ RValue SILGenFunction::emitRValueForNonMemberVarDecl(SILLocation loc,
31693141 SILAccessKind::Read);
31703142
31713143 if (accessAddr->getType ().isMoveOnly ()) {
3144+ // When loading an rvalue, we should never need to modify the place
3145+ // we're loading from.
31723146 accessAddr = B.createMarkMustCheckInst (
31733147 loc, accessAddr,
3174- MarkMustCheckInst::CheckKind::AssignableButNotConsumable );
3148+ MarkMustCheckInst::CheckKind::NoConsumeOrAssign );
31753149 }
31763150
31773151 auto propagateRValuePastAccess = [&](RValue &&rvalue) {
0 commit comments