diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index edfa810f1c638..1a493c3bcd013 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -137,11 +137,9 @@ class alignas(8) Expr { protected: union { uint64_t OpaqueBits; - SWIFT_INLINE_BITFIELD_BASE(Expr, bitmax(NumExprKindBits,8)+2+1, + SWIFT_INLINE_BITFIELD_BASE(Expr, bitmax(NumExprKindBits,8)+1, /// The subclass of Expr that this is. Kind : bitmax(NumExprKindBits,8), - /// How this l-value is used, if it's an l-value. - LValueAccessKind : 2, /// Whether the Expr represents something directly written in source or /// it was implicitly generated by the type-checker. Implicit : 1 @@ -381,17 +379,12 @@ class alignas(8) Expr { private: /// Ty - This is the type of the expression. Type Ty; - - void setLValueAccessKind(AccessKind accessKind) { - Bits.Expr.LValueAccessKind = unsigned(accessKind) + 1; - } protected: Expr(ExprKind Kind, bool Implicit, Type Ty = Type()) : Ty(Ty) { Bits.OpaqueBits = 0; Bits.Expr.Kind = unsigned(Kind); Bits.Expr.Implicit = Implicit; - Bits.Expr.LValueAccessKind = 0; } public: @@ -499,32 +492,6 @@ class alignas(8) Expr { Bits.Expr.Implicit = Implicit; } - /// getLValueAccessKind - Determines how this l-value expression is used. - AccessKind getLValueAccessKind() const { - assert(hasLValueAccessKind()); - return AccessKind(Bits.Expr.LValueAccessKind - 1); - } - bool hasLValueAccessKind() const { - return Bits.Expr.LValueAccessKind != 0; - } - void clearLValueAccessKind() { - Bits.Expr.LValueAccessKind = 0; - } - - /// Set that this l-value expression is used in the given way. - /// - /// This information is also correctly propagated to any l-value - /// sub-expressions from which this l-value is derived. - /// - /// \param allowOverwrite - true if it's okay if an expression already - /// has an access kind - void propagateLValueAccessKind(AccessKind accessKind, - llvm::function_ref getType - = [](Expr *E) -> Type { - return E->getType(); - }, - bool allowOverwrite = false); - /// Retrieves the declaration that is being referenced by this /// expression, if any. ConcreteDeclRef getReferencedDecl() const; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 99729c0284c83..92b35bb4e1b47 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -1734,11 +1734,6 @@ class PrintExpr : public ExprVisitor { PrintWithColorRAII(OS, ExprModifierColor) << " implicit"; PrintWithColorRAII(OS, TypeColor) << " type='" << GetTypeOfExpr(E) << '\''; - if (E->hasLValueAccessKind()) { - PrintWithColorRAII(OS, ExprModifierColor) - << " accessKind=" << getAccessKindString(E->getLValueAccessKind()); - } - // If we have a source range and an ASTContext, print the source range. if (auto Ty = GetTypeOfExpr(E)) { auto &Ctx = Ty->getASTContext(); diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index 0d95ad2cb7640..2234517789b89 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -558,16 +558,6 @@ class Verifier : public ASTWalker { } return; } - - // Require an access kind to be set on every l-value expression. - // Note that the empty tuple type is assignable but usually isn't - // an l-value, so we have to be conservative there. - if (E->getType()->hasLValueType() != E->hasLValueAccessKind() && - !(E->hasLValueAccessKind() && E->getType()->isAssignableType())) { - Out << "l-value expression does not have l-value access kind set\n"; - E->print(Out); - abort(); - } } void verifyChecked(Stmt *S) {} void verifyChecked(Pattern *P) { } @@ -1757,7 +1747,6 @@ class Verifier : public ASTWalker { Out << "Unexpected types in IdentityExpr\n"; abort(); } - checkSameLValueAccessKind(E, E->getSubExpr(), "IdentityExpr"); verifyCheckedBase(E); } @@ -3136,15 +3125,6 @@ class Verifier : public ASTWalker { abort(); } - void checkSameLValueAccessKind(Expr *LHS, Expr *RHS, const char *what) { - if (LHS->hasLValueAccessKind() != RHS->hasLValueAccessKind() || - (LHS->hasLValueAccessKind() && - LHS->getLValueAccessKind() != RHS->getLValueAccessKind())) { - Out << what << " has a mismatched l-value access kind\n"; - abort(); - } - } - // Verification utilities. Type checkMetatypeType(Type type, const char *what) { auto metatype = type->getAs(); diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index c117271d7edcd..641f9f37fdd17 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -220,179 +220,6 @@ DeclRefExpr *Expr::getMemberOperatorRef() { return operatorRef; } -/// Propagate l-value use information to children. -void Expr::propagateLValueAccessKind(AccessKind accessKind, - llvm::function_ref getType, - bool allowOverwrite) { - /// A visitor class which walks an entire l-value expression. - class PropagateAccessKind - : public ExprVisitor { - llvm::function_ref GetType; -#ifndef NDEBUG - bool AllowOverwrite; -#endif - public: - PropagateAccessKind(llvm::function_ref getType, - bool allowOverwrite) : GetType(getType) -#ifndef NDEBUG - , AllowOverwrite(allowOverwrite) -#endif - {} - - void visit(Expr *E, AccessKind kind) { - assert((AllowOverwrite || !E->hasLValueAccessKind()) && - "l-value access kind has already been set"); - - assert(GetType(E)->isAssignableType() && - "setting access kind on non-l-value"); - E->setLValueAccessKind(kind); - - // Propagate this to sub-expressions. - ASTVisitor::visit(E, kind); - } - -#define NON_LVALUE_EXPR(KIND) \ - void visit##KIND##Expr(KIND##Expr *, AccessKind accessKind) { \ - llvm_unreachable("not an l-value"); \ - } -#define LEAF_LVALUE_EXPR(KIND) \ - void visit##KIND##Expr(KIND##Expr *E, AccessKind accessKind) {} -#define COMPLETE_PHYSICAL_LVALUE_EXPR(KIND, ACCESSOR) \ - void visit##KIND##Expr(KIND##Expr *E, AccessKind accessKind) { \ - visit(E->ACCESSOR, accessKind); \ - } -#define PARTIAL_PHYSICAL_LVALUE_EXPR(KIND, ACCESSOR) \ - void visit##KIND##Expr(KIND##Expr *E, AccessKind accessKind) { \ - visit(E->ACCESSOR, getPartialAccessKind(accessKind)); \ - } - - void visitMemberRefExpr(MemberRefExpr *E, AccessKind accessKind) { - if (!GetType(E->getBase())->hasLValueType()) return; - visit(E->getBase(), getBaseAccessKind(E->getMember(), accessKind)); - } - void visitSubscriptExpr(SubscriptExpr *E, AccessKind accessKind) { - if (!GetType(E->getBase())->hasLValueType()) return; - visit(E->getBase(), getBaseAccessKind(E->getDecl(), accessKind)); - } - void visitKeyPathApplicationExpr(KeyPathApplicationExpr *E, - AccessKind accessKind) { - if (!GetType(E->getBase())->hasLValueType()) return; - auto kpDecl = GetType(E->getKeyPath())->castTo() - ->getDecl(); - AccessKind baseAccess; - // A ReferenceWritableKeyPath only reads its base. - if (kpDecl == - GetType(E)->getASTContext().getReferenceWritableKeyPathDecl()) - baseAccess = AccessKind::Read; - else - // Assuming a writable keypath projects a part of the base. - baseAccess = getPartialAccessKind(accessKind); - - visit(E->getBase(), baseAccess); - } - - static AccessKind getPartialAccessKind(AccessKind accessKind) { - return (accessKind == AccessKind::Read - ? accessKind : AccessKind::ReadWrite); - } - - static AccessKind getBaseAccessKind(ConcreteDeclRef member, - AccessKind accessKind) { - // We assume writes are partial writes, so the result is always - // either Read or ReadWrite. - auto memberDecl = cast(member.getDecl()); - - // If we're reading and the getter is mutating, or we're writing - // and the setter is mutating, this is readwrite. - if ((accessKind != AccessKind::Write && - memberDecl->isGetterMutating()) || - (accessKind != AccessKind::Read && - memberDecl->isSetterMutating())) { - return AccessKind::ReadWrite; - } - - return AccessKind::Read; - } - - void visitTupleExpr(TupleExpr *E, AccessKind accessKind) { - for (auto elt : E->getElements()) { - visit(elt, accessKind); - } - } - - void visitOpenExistentialExpr(OpenExistentialExpr *E, - AccessKind accessKind) { - AccessKind oldOpaqueValueAK; - bool opaqueValueHadAK; - if (E->getOpaqueValue()) { - opaqueValueHadAK = E->getOpaqueValue()->hasLValueAccessKind(); - oldOpaqueValueAK = - (opaqueValueHadAK ? E->getOpaqueValue()->getLValueAccessKind() - : AccessKind::Read); - } - - visit(E->getSubExpr(), accessKind); - - if (E->getOpaqueValue()) { - // Propagate the new access kind from the OVE to the original - // existential if we just set or changed it on the OVE. - if (E->getOpaqueValue()->hasLValueAccessKind()) { - auto newOpaqueValueAK = E->getOpaqueValue()->getLValueAccessKind(); - if (!opaqueValueHadAK || newOpaqueValueAK != oldOpaqueValueAK) - visit(E->getExistentialValue(), newOpaqueValueAK); - } - } - } - - LEAF_LVALUE_EXPR(DeclRef) - LEAF_LVALUE_EXPR(DiscardAssignment) - LEAF_LVALUE_EXPR(DynamicLookup) - LEAF_LVALUE_EXPR(OpaqueValue) - LEAF_LVALUE_EXPR(EditorPlaceholder) - LEAF_LVALUE_EXPR(Error) - - COMPLETE_PHYSICAL_LVALUE_EXPR(AnyTry, getSubExpr()) - PARTIAL_PHYSICAL_LVALUE_EXPR(BindOptional, getSubExpr()) - COMPLETE_PHYSICAL_LVALUE_EXPR(DotSyntaxBaseIgnored, getRHS()); - PARTIAL_PHYSICAL_LVALUE_EXPR(ForceValue, getSubExpr()) - COMPLETE_PHYSICAL_LVALUE_EXPR(Identity, getSubExpr()) - PARTIAL_PHYSICAL_LVALUE_EXPR(TupleElement, getBase()) - - NON_LVALUE_EXPR(Literal) - NON_LVALUE_EXPR(SuperRef) - NON_LVALUE_EXPR(Type) - NON_LVALUE_EXPR(OtherConstructorDeclRef) - NON_LVALUE_EXPR(Collection) - NON_LVALUE_EXPR(CaptureList) - NON_LVALUE_EXPR(AbstractClosure) - NON_LVALUE_EXPR(InOut) - NON_LVALUE_EXPR(DynamicType) - NON_LVALUE_EXPR(RebindSelfInConstructor) - NON_LVALUE_EXPR(Apply) - NON_LVALUE_EXPR(MakeTemporarilyEscapable) - NON_LVALUE_EXPR(ImplicitConversion) - NON_LVALUE_EXPR(ExplicitCast) - NON_LVALUE_EXPR(OptionalEvaluation) - NON_LVALUE_EXPR(If) - NON_LVALUE_EXPR(Assign) - NON_LVALUE_EXPR(CodeCompletion) - NON_LVALUE_EXPR(ObjCSelector) - NON_LVALUE_EXPR(KeyPath) - NON_LVALUE_EXPR(EnumIsCase) - NON_LVALUE_EXPR(LazyInitializer) - -#define UNCHECKED_EXPR(KIND, BASE) \ - NON_LVALUE_EXPR(KIND) -#include "swift/AST/ExprNodes.def" - -#undef PHYSICAL_LVALUE_EXPR -#undef LEAF_LVALUE_EXPR -#undef NON_LVALUE_EXPR - }; - - PropagateAccessKind(getType, allowOverwrite).visit(this, accessKind); -} - ConcreteDeclRef Expr::getReferencedDecl() const { switch (getKind()) { // No declaration reference. diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index dcf69ff04f37f..485203329b16a 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -454,7 +454,6 @@ makeEnumRawValueConstructor(ClangImporter::Implementation &Impl, auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(), /*implicit*/true); selfRef->setType(LValueType::get(selfDecl->getType())); - selfRef->propagateLValueAccessKind(AccessKind::Write); auto paramRef = new (C) DeclRefExpr(param, DeclNameLoc(), /*implicit*/ true); @@ -1184,7 +1183,6 @@ createDefaultConstructor(ClangImporter::Implementation &Impl, Expr *lhs = new (context) DeclRefExpr(selfDecl, DeclNameLoc(), /*Implicit=*/true); lhs->setType(LValueType::get(selfType)); - lhs->propagateLValueAccessKind(AccessKind::Write); auto emptyTuple = TupleType::getEmpty(context); @@ -1326,7 +1324,6 @@ createValueConstructor(ClangImporter::Implementation &Impl, /*Implicit=*/true, semantics); lhs->setType(LValueType::get(var->getType())); - lhs->propagateLValueAccessKind(AccessKind::Write); // Construct right-hand side. auto rhs = new (context) DeclRefExpr(valueParameters[paramPos], @@ -1474,7 +1471,6 @@ static ConstructorDecl *createRawValueBridgingConstructor( DeclNameLoc(), /*Implicit=*/true, AccessSemantics::DirectToStorage); lhs->setType(LValueType::get(storedType)); - lhs->propagateLValueAccessKind(AccessKind::Write); // Construct right-hand side. // FIXME: get the parameter from the init, and plug it in here. diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 8437e4de1e934..7daa8f2b55cbc 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -246,22 +246,6 @@ getImplicitMemberReferenceAccessSemantics(Expr *base, VarDecl *member, return member->getAccessSemanticsFromContext(DC, isAccessOnSelf); } -void ConstraintSystem::propagateLValueAccessKind(Expr *E, AccessKind accessKind, - bool isShallow, - bool allowOverwrite) { - // If solver is set up in "shallow" mode we expect that some of the - // sub-expressions are already type-checked which means that they - // already have access kind set. - if (isShallow && E->hasLValueAccessKind() && !allowOverwrite) - return; - - E->propagateLValueAccessKind(accessKind, - [&](Expr *E) -> Type { - return getType(E); - }, - allowOverwrite); -} - bool ConstraintSystem::isTypeReference(const Expr *E) { return E->isTypeReference([&](const Expr *E) -> Type { return getType(E); }); } @@ -425,7 +409,6 @@ namespace { DeclContext *dc; const Solution &solution; bool SuppressDiagnostics; - bool IsShallow; /// Recognize used conformances from an imported type when we must emit /// the witness table. @@ -895,16 +878,6 @@ namespace { } } - // If the opaque value has an l-value access kind, then - // the OpenExistentialExpr isn't making a derived l-value, which - // means this is our only chance to propagate the l-value access kind - // down to the original existential value. Otherwise, propagateLVAK - // will handle this. - if (record.OpaqueValue && record.OpaqueValue->hasLValueAccessKind()) - cs.propagateLValueAccessKind(record.ExistentialValue, - record.OpaqueValue->getLValueAccessKind(), - IsShallow); - // Form the open-existential expression. result = new (tc.Context) OpenExistentialExpr( record.ExistentialValue, @@ -1854,9 +1827,9 @@ namespace { public: ExprRewriter(ConstraintSystem &cs, const Solution &solution, - bool suppressDiagnostics, bool shallow = false) + bool suppressDiagnostics) : cs(cs), dc(cs.DC), solution(solution), - SuppressDiagnostics(suppressDiagnostics), IsShallow(shallow) {} + SuppressDiagnostics(suppressDiagnostics) {} ConstraintSystem &getConstraintSystem() const { return cs; } @@ -3176,13 +3149,6 @@ namespace { } Expr *visitInOutExpr(InOutExpr *expr) { - // The default assumption is that inouts are read-write. It's easier - // to do this unconditionally here and then overwrite in the exception - // case (when we turn the inout into an UnsafePointer) than to try to - // discover that we're in that case right now. - if (!cs.getType(expr->getSubExpr())->is()) - cs.propagateLValueAccessKind(expr->getSubExpr(), AccessKind::ReadWrite, - IsShallow); auto objectTy = cs.getType(expr->getSubExpr())->getRValueType(); // The type is simply inout of whatever the lvalue's object type was. @@ -3875,8 +3841,6 @@ namespace { auto destTy = cs.computeAssignDestType(expr->getDest(), expr->getLoc()); if (!destTy) return nullptr; - cs.propagateLValueAccessKind(expr->getDest(), AccessKind::Write, - IsShallow); // Convert the source to the simplified destination type. auto locator = @@ -4197,11 +4161,6 @@ namespace { return E; } - if (cs.getType(subExpr)->hasLValueType()) { - // Treat this like a read of the property. - cs.propagateLValueAccessKind(subExpr, AccessKind::Read, IsShallow); - } - // Check that we requested a property getter or setter. switch (E->getSelectorKind()) { case ObjCSelectorExpr::Method: { @@ -6601,7 +6560,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, // Load from the lvalue. If we're loading the result of a force, // swap the order so that we load first and force the result. - cs.propagateLValueAccessKind(expr, AccessKind::Read, IsShallow); if (auto *forceExpr = dyn_cast(expr)) { fromType = cs.getType(forceExpr->getSubExpr())->getRValueType(); auto *loadExpr = cs.cacheType( @@ -6708,13 +6666,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, PointerTypeKind pointerKind; auto toEltType = unwrappedTy->getAnyPointerElementType(pointerKind); assert(toEltType && "not a pointer type?"); (void) toEltType; - if (pointerKind == PTK_UnsafePointer) { - // Overwrite the l-value access kind to be read-only if we're - // converting to a non-mutable pointer type. - auto *E = cast(expr->getValueProvidingExpr())->getSubExpr(); - cs.propagateLValueAccessKind(E, AccessKind::Read, IsShallow, - /*overwrite*/ true); - } tc.requirePointerArgumentIntrinsics(expr->getLoc()); Expr *result = @@ -6820,7 +6771,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, // In an 'inout' operator like "i += 1", the operand is converted from // an implicit lvalue to an inout argument. assert(toIO->getObjectType()->isEqual(fromLValue->getObjectType())); - cs.propagateLValueAccessKind(expr, AccessKind::ReadWrite, IsShallow); return cs.cacheType(new (tc.Context) InOutExpr(expr->getStartLoc(), expr, toIO->getObjectType(), @@ -6839,7 +6789,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, if (performLoad) { // Load from the lvalue. - cs.propagateLValueAccessKind(expr, AccessKind::Read, IsShallow); expr = cs.cacheType(new (tc.Context) LoadExpr(expr, fromLValue->getObjectType())); @@ -7100,7 +7049,6 @@ ExprRewriter::coerceObjectArgumentToType(Expr *expr, // Use InOutExpr to convert it to an explicit inout argument for the // receiver. - cs.propagateLValueAccessKind(expr, AccessKind::ReadWrite, IsShallow); return cs.cacheType(new (ctx) InOutExpr(expr->getStartLoc(), expr, toInOutTy->getInOutObjectType(), /*isImplicit*/ true)); @@ -8263,7 +8211,7 @@ Expr *ConstraintSystem::applySolution(Solution &solution, Expr *expr, Expr *ConstraintSystem::applySolutionShallow(const Solution &solution, Expr *expr, bool suppressDiagnostics) { - ExprRewriter rewriter(*this, solution, suppressDiagnostics, true); + ExprRewriter rewriter(*this, solution, suppressDiagnostics); rewriter.walkToExprPre(expr); Expr *result = rewriter.walkToExprPost(expr); if (result) diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp index d1fa971df277a..d0d22e30cc429 100644 --- a/lib/Sema/CSDiag.cpp +++ b/lib/Sema/CSDiag.cpp @@ -2130,7 +2130,6 @@ namespace { } expr->setType(nullptr); - expr->clearLValueAccessKind(); return { true, expr }; } diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp index 9490780945f34..0c8af525b48e1 100644 --- a/lib/Sema/CodeSynthesis.cpp +++ b/lib/Sema/CodeSynthesis.cpp @@ -1620,7 +1620,6 @@ void TypeChecker::completePropertyBehaviorAccessors(VarDecl *VD, // Access the base as inout if the accessor is mutating. auto lvTy = LValueType::get(selfTy); selfExpr->setType(lvTy); - selfExpr->propagateLValueAccessKind(AccessKind::ReadWrite); selfExpr = new (Context) InOutExpr(SourceLoc(), selfExpr, selfTy, /*implicit*/ true); } @@ -1643,7 +1642,6 @@ void TypeChecker::completePropertyBehaviorAccessors(VarDecl *VD, if (ValueImpl->isSettable(VD->getDeclContext())) { auto valueLVTy = LValueType::get(valueTy); implMemberExpr->setType(valueLVTy); - implMemberExpr->propagateLValueAccessKind(AccessKind::Read); returnExpr = new (Context) LoadExpr(implMemberExpr, valueTy); returnExpr->setImplicit(); @@ -1672,7 +1670,6 @@ void TypeChecker::completePropertyBehaviorAccessors(VarDecl *VD, /*implicit*/ true); auto valueLVTy = LValueType::get(valueTy); implMemberExpr->setType(valueLVTy); - implMemberExpr->propagateLValueAccessKind(AccessKind::Write); ConcreteDeclRef newValueRef = getFirstParamDecl(setter); auto newValueExpr = new (Context) DeclRefExpr(newValueRef, DeclNameLoc(), diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h index eca37520911df..1fc8f27c9a8b4 100644 --- a/lib/Sema/ConstraintSystem.h +++ b/lib/Sema/ConstraintSystem.h @@ -2070,12 +2070,6 @@ class ConstraintSystem { /// \brief Determine if the type in question is AnyHashable. bool isAnyHashableType(Type t); - /// Call Expr::propagateLValueAccessKind on the given expression, - /// using a custom accessor for the type on the expression that - /// reads the type from the ConstraintSystem expression type map. - void propagateLValueAccessKind(Expr *E, AccessKind accessKind, bool isShallow, - bool allowOverwrite = false); - /// Call Expr::isTypeReference on the given expression, using a /// custom accessor for the type on the expression that reads the /// type from the ConstraintSystem expression type map. diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index e567364790a77..463aa618f6347 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -3062,7 +3062,6 @@ Expr *TypeChecker::coerceToRValue(Expr *expr, // Load lvalues. if (auto lvalue = exprTy->getAs()) { - expr->propagateLValueAccessKind(AccessKind::Read, getType); auto result = new (Context) LoadExpr(expr, lvalue->getObjectType()); setType(result, lvalue->getObjectType()); return result; diff --git a/validation-test/compiler_crashers/28627-unreachable-executed-at-swift-include-swift-ast-exprnodes-def-79.swift b/validation-test/compiler_crashers_fixed/28627-unreachable-executed-at-swift-include-swift-ast-exprnodes-def-79.swift similarity index 86% rename from validation-test/compiler_crashers/28627-unreachable-executed-at-swift-include-swift-ast-exprnodes-def-79.swift rename to validation-test/compiler_crashers_fixed/28627-unreachable-executed-at-swift-include-swift-ast-exprnodes-def-79.swift index ecf0c844ae127..8edcde1b61c86 100644 --- a/validation-test/compiler_crashers/28627-unreachable-executed-at-swift-include-swift-ast-exprnodes-def-79.swift +++ b/validation-test/compiler_crashers_fixed/28627-unreachable-executed-at-swift-include-swift-ast-exprnodes-def-79.swift @@ -5,5 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir [(t:_._=(