Skip to content

Commit 2373191

Browse files
committed
Always emit enum cases as normal applies
1 parent 4994fef commit 2373191

19 files changed

+199
-150
lines changed

lib/Parse/ParsePattern.cpp

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,17 @@ template <typename T>
407407
static TypeRepr *
408408
validateParameterWithSpecifier(Parser &parser,
409409
Parser::ParsedParameter &paramInfo,
410-
StringRef specifierName) {
410+
StringRef specifierName,
411+
bool parsingEnumElt) {
411412
auto type = paramInfo.Type;
412413
auto loc = paramInfo.SpecifierLoc;
414+
// If we're validating an enum element, 'inout' is not allowed
415+
// at all - Sema will catch this for us. In all other contexts, we
416+
// assume the user put 'inout' in the wrong place and offer a fixit.
417+
if (parsingEnumElt) {
418+
return new (parser.Context) T(type, loc);
419+
}
420+
413421
if (isa<SpecifierTypeRepr>(type)) {
414422
parser.diagnose(loc, diag::parameter_specifier_repeated).fixItRemove(loc);
415423
} else {
@@ -446,10 +454,11 @@ mapParsedParameters(Parser &parser,
446454
argNameLoc, argName,
447455
paramNameLoc, paramName, Type(),
448456
parser.CurDeclContext);
457+
bool parsingEnumElt
458+
= (paramContext == Parser::ParameterContextKind::EnumElement);
449459
// If we're not parsing an enum case, lack of a SourceLoc for both
450460
// names indicates the parameter is synthetic.
451-
if (paramContext != Parser::ParameterContextKind::EnumElement &&
452-
argNameLoc.isInvalid() && paramNameLoc.isInvalid())
461+
if (!parsingEnumElt && argNameLoc.isInvalid() && paramNameLoc.isInvalid())
453462
param->setImplicit();
454463

455464
// If we diagnosed this parameter as a parse error, propagate to the decl.
@@ -458,21 +467,19 @@ mapParsedParameters(Parser &parser,
458467

459468
// If a type was provided, create the type for the parameter.
460469
if (auto type = paramInfo.Type) {
461-
if (paramContext != Parser::ParameterContextKind::EnumElement) {
462-
// If 'inout' was specified, turn the type into an in-out type.
463-
if (paramInfo.SpecifierKind == VarDecl::Specifier::InOut) {
464-
type = validateParameterWithSpecifier<InOutTypeRepr>(parser,
465-
paramInfo,
466-
"inout");
467-
} else if (paramInfo.SpecifierKind == VarDecl::Specifier::Shared) {
468-
type = validateParameterWithSpecifier<SharedTypeRepr>(parser,
469-
paramInfo,
470-
"__shared");
471-
} else if (paramInfo.SpecifierKind == VarDecl::Specifier::Owned) {
472-
type = validateParameterWithSpecifier<OwnedTypeRepr>(parser,
473-
paramInfo,
474-
"__owned");
475-
}
470+
// If 'inout' was specified, turn the type into an in-out type.
471+
if (paramInfo.SpecifierKind == VarDecl::Specifier::InOut) {
472+
type = validateParameterWithSpecifier<InOutTypeRepr>(parser, paramInfo,
473+
"inout",
474+
parsingEnumElt);
475+
} else if (paramInfo.SpecifierKind == VarDecl::Specifier::Shared) {
476+
type = validateParameterWithSpecifier<SharedTypeRepr>(parser, paramInfo,
477+
"__shared",
478+
parsingEnumElt);
479+
} else if (paramInfo.SpecifierKind == VarDecl::Specifier::Owned) {
480+
type = validateParameterWithSpecifier<OwnedTypeRepr>(parser, paramInfo,
481+
"__owned",
482+
parsingEnumElt);
476483
}
477484
param->getTypeLoc() = TypeLoc(type);
478485
} else if (paramContext != Parser::ParameterContextKind::Closure) {

lib/SILGen/ArgumentSource.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,18 +223,6 @@ class ArgumentSource {
223223
bool isRValue() const & { return StoredKind == Kind::RValue; }
224224
bool isLValue() const & { return StoredKind == Kind::LValue; }
225225
bool isTuple() const & { return StoredKind == Kind::Tuple; }
226-
bool isTupleShuffleExpr() const & {
227-
if (StoredKind == Kind::Expr) {
228-
auto *e = asKnownExpr();
229-
if (auto *TSE = dyn_cast<TupleShuffleExpr>(e)) {
230-
return llvm::any_of(TSE->getElementMapping(), [](const int &i) {
231-
return i == TupleShuffleExpr::DefaultInitialize
232-
|| i == TupleShuffleExpr::CallerDefaultInitialize;
233-
});
234-
}
235-
}
236-
return false;
237-
}
238226

239227
/// Given that this source is storing an RValue, extract and clear
240228
/// that value.

lib/SILGen/SILGenApply.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,10 +3481,6 @@ class CallEmission {
34813481
extraSites.push_back(std::move(site));
34823482
}
34833483

3484-
bool isArgTupleShuffle() const {
3485-
return ArgValue.isTupleShuffleExpr();
3486-
}
3487-
34883484
/// Add a level of function application by passing in its possibly
34893485
/// unevaluated arguments and their formal type
34903486
template<typename...T>
@@ -3639,12 +3635,6 @@ CallEmission::applyFirstLevelCallee(SGFContext C) {
36393635
return applyPartiallyAppliedSuperMethod(C);
36403636
}
36413637

3642-
if (isEnumElementConstructor() && !llvm::any_of(uncurriedSites, [](const CallSite &s){
3643-
return s.isArgTupleShuffle();
3644-
})) {
3645-
return applyEnumElementConstructor(C);
3646-
}
3647-
36483638
return applyNormalCall(C);
36493639
}
36503640

test/Compatibility/enum_element_pattern.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func testE(e: E) {
2626
break
2727
case .C(): // Ok.
2828
break
29-
case .D(let payload):
29+
case .D(let payload): // Ok. 'payload' has type '()'.
3030
let _: () = payload
3131
break
3232
default:
@@ -35,7 +35,7 @@ func testE(e: E) {
3535

3636
guard
3737
case .C() = e, // Ok. SILGen assert this, but no-assert Swift3 GM build didn't assert.
38-
case .D(let payload) = e
38+
case .D(let payload) = e // FIXME: Should be rejected. Swift3 IRGen verifier did catch this.
3939
else { return }
4040
print(payload)
4141
}
@@ -49,6 +49,6 @@ do {
4949
try canThrow()
5050
} catch E.A() { // Ok.
5151
// ..
52-
} catch E.B(let payload) {
52+
} catch E.B(let payload) { // Ok. 'payload' has type '()'.
5353
let _: () = payload
5454
}

test/IRGen/class_resilience_thunks.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ public func testDispatchThunkDerived(d: Derived) {
2929
// CHECK: call swiftcc void @"$S22resilient_class_thunks4BaseC6takesTyyxFTj"(%swift.opaque* noalias nocapture dereferenceable({{4|8}}) {{%.*}}, %T22resilient_class_thunks4BaseC* swiftself {{%.*}})
3030
d.takesT(0)
3131

32-
// CHECK: call swiftcc void @"$S22resilient_class_thunks7DerivedC8takesIntyySiSgFTj"([[INT]] 0, i8 1, %T22resilient_class_thunks7DerivedC* swiftself %0)
32+
// CHECK: call swiftcc void @"$S22resilient_class_thunks7DerivedC8takesIntyySiSgFTj"([[INT]] {{%.*}}, i8 {{%.*}}, %T22resilient_class_thunks7DerivedC* swiftself %0)
3333
d.takesInt(nil)
3434

35-
// CHECK: call swiftcc void @"$S22resilient_class_thunks4BaseC14takesReferenceyyAA6ObjectCFTj"(%T22resilient_class_thunks6ObjectC* null, %T22resilient_class_thunks4BaseC* swiftself {{%.*}})
35+
// CHECK: call swiftcc void @"$S22resilient_class_thunks4BaseC14takesReferenceyyAA6ObjectCFTj"(%T22resilient_class_thunks6ObjectC* {{%.*}}, %T22resilient_class_thunks4BaseC* swiftself {{%.*}})
3636
d.takesReference(nil)
3737

3838
// CHECK: ret void

test/IRGen/dynamic_self_metadata.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
class C {
1616
class func fromMetatype() -> Self? { return nil }
1717
// CHECK-LABEL: define hidden swiftcc i64 @"$S21dynamic_self_metadata1CC12fromMetatypeACXDSgyFZ"(%swift.type* swiftself)
18-
// CHECK: ret i64 0
18+
// CHECK: ret i64 {{%.*}}
1919

2020
func fromInstance() -> Self? { return nil }
2121
// CHECK-LABEL: define hidden swiftcc i64 @"$S21dynamic_self_metadata1CC12fromInstanceACXDSgyF"(%T21dynamic_self_metadata1CC* swiftself)
22-
// CHECK: ret i64 0
22+
// CHECK: ret i64 {{%.*}}
2323

2424
func dynamicSelfArgument() -> Self? {
2525
return id(nil)

test/IRGen/enum_resilience.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,22 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
119119
// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT:i32|i64]] -1
120120
// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
121121

122+
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
123+
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]], align 8, !invariant.load !11
124+
// CHECK-NEXT: [[ALLOCA_SIZE:%.*]] = ptrtoint i8* [[WITNESS]] to i64
125+
// CHECK-NEXT: [[STACK:%.*]] = alloca i8, i64 [[ALLOCA_SIZE]], align 16
126+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 -1, i8* [[STACK]])
127+
// CHECK-NEXT: [[DEST:%.*]] = bitcast i8* [[STACK]] to %swift.opaque*
128+
122129
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 2
123130
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
124131
// CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
125-
// CHECK-NEXT: [[COPY:%.*]] = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias %0, %swift.opaque* noalias %1, %swift.type* [[METADATA]])
132+
// CHECK-NEXT: [[COPY:%.*]] = call %swift.opaque* %initializeWithCopy(%swift.opaque* noalias [[DEST]], %swift.opaque* noalias %1, %swift.type* [[METADATA]])
133+
134+
// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 4
135+
// CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
136+
// CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
137+
// CHECK-NEXT: [[COPY:%.*]] = call %swift.opaque* %initializeWithTake(%swift.opaque* noalias %0, %swift.opaque* noalias [[DEST]], %swift.type* [[METADATA]])
126138

127139
// CHECK-NEXT: [[METADATA2:%.*]] = call %swift.type* @"$S14resilient_enum6MediumOMa"()
128140
// CHECK-NEXT: [[METADATA_ADDR2:%.*]] = bitcast %swift.type* [[METADATA2]] to i8***
@@ -139,6 +151,9 @@ public func constructResilientEnumPayload(_ s: Size) -> Medium {
139151
// CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
140152
// CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %1, %swift.type* [[METADATA]])
141153

154+
// CHECK-NEXT: [[STACK:%.*]] = bitcast %swift.opaque* [[DEST]] to i8*
155+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[STACK]])
156+
142157
// CHECK-NEXT: ret void
143158
return Medium.Postcard(s)
144159
}

test/SILGen/argument_shuffle_swift3.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ func g(x: Any) {
1717
// CHECK: apply [[FN:%.*]]({{.*}}) : $@convention(thin) (@in Any) -> ()
1818
fn(data: x)
1919

20-
// CHECK: inject_enum_addr {{.*}} : $*HasAnyCase, #HasAnyCase.any!enumelt.1
20+
// CHECK: // function_ref HasAnyCase.any(_:)
21+
// CHECK-NEXT: [[ENUM_CASE:%.*]] = function_ref @$S23argument_shuffle_swift310HasAnyCaseO3anyyACypcACmF
22+
// CHECK-NEXT: apply [[ENUM_CASE]]({{.*}})
2123
_ = HasAnyCase.any(123)
2224

23-
// CHECK: inject_enum_addr {{.*}} : $*HasAnyCase, #HasAnyCase.any!enumelt.1
25+
// CHECK: // function_ref HasAnyCase.any(_:)
26+
// CHECK-NEXT: [[ENUM_CASE:%.*]] = function_ref @$S23argument_shuffle_swift310HasAnyCaseO3anyyACypcACmF
27+
// CHECK-NEXT: apply [[ENUM_CASE]]({{.*}})
2428
_ = HasAnyCase.any(data: 123)
2529

2630
// CHECK: return

test/SILGen/default_arguments.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -377,19 +377,19 @@ enum default_args {
377377
case defarg2(i: Int, d: Double = 3.14159, s: String = "Hello")
378378
}
379379

380-
// CHECK-LABEL: sil hidden @_T017default_arguments18testDefaultArgEnumyyF
380+
// CHECK-LABEL: sil hidden @$S17default_arguments18testDefaultArgEnumyyF
381381
func testDefaultArgEnum() {
382382
// CHECK: [[METATYPE_DEF_1:%[0-9]+]] = metatype $@thin default_args.Type
383383

384384
// implicit closure #1
385-
// CHECK: [[THIN_FILE_ARG_THUNK1:%[0-9]+]] = function_ref @_T017default_arguments18testDefaultArgEnumyyFSSyXKfu_ : $@convention(thin) () -> @owned String
385+
// CHECK: [[THIN_FILE_ARG_THUNK1:%[0-9]+]] = function_ref @$S17default_arguments18testDefaultArgEnumyyFSSyXAfu_ : $@convention(thin) () -> @owned String
386386
// CHECK-NEXT: [[THICK_FILE_ARG_THUNK1:%[0-9]+]] = thin_to_thick_function [[THIN_FILE_ARG_THUNK1]] : $@convention(thin) () -> @owned String to $@callee_guaranteed () -> @owned String
387387

388388
// implicit closure #2
389-
// CHECK: [[THIN_LINE_ARG_THUNK2:%[0-9]+]] = function_ref @_T017default_arguments18testDefaultArgEnumyyFSiyXKfu0_ : $@convention(thin) () -> Int
389+
// CHECK: [[THIN_LINE_ARG_THUNK2:%[0-9]+]] = function_ref @$S17default_arguments18testDefaultArgEnumyyFSiyXAfu0_ : $@convention(thin) () -> Int
390390
// CHECK-NEXT: [[THICK_LINE_ARG_THUNK2:%[0-9]+]] = thin_to_thick_function [[THIN_LINE_ARG_THUNK2]] : $@convention(thin) () -> Int to $@callee_guaranteed () -> Int
391391

392-
// CHECK: [[DEF1_THUNK:%[0-9]+]] = function_ref @_T017default_arguments0A5_argsO7defarg1yACSSyXK_SiyXKtcACmF : $@convention(method) (@owned @callee_guaranteed () -> @owned String, @owned @callee_guaranteed () -> Int, @thin default_args.Type) -> @owned default_args
392+
// CHECK: [[DEF1_THUNK:%[0-9]+]] = function_ref @$S17default_arguments0A5_argsO7defarg1yACSSyXA_SiyXAtcACmF : $@convention(method) (@owned @callee_guaranteed () -> @owned String, @owned @callee_guaranteed () -> Int, @thin default_args.Type) -> @owned default_args
393393

394394
// CHECK: apply [[DEF1_THUNK]]([[THICK_FILE_ARG_THUNK1]], [[THICK_LINE_ARG_THUNK2]], [[METATYPE_DEF_1]])
395395
_ = default_args.defarg1()
@@ -400,14 +400,14 @@ func testDefaultArgEnum() {
400400
// CHECK: integer_literal $Builtin.Int
401401

402402
// default argument 1
403-
// CHECK: [[DOUBLE_ARG_THUNK:%[0-9]+]] = function_ref @_T017default_arguments0A5_argsOfA0_ : $@convention(thin) () -> Double
403+
// CHECK: [[DOUBLE_ARG_THUNK:%[0-9]+]] = function_ref @$S17default_arguments0A5_argsOfA0_ : $@convention(thin) () -> Double
404404
// CHECK-NEXT: [[DOUBLE_ARG:%[0-9]+]] = apply [[DOUBLE_ARG_THUNK]]() : $@convention(thin) () -> Double
405405

406406
// default argument 2
407-
// CHECK: [[STRING_ARG_THUNK:%[0-9]+]] = function_ref @_T017default_arguments0A5_argsOfA1_ : $@convention(thin) () -> @owned String
407+
// CHECK: [[STRING_ARG_THUNK:%[0-9]+]] = function_ref @$S17default_arguments0A5_argsOfA1_ : $@convention(thin) () -> @owned String
408408
// CHECK-NEXT: [[STRING_ARG:%[0-9]+]] = apply [[STRING_ARG_THUNK]]() : $@convention(thin) () -> @owned String
409409

410-
// CHECK: [[DEF2_THUNK:%[0-9]+]] = function_ref @_T017default_arguments0A5_argsO7defarg2yACSi_SdSStcACmF : $@convention(method) (Int, Double, @owned String, @thin default_args.Type) -> @owned default_args
410+
// CHECK: [[DEF2_THUNK:%[0-9]+]] = function_ref @$S17default_arguments0A5_argsO7defarg2yACSi_SdSStcACmF : $@convention(method) (Int, Double, @owned String, @thin default_args.Type) -> @owned default_args
411411

412412
// CHECK: apply [[DEF2_THUNK]]({{%[0-9]+}}, [[DOUBLE_ARG]], [[STRING_ARG]], [[METATYPE_DEF_2]])
413413
_ = default_args.defarg2(i: 5)

test/SILGen/default_arguments_imported.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import gizmo
88

99
// CHECK-LABEL: sil hidden @$S26default_arguments_imported9testGizmo{{[_0-9a-zA-Z]*}}F
1010
func testGizmo(gizmo: Gizmo) {
11-
// CHECK: enum $Optional<@callee_guaranteed (@owned Optional<Gizmo>) -> ()>, #Optional.none!enumelt
11+
// CHECK: // function_ref Optional.none<A>(_:)
12+
// CHECK-NEXT: [[ENUM_CASE:%.*]] = function_ref @$SSq4noneyxSgABmlF : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
13+
// CHECK-NEXT: apply [[ENUM_CASE]]<(Gizmo?) -> ()>({{%.*}}, {{%.*}})
1214
// CHECK: objc_method [[SELF:%[0-9]+]] : $Gizmo, #Gizmo.enumerateSubGizmos!1.foreign
1315
gizmo.enumerateSubGizmos()
1416
} // CHECK: } // end sil function '$S26default_arguments_imported9testGizmo5gizmoySo0E0C_tF'
@@ -24,7 +26,9 @@ func testNonnullDictionary(gizmo: Gizmo) {
2426
// CHECK-LABEL: sil hidden @$S26default_arguments_imported22testNullableDictionary5gizmoySo5GizmoC_tF
2527
func testNullableDictionary(gizmo: Gizmo) {
2628
// CHECK-NOT: dictionaryLiteral
27-
// CHECK: enum $Optional<Dictionary<AnyHashable, Any>>, #Optional.none!enumelt
29+
// CHECK: // function_ref Optional.none<A>(_:)
30+
// CHECK-NEXT: [[ENUM_CASE:%.*]] = function_ref @$SSq4noneyxSgABmlF : $@convention(method) <τ_0_0> (@thin Optional<τ_0_0>.Type) -> @out Optional<τ_0_0>
31+
// CHECK-NEXT: apply [[ENUM_CASE]]<[AnyHashable : Any]>({{%.*}}, {{%.*}})
2832
// CHECK: objc_method [[SELF:%[0-9]+]] : $Gizmo, #Gizmo.doTheOtherThing!1.foreign
2933
gizmo.doTheOtherThing()
3034
} // CHECK: } // end sil function '$S26default_arguments_imported22testNullableDictionary5gizmoySo5GizmoC_tF'

0 commit comments

Comments
 (0)