Skip to content

Commit 7629fbd

Browse files
committed
[Sema] Quick fix for non-copyable type resolution crash
Add a guard to make sure we don't attempt to check for Copyable conformance if the type contains type variables. This matches the existing behavior where we won't check for unbound generic types. Neither behavior is correct since we won't do the proper check once the generic type is opened, but this at least makes the behavior consistent and fixes the crash. It's also a very low risk fix that can be cherry-picked. rdar://152287178
1 parent f449b7b commit 7629fbd

File tree

4 files changed

+19
-1
lines changed

4 files changed

+19
-1
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3958,8 +3958,9 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr,
39583958
}
39593959

39603960
// Validate the presence of ownership for a noncopyable parameter.
3961+
// FIXME: This won't diagnose if the type contains unbound generics.
39613962
if (inStage(TypeResolutionStage::Interface)
3962-
&& !ty->hasUnboundGenericType()) {
3963+
&& !ty->hasUnboundGenericType() && !ty->hasTypeVariable()) {
39633964
diagnoseMissingOwnership(ownership, eltTypeRepr, ty, resolution);
39643965

39653966
// @_staticExclusiveOnly types cannot be passed as 'inout' in function
@@ -5709,6 +5710,7 @@ NeverNullType TypeResolver::resolveVarargType(VarargTypeRepr *repr,
57095710
}
57105711

57115712
// do not allow move-only types as the element of a vararg
5713+
// FIXME: This does not correctly handle type variables and unbound generics.
57125714
if (inStage(TypeResolutionStage::Interface)) {
57135715
auto contextTy = GenericEnvironment::mapTypeIntoContext(
57145716
resolution.getGenericSignature().getGenericEnvironment(), element);
@@ -5895,6 +5897,7 @@ NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr,
58955897
// Track the presence of a noncopyable field for diagnostic purposes only.
58965898
// We don't need to re-diagnose if a tuple contains another tuple, though,
58975899
// since we should've diagnosed the inner tuple already.
5900+
// FIXME: This won't diagnose if the type contains unbound generics
58985901
if (!ctx.LangOpts.hasFeature(Feature::MoveOnlyTuples) &&
58995902
!options.contains(TypeResolutionFlags::SILMode) &&
59005903
inStage(TypeResolutionStage::Interface) &&

test/Sema/editor_placeholders.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,8 @@ func test_ambiguity_with_placeholders(pairs: [(rank: Int, count: Int)]) -> Bool
4040

4141
let unboundInPlaceholder1: Array<Never> = <#T##Array#> // expected-error{{editor placeholder in source file}}
4242
let unboundInPlaceholder2: Array<Never> = foo(<#T##t: Array##Array<Never>#>) // expected-error{{editor placeholder in source file}}
43+
44+
// Make sure this doesn't crash:
45+
<#T##(Result) -> Void#> // expected-error {{editor placeholder in source file}}
46+
// expected-error@-1 {{generic parameter 'Success' could not be inferred}}
47+
// expected-error@-2 {{generic parameter 'Failure' could not be inferred}}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// {"kind":"typecheck","signature":"checkRequirementsImpl(llvm::ArrayRef<swift::Requirement>, bool)","signatureAssert":"Assertion failed: (!firstType->hasTypeVariable()), function checkRequirementsImpl"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
struct a<b: ~Copyable
4+
extension a: Copyable where b: Copyable
5+
let c (a -> d
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// {"kind":"typecheck","signature":"checkRequirementsImpl(llvm::ArrayRef<swift::Requirement>, bool)","signatureAssert":"Assertion failed: (!firstType->hasTypeVariable()), function checkRequirementsImpl"}
2+
// RUN: not %target-swift-frontend -typecheck %s
3+
struct a<b: ~Copyable
4+
extension a: Copyable where b: Copyable
5+
let c = <#T##(a -> d)#>

0 commit comments

Comments
 (0)