Repository: apple/swift
File: lib/SILGen/SILGenExpr.cpp (C++)

Code before:
  // Otherwise, emit the result (to get any side effects), but produce it at +0
  // if that allows simplification.
  RValue rv = emitRValue(E, SGFContext::AllowImmediatePlusZero);

  // Return early if we do not have any result.
  if (rv.isNull())
    return;

  // Then emit ignored use on all of the rvalue components. We purposely do not
  // implode the tuple since if we have a tuple formation like:
  //
  // let _ = (x, y)
  //
  // we want the use to be on x and y and not on the imploded tuple. It also
  // helps us avoid emitting unnecessary code.
  SmallVector<ManagedValue, 16> values;
  std::move(rv).getAll(values);
  for (auto v : values) {
    B.createIgnoredUse(E, v.getValue());
  }
}

/// Emit the given expression as an r-value, then (if it is a tuple), combine
/// it together into a single ManagedValue.
ManagedValue SILGenFunction::emitRValueAsSingleValue(Expr *E, SGFContext C) {
  return emitRValue(E, C).getAsSingleValue(*this, E);
}

RValue SILGenFunction::emitUndefRValue(SILLocation loc, Type type) {
  return RValue(*this, loc, type->getCanonicalType(),
                emitUndef(getLoweredType(type)));
}

ManagedValue SILGenFunction::emitUndef(Type type) {
  return emitUndef(getLoweredType(type));
}

ManagedValue SILGenFunction::emitUndef(SILType type) {
  SILValue undef = SILUndef::get(F, type);
  return ManagedValue::forRValueWithoutOwnership(undef);
}


Review comment (suggestion):
could someone verify if it matters what SGFContext value is used here? i assume this case should always result in a downstream error so i'm inclined to think it doesn't...

Code after:
  // arguments.
  
  FullExpr scope(Cleanups, CleanupLocation(E));
  FormalEvaluationScope evalScope(*this);

  if (E->getType()->hasLValueType()) {
    // Emit the l-value, but don't perform an access.
    emitLValue(E, SGFAccessKind::IgnoredRead);
    return;
  }

  // If this is a load expression, we try hard not to actually do the load
  // (which could materialize a potentially expensive value with cleanups).
  if (auto *LE = dyn_cast<LoadExpr>(E)) {
    LValue lv = emitLValue(LE->getSubExpr(), SGFAccessKind::IgnoredRead);

    if (LE->getType()->isStructurallyUninhabited()) {
      // If the lvalue is structurally uninhabited, we emit the load so that
      // DI will see any uses before initialization. It should not be possible
      // to ever really load such a value, so this should result in some sort
      // of downstream error.
      //
      // Failure to do this in the past resulted in this bug:
      // https://github.com/swiftlang/swift/issues/74478.

      emitLoadOfLValue(E, std::move(lv), SGFContext::AllowImmediatePlusZero);
      return;
    }

    // If loading from the lvalue is guaranteed to have no side effects, we
    // don't need to drill into it.
    if (lv.isLoadingPure())
      return;

    // If the last component is physical, then we just need to drill through
    // side effects in the lvalue, but don't need to perform the final load.
    if (lv.isLastComponentPhysical()) {
      emitAddressOfLValue(E, std::move(lv));
      return;
    }

    // Otherwise, we must call the ultimate getter to get its potential side
    // effect.
    emitLoadOfLValue(E, std::move(lv), SGFContext::AllowImmediatePlusZero);
    return;
  }

  auto findLoadThroughForceValueExprs = [](Expr *E,
                                           SmallVectorImpl<ForceValueExpr *>
                                             &forceValueExprs) -> LoadExpr * {
    while (auto FVE = dyn_cast<ForceValueExpr>(E)) {