From 7629fbd0e04ba82f9f0e90f833053a31b1273273 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Wed, 15 Oct 2025 13:03:13 +0100 Subject: [PATCH] [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 --- lib/Sema/TypeCheckType.cpp | 5 ++++- test/Sema/editor_placeholders.swift | 5 +++++ .../compiler_crashers_2_fixed/1e0e4ce6cf612c7b.swift | 5 +++++ .../compiler_crashers_2_fixed/a23d151072660954.swift | 5 +++++ 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 validation-test/compiler_crashers_2_fixed/1e0e4ce6cf612c7b.swift create mode 100644 validation-test/compiler_crashers_2_fixed/a23d151072660954.swift diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index fcefcbf105d7f..500cba36a25ef 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -3958,8 +3958,9 @@ TypeResolver::resolveASTFunctionTypeParams(TupleTypeRepr *inputRepr, } // Validate the presence of ownership for a noncopyable parameter. + // FIXME: This won't diagnose if the type contains unbound generics. if (inStage(TypeResolutionStage::Interface) - && !ty->hasUnboundGenericType()) { + && !ty->hasUnboundGenericType() && !ty->hasTypeVariable()) { diagnoseMissingOwnership(ownership, eltTypeRepr, ty, resolution); // @_staticExclusiveOnly types cannot be passed as 'inout' in function @@ -5709,6 +5710,7 @@ NeverNullType TypeResolver::resolveVarargType(VarargTypeRepr *repr, } // do not allow move-only types as the element of a vararg + // FIXME: This does not correctly handle type variables and unbound generics. if (inStage(TypeResolutionStage::Interface)) { auto contextTy = GenericEnvironment::mapTypeIntoContext( resolution.getGenericSignature().getGenericEnvironment(), element); @@ -5895,6 +5897,7 @@ NeverNullType TypeResolver::resolveTupleType(TupleTypeRepr *repr, // Track the presence of a noncopyable field for diagnostic purposes only. // We don't need to re-diagnose if a tuple contains another tuple, though, // since we should've diagnosed the inner tuple already. + // FIXME: This won't diagnose if the type contains unbound generics if (!ctx.LangOpts.hasFeature(Feature::MoveOnlyTuples) && !options.contains(TypeResolutionFlags::SILMode) && inStage(TypeResolutionStage::Interface) && diff --git a/test/Sema/editor_placeholders.swift b/test/Sema/editor_placeholders.swift index cf14d23b74fd2..8bca60df28465 100644 --- a/test/Sema/editor_placeholders.swift +++ b/test/Sema/editor_placeholders.swift @@ -40,3 +40,8 @@ func test_ambiguity_with_placeholders(pairs: [(rank: Int, count: Int)]) -> Bool let unboundInPlaceholder1: Array = <#T##Array#> // expected-error{{editor placeholder in source file}} let unboundInPlaceholder2: Array = foo(<#T##t: Array##Array#>) // expected-error{{editor placeholder in source file}} + +// Make sure this doesn't crash: +<#T##(Result) -> Void#> // expected-error {{editor placeholder in source file}} +// expected-error@-1 {{generic parameter 'Success' could not be inferred}} +// expected-error@-2 {{generic parameter 'Failure' could not be inferred}} diff --git a/validation-test/compiler_crashers_2_fixed/1e0e4ce6cf612c7b.swift b/validation-test/compiler_crashers_2_fixed/1e0e4ce6cf612c7b.swift new file mode 100644 index 0000000000000..8344bdd5068e5 --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/1e0e4ce6cf612c7b.swift @@ -0,0 +1,5 @@ +// {"kind":"typecheck","signature":"checkRequirementsImpl(llvm::ArrayRef, bool)","signatureAssert":"Assertion failed: (!firstType->hasTypeVariable()), function checkRequirementsImpl"} +// RUN: not %target-swift-frontend -typecheck %s +struct a d diff --git a/validation-test/compiler_crashers_2_fixed/a23d151072660954.swift b/validation-test/compiler_crashers_2_fixed/a23d151072660954.swift new file mode 100644 index 0000000000000..04fad034f4e45 --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/a23d151072660954.swift @@ -0,0 +1,5 @@ +// {"kind":"typecheck","signature":"checkRequirementsImpl(llvm::ArrayRef, bool)","signatureAssert":"Assertion failed: (!firstType->hasTypeVariable()), function checkRequirementsImpl"} +// RUN: not %target-swift-frontend -typecheck %s +struct a d)#>