Skip to content

Commit

Permalink
Use 'hasAssociatedValues'
Browse files Browse the repository at this point in the history
Use 'hasAssociatedValues' instead of computing and discarding the
interface type of an enum element decl.  This change has specifically not
been made in conditions that use the presence or absence of the
interface type, only conditions that depend on the presence or absence
of associated values in the enum element decl.
  • Loading branch information
CodaFi committed May 22, 2017
1 parent e92805f commit 3b202c1
Show file tree
Hide file tree
Showing 20 changed files with 38 additions and 39 deletions.
4 changes: 2 additions & 2 deletions lib/IRGen/GenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1372,7 +1372,7 @@ namespace {
return false;

for (auto elt : decl->getAllElements()) {
if (elt->getArgumentInterfaceType() &&
if (elt->hasAssociatedValues() &&
!elt->isIndirect() &&
visit(elt->getArgumentInterfaceType()->getCanonicalType()))
return true;
Expand Down Expand Up @@ -1773,7 +1773,7 @@ SILType irgen::getSingletonAggregateFieldType(IRGenModule &IGM, SILType t,

auto theCase = allCases.begin();
if (!allCases.empty() && std::next(theCase) == allCases.end()
&& (*theCase)->getArgumentInterfaceType())
&& (*theCase)->hasAssociatedValues())
return t.getEnumElementType(*theCase, IGM.getSILModule());

return SILType();
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/AbstractionPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ AbstractionPattern TypeConverter::getAbstractionPattern(VarDecl *var) {
}

AbstractionPattern TypeConverter::getAbstractionPattern(EnumElementDecl *decl) {
assert(decl->getArgumentInterfaceType());
assert(decl->hasAssociatedValues());
assert(!decl->hasClangNode());

// This cannot be implemented correctly for Optional.Some.
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/SILDeclRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ unsigned swift::getNaturalUncurryLevel(ValueDecl *vd) {
} else if (isa<ConstructorDecl>(vd)) {
return 1;
} else if (auto *ed = dyn_cast<EnumElementDecl>(vd)) {
return ed->getArgumentInterfaceType() ? 1 : 0;
return ed->hasAssociatedValues() ? 1 : 0;
} else if (isa<DestructorDecl>(vd)) {
return 0;
} else if (isa<ClassDecl>(vd)) {
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/SILOwnershipVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ OwnershipUseCheckerResult OwnershipCompatibilityUseChecker::visitNonTrivialEnum(
// Check if this enum has at least one case that is non-trivially typed.
bool HasNonTrivialCase =
llvm::any_of(E->getAllElements(), [this](EnumElementDecl *E) -> bool {
if (!E->getArgumentInterfaceType())
if (!E->hasAssociatedValues())
return false;
SILType EnumEltType = getType().getEnumElementType(E, Mod);
return !EnumEltType.isTrivial(Mod);
Expand Down
8 changes: 4 additions & 4 deletions lib/SIL/SILType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static bool canUnsafeCastEnum(SILType fromType, EnumDecl *fromEnum,
if (EnumDecl *toEnum = toType.getEnumOrBoundGenericEnum()) {
for (auto toElement : toEnum->getAllElements()) {
++numToElements;
if (!toElement->getArgumentInterfaceType())
if (!toElement->hasAssociatedValues())
continue;
// Bail on multiple payloads.
if (!toElementTy.isNull())
Expand All @@ -209,7 +209,7 @@ static bool canUnsafeCastEnum(SILType fromType, EnumDecl *fromEnum,
// If any of the fromElements can be cast by value to the singleton toElement,
// then the overall enum can be cast by value.
for (auto fromElement : fromElements) {
if (!fromElement->getArgumentInterfaceType())
if (!fromElement->hasAssociatedValues())
continue;

auto fromElementTy = fromType.getEnumElementType(fromElement, M);
Expand Down Expand Up @@ -317,7 +317,7 @@ SILType SILType::getFieldType(VarDecl *field, SILModule &M) const {

SILType SILType::getEnumElementType(EnumElementDecl *elt, SILModule &M) const {
assert(elt->getDeclContext() == getEnumOrBoundGenericEnum());
assert(elt->getArgumentInterfaceType());
assert(elt->hasAssociatedValues());

if (auto objectType = getSwiftRValueType().getAnyOptionalObjectType()) {
assert(elt == M.getASTContext().getOptionalSomeDecl());
Expand Down Expand Up @@ -413,7 +413,7 @@ bool SILType::aggregateContainsRecord(SILType Record, SILModule &Mod) const {
// Then if we have an enum...
if (EnumDecl *E = Ty.getEnumOrBoundGenericEnum()) {
for (auto Elt : E->getAllElements())
if (Elt->getArgumentInterfaceType())
if (Elt->hasAssociatedValues())
Worklist.push_back(Ty.getEnumElementType(Elt, Mod));
continue;
}
Expand Down
8 changes: 4 additions & 4 deletions lib/SIL/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,10 +1695,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
"EnumInst case must be a case of the result enum type");
require(UI->getType().isObject(),
"EnumInst must produce an object");
require(UI->hasOperand() == !!UI->getElement()->getArgumentInterfaceType(),
require(UI->hasOperand() == UI->getElement()->hasAssociatedValues(),
"EnumInst must take an argument iff the element does");

if (UI->getElement()->getArgumentInterfaceType()) {
if (UI->getElement()->hasAssociatedValues()) {
require(UI->getOperand()->getType().isObject(),
"EnumInst operand must be an object");
SILType caseTy = UI->getType().getEnumElementType(UI->getElement(),
Expand All @@ -1713,7 +1713,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
require(ud, "InitEnumDataAddrInst must take an enum operand");
require(UI->getElement()->getParentEnum() == ud,
"InitEnumDataAddrInst case must be a case of the enum operand type");
require(UI->getElement()->getArgumentInterfaceType(),
require(UI->getElement()->hasAssociatedValues(),
"InitEnumDataAddrInst case must have a data type");
require(UI->getOperand()->getType().isAddress(),
"InitEnumDataAddrInst must take an address operand");
Expand Down Expand Up @@ -3431,7 +3431,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {

// The destination BB can take the argument payload, if any, as a BB
// arguments, or it can ignore it and take no arguments.
if (elt->getArgumentInterfaceType()) {
if (elt->hasAssociatedValues()) {
if (isSILOwnershipEnabled() && F.hasQualifiedOwnership()) {
require(dest->getArguments().size() == 1,
"switch_enum destination for case w/ args must take 1 "
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/TypeLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,7 @@ namespace {
bool trivial = true;
for (auto elt : D->getAllElements()) {
// No-payload elements do not affect address-only-ness.
if (!elt->getArgumentInterfaceType())
if (!elt->hasAssociatedValues())
continue;

// Indirect elements make the type nontrivial, but don't affect
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4366,7 +4366,7 @@ RValue CallEmission::applyEnumElementConstructor(

// Get the payload argument.
ArgumentSource payload;
if (element->getArgumentInterfaceType()) {
if (element->hasAssociatedValues()) {
assert(uncurriedSites.size() == 2);
formalResultType = formalType.getResult();
claimNextParamClause(origFormalType.getValue());
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ void SwitchEnumBuilder::emit() && {
builder.emitBlock(caseBlock);

ManagedValue input;
if (decl->getArgumentInterfaceType()) {
if (decl->hasAssociatedValues()) {
// Pull the payload out if we have one.
SILType inputType =
optional.getType().getEnumElementType(decl, builder.getModule());
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ void SILGenFunction::emitEnumConstructor(EnumElementDecl *element) {

// Emit the exploded constructor argument.
ArgumentSource payload;
if (element->getArgumentInterfaceType()) {
if (element->hasAssociatedValues()) {
RValue arg = emitImplicitValueConstructorArg
(*this, Loc, element->getArgumentInterfaceType()->getCanonicalType(),
element->getDeclContext());
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ void EnumElementPatternInitialization::emitEnumMatch(
[&SGF, &loc, &eltDecl, &subInit, &value](ManagedValue mv,
SwitchCaseFullExpr &expr) {
// If the enum case has no bound value, we're done.
if (!eltDecl->getArgumentInterfaceType()) {
if (!eltDecl->hasAssociatedValues()) {
assert(
subInit == nullptr &&
"Cannot have a subinit when there is no value to match against");
Expand Down
4 changes: 2 additions & 2 deletions lib/SILGen/SILGenPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,7 @@ void PatternMatchEmission::emitEnumElementDispatchWithOwnership(

SILType eltTy;
bool hasElt = false;
if (elt->getArgumentInterfaceType()) {
if (elt->hasAssociatedValues()) {
eltTy = src.getType().getEnumElementType(elt, SGF.SGM.M);
hasElt = !eltTy.getSwiftRValueType()->isVoid();
}
Expand Down Expand Up @@ -2025,7 +2025,7 @@ void PatternMatchEmission::emitEnumElementDispatch(

SILType eltTy;
bool hasElt = false;
if (elt->getArgumentInterfaceType()) {
if (elt->hasAssociatedValues()) {
eltTy = src.getType().getEnumElementType(elt, SGF.SGM.M);
hasElt = !eltTy.getSwiftRValueType()->isVoid();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ static bool isOrContainsReference(SILType Ty, SILModule *Mod) {
}
if (auto En = Ty.getEnumOrBoundGenericEnum()) {
for (auto *ElemDecl : En->getAllElements()) {
if (ElemDecl->getArgumentInterfaceType() &&
if (ElemDecl->hasAssociatedValues() &&
isOrContainsReference(Ty.getEnumElementType(ElemDecl, *Mod), Mod))
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static llvm::Optional<bool> proveNonPayloadedEnumCase(SILBasicBlock *BB,
NullablePtr<EnumElementDecl> Decl = SEI->getUniqueCaseForDestination(BB);
if (Decl.isNull())
return None;
return !Decl.get()->getArgumentInterfaceType();
return !Decl.get()->hasAssociatedValues();
}

bool RCIdentityFunctionInfo::
Expand Down
2 changes: 1 addition & 1 deletion lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ SILCombiner::visitInjectEnumAddrInst(InjectEnumAddrInst *IEAI) {

// If the enum does not have a payload create the enum/store since we don't
// need to worry about payloads.
if (!IEAI->getElement()->getArgumentInterfaceType()) {
if (!IEAI->getElement()->hasAssociatedValues()) {
EnumInst *E =
Builder.createEnum(IEAI->getLoc(), SILValue(), IEAI->getElement(),
IEAI->getOperand()->getType().getObjectType());
Expand Down
14 changes: 7 additions & 7 deletions lib/SILOptimizer/Transforms/SILCodeMotion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace {
static void createRefCountOpForPayload(SILBuilder &Builder, SILInstruction *I,
EnumElementDecl *EnumDecl,
SILValue DefOfEnum = SILValue()) {
assert(EnumDecl->getArgumentInterfaceType() &&
assert(EnumDecl->hasAssociatedValues() &&
"We assume enumdecl has an argument type");

SILModule &Mod = I->getModule();
Expand Down Expand Up @@ -755,7 +755,7 @@ static bool tryToSinkRefCountAcrossSwitch(SwitchEnumInst *Switch,
EnumElementDecl *Enum = Case.first;
SILBasicBlock *Succ = Case.second;
Builder.setInsertionPoint(&*Succ->begin());
if (Enum->getArgumentInterfaceType())
if (Enum->hasAssociatedValues())
createRefCountOpForPayload(Builder, &*RV, Enum, Switch->getOperand());
}

Expand Down Expand Up @@ -841,7 +841,7 @@ static bool tryToSinkRefCountAcrossSelectEnum(CondBranchInst *CondBr,
EnumElementDecl *Enum = Elts[i];
SILBasicBlock *Succ = i == 0 ? CondBr->getTrueBB() : CondBr->getFalseBB();
Builder.setInsertionPoint(&*Succ->begin());
if (Enum->getArgumentInterfaceType())
if (Enum->hasAssociatedValues())
createRefCountOpForPayload(Builder, &*I, Enum, SEI->getEnumOperand());
}

Expand Down Expand Up @@ -1304,7 +1304,7 @@ bool BBEnumTagDataflowState::visitRetainValueInst(RetainValueInst *RVI) {
return false;

// If we do not have any argument, kill the retain_value.
if (!(*FindResult)->second->getArgumentInterfaceType()) {
if (!(*FindResult)->second->hasAssociatedValues()) {
RVI->eraseFromParent();
return true;
}
Expand All @@ -1324,7 +1324,7 @@ bool BBEnumTagDataflowState::visitReleaseValueInst(ReleaseValueInst *RVI) {
return false;

// If we do not have any argument, just delete the release value.
if (!(*FindResult)->second->getArgumentInterfaceType()) {
if (!(*FindResult)->second->hasAssociatedValues()) {
RVI->eraseFromParent();
return true;
}
Expand Down Expand Up @@ -1415,7 +1415,7 @@ BBEnumTagDataflowState::hoistDecrementsIntoSwitchRegions(AliasAnalysis *AA) {
for (auto P : EnumBBCaseList) {
// If we don't have an argument for this case, there is nothing to
// do... continue...
if (!P.second->getArgumentInterfaceType())
if (!P.second->hasAssociatedValues())
continue;

// Otherwise create the release_value before the terminator of the
Expand Down Expand Up @@ -1480,7 +1480,7 @@ findRetainsSinkableFromSwitchRegionForEnum(

// If the case does not have an argument type, skip the predecessor since
// there will not be a retain to sink.
if (!Decl->getArgumentInterfaceType())
if (!Decl->hasAssociatedValues())
continue;

// Ok, we found a payloaded predecessor. Look backwards through the
Expand Down
4 changes: 2 additions & 2 deletions lib/SILOptimizer/Transforms/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ static SILInstruction *createEnumElement(SILBuilder &Builder,
auto EnumVal = SEI->getOperand();
// Do we have a payload.
auto EnumTy = EnumVal->getType();
if (EnumElement->getArgumentInterfaceType()) {
if (EnumElement->hasAssociatedValues()) {
auto Ty = EnumTy.getEnumElementType(EnumElement, SEI->getModule());
SILValue UED(Builder.createUncheckedEnumData(SEI->getLoc(), EnumVal,
EnumElement, Ty));
Expand Down Expand Up @@ -1628,7 +1628,7 @@ bool SimplifyCFG::simplifySwitchEnumUnreachableBlocks(SwitchEnumInst *SEI) {
return true;
}

if (!Element || !Element->getArgumentInterfaceType() || Dest->args_empty()) {
if (!Element || !Element->hasAssociatedValues() || Dest->args_empty()) {
assert(Dest->args_empty() && "Unexpected argument at destination!");

SILBuilderWithScope(SEI).createBranch(SEI->getLoc(), Dest);
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CSRanking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ static bool isDeclAsSpecializedAs(TypeChecker &tc, DeclContext *dc,
if (isa<AbstractFunctionDecl>(decl1) || isa<EnumElementDecl>(decl1)) {
// Nothing to do: these have the curried 'self' already.
if (auto elt = dyn_cast<EnumElementDecl>(decl1)) {
checkKind = elt->getArgumentInterfaceType() ? CheckInput : CheckAll;
checkKind = elt->hasAssociatedValues() ? CheckInput : CheckAll;
} else {
checkKind = CheckInput;
}
Expand Down
9 changes: 4 additions & 5 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3071,7 +3071,7 @@ static void checkEnumRawValues(TypeChecker &TC, EnumDecl *ED) {
continue;

// We don't yet support raw values on payload cases.
if (elt->getArgumentInterfaceType()) {
if (elt->hasAssociatedValues()) {
TC.diagnose(elt->getLoc(),
diag::enum_with_raw_type_case_with_argument);
TC.diagnose(ED->getInherited().front().getSourceRange().Start,
Expand Down Expand Up @@ -6570,10 +6570,9 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
return;

// Require the carried type to be materializable.
if (EED->getArgumentInterfaceType() &&
!EED->getArgumentInterfaceType()->isMaterializable()) {
TC.diagnose(EED->getLoc(), diag::enum_element_not_materializable,
EED->getArgumentInterfaceType());
auto IFacTy = EED->getArgumentInterfaceType();
if (IFacTy && !IFacTy->isMaterializable()) {
TC.diagnose(EED->getLoc(), diag::enum_element_not_materializable, IFacTy);
EED->setInterfaceType(ErrorType::get(TC.Context));
EED->setInvalid();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2958,7 +2958,7 @@ void Serializer::writeDecl(const Decl *D) {
addIdentifierRef(elem->getName()),
contextID,
addTypeRef(elem->getInterfaceType()),
!!elem->getArgumentInterfaceType(),
elem->hasAssociatedValues(),
elem->isImplicit(),
(unsigned)RawValueKind,
Negative,
Expand Down

0 comments on commit 3b202c1

Please sign in to comment.