Skip to content

Commit 6bbf945

Browse files
authored
Merge pull request #76141 from xedin/downgrade-specialization-errors-to-warnings
[ConstraintSystem] Downgrade some invalid specialization uses to a warning until Swift 6 language mode
2 parents c32487a + b6fd5fe commit 6bbf945

File tree

8 files changed

+84
-42
lines changed

8 files changed

+84
-42
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4606,8 +4606,8 @@ NOTE(duplicated_key_declared_here, none,
46064606
"duplicate key declared here", ())
46074607

46084608
// Generic specializations
4609-
ERROR(cannot_explicitly_specialize_generic_function,none,
4610-
"cannot explicitly specialize a generic function", ())
4609+
ERROR(cannot_explicitly_specialize_function,none,
4610+
"cannot explicitly specialize %kind0", (ValueDecl *))
46114611
ERROR(not_a_generic_type,none,
46124612
"cannot specialize non-generic type %0", (Type))
46134613
ERROR(not_a_generic_macro,none,

include/swift/Sema/CSFix.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,8 @@ enum class FixKind : uint8_t {
465465
/// Ignore an attempt to specialize a non-generic type.
466466
AllowConcreteTypeSpecialization,
467467

468-
/// Ignore an attempt to specialize a generic function.
469-
AllowGenericFunctionSpecialization,
468+
/// Ignore an attempt to specialize a (generic) function reference.
469+
AllowFunctionSpecialization,
470470

471471
/// Ignore an out-of-place \c then statement.
472472
IgnoreOutOfPlaceThenStmt,
@@ -3750,17 +3750,19 @@ class AllowConcreteTypeSpecialization final : public ConstraintFix {
37503750
}
37513751
};
37523752

3753-
class AllowGenericFunctionSpecialization final : public ConstraintFix {
3753+
class AllowFunctionSpecialization final : public ConstraintFix {
37543754
ValueDecl *Decl;
37553755

3756-
AllowGenericFunctionSpecialization(ConstraintSystem &cs, ValueDecl *decl,
3757-
ConstraintLocator *locator)
3758-
: ConstraintFix(cs, FixKind::AllowGenericFunctionSpecialization, locator),
3756+
AllowFunctionSpecialization(ConstraintSystem &cs, ValueDecl *decl,
3757+
ConstraintLocator *locator,
3758+
FixBehavior fixBehavior)
3759+
: ConstraintFix(cs, FixKind::AllowFunctionSpecialization, locator,
3760+
fixBehavior),
37593761
Decl(decl) {}
37603762

37613763
public:
37623764
std::string getName() const override {
3763-
return "allow generic function specialization";
3765+
return "allow (generic) function specialization";
37643766
}
37653767

37663768
bool diagnose(const Solution &solution, bool asNote = false) const override;
@@ -3769,11 +3771,11 @@ class AllowGenericFunctionSpecialization final : public ConstraintFix {
37693771
return diagnose(*commonFixes.front().first);
37703772
}
37713773

3772-
static AllowGenericFunctionSpecialization *
3774+
static AllowFunctionSpecialization *
37733775
create(ConstraintSystem &cs, ValueDecl *decl, ConstraintLocator *locator);
37743776

37753777
static bool classof(const ConstraintFix *fix) {
3776-
return fix->getKind() == FixKind::AllowGenericFunctionSpecialization;
3778+
return fix->getKind() == FixKind::AllowFunctionSpecialization;
37773779
}
37783780
};
37793781

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9365,8 +9365,8 @@ bool ConcreteTypeSpecialization::diagnoseAsError() {
93659365
return true;
93669366
}
93679367

9368-
bool GenericFunctionSpecialization::diagnoseAsError() {
9369-
emitDiagnostic(diag::cannot_explicitly_specialize_generic_function);
9368+
bool InvalidFunctionSpecialization::diagnoseAsError() {
9369+
emitDiagnostic(diag::cannot_explicitly_specialize_function, Decl);
93709370
emitDiagnosticAt(Decl, diag::decl_declared_here, Decl);
93719371
return true;
93729372
}

lib/Sema/CSDiagnostics.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3133,13 +3133,15 @@ class ConcreteTypeSpecialization final : public FailureDiagnostic {
31333133
bool diagnoseAsError() override;
31343134
};
31353135

3136-
class GenericFunctionSpecialization final : public FailureDiagnostic {
3136+
/// Diagnose attempts to specialize (generic) function references.
3137+
class InvalidFunctionSpecialization final : public FailureDiagnostic {
31373138
ValueDecl *Decl;
31383139

31393140
public:
3140-
GenericFunctionSpecialization(const Solution &solution, ValueDecl *decl,
3141-
ConstraintLocator *locator)
3142-
: FailureDiagnostic(solution, locator), Decl(decl) {}
3141+
InvalidFunctionSpecialization(const Solution &solution, ValueDecl *decl,
3142+
ConstraintLocator *locator,
3143+
FixBehavior fixBehavior)
3144+
: FailureDiagnostic(solution, locator, fixBehavior), Decl(decl) {}
31433145

31443146
bool diagnoseAsError() override;
31453147
};

lib/Sema/CSFix.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,16 +2618,21 @@ AllowConcreteTypeSpecialization *AllowConcreteTypeSpecialization::create(
26182618
cs, concreteTy, decl, locator, fixBehavior);
26192619
}
26202620

2621-
bool AllowGenericFunctionSpecialization::diagnose(const Solution &solution,
2622-
bool asNote) const {
2623-
GenericFunctionSpecialization failure(solution, Decl, getLocator());
2621+
bool AllowFunctionSpecialization::diagnose(const Solution &solution,
2622+
bool asNote) const {
2623+
InvalidFunctionSpecialization failure(solution, Decl, getLocator(),
2624+
fixBehavior);
26242625
return failure.diagnose(asNote);
26252626
}
26262627

2627-
AllowGenericFunctionSpecialization *AllowGenericFunctionSpecialization::create(
2628-
ConstraintSystem &cs, ValueDecl *decl, ConstraintLocator *locator) {
2628+
AllowFunctionSpecialization *
2629+
AllowFunctionSpecialization::create(ConstraintSystem &cs, ValueDecl *decl,
2630+
ConstraintLocator *locator) {
2631+
auto fixBehavior = cs.getASTContext().isSwiftVersionAtLeast(6)
2632+
? FixBehavior::Error
2633+
: FixBehavior::DowngradeToWarning;
26292634
return new (cs.getAllocator())
2630-
AllowGenericFunctionSpecialization(cs, decl, locator);
2635+
AllowFunctionSpecialization(cs, decl, locator, fixBehavior);
26312636
}
26322637

26332638
bool IgnoreOutOfPlaceThenStmt::diagnose(const Solution &solution,

lib/Sema/CSSimplify.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14069,6 +14069,13 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1406914069

1407014070
auto genericParams = getGenericParams(decl);
1407114071
if (!decl->getAsGenericContext() || !genericParams) {
14072+
if (isa<AbstractFunctionDecl>(decl)) {
14073+
return recordFix(AllowFunctionSpecialization::create(
14074+
*this, decl, getConstraintLocator(locator)))
14075+
? SolutionKind::Error
14076+
: SolutionKind::Solved;
14077+
}
14078+
1407214079
// Allow concrete macros to have specializations with just a warning.
1407314080
return recordFix(AllowConcreteTypeSpecialization::create(
1407414081
*this, type1, decl, getConstraintLocator(locator),
@@ -14111,10 +14118,7 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1411114118
// FIXME: We could support explicit function specialization.
1411214119
if (openedGenericParams.empty() ||
1411314120
(isa<AbstractFunctionDecl>(decl) && !hasParameterPack)) {
14114-
if (!shouldAttemptFixes())
14115-
return SolutionKind::Error;
14116-
14117-
return recordFix(AllowGenericFunctionSpecialization::create(
14121+
return recordFix(AllowFunctionSpecialization::create(
1411814122
*this, decl, getConstraintLocator(locator)))
1411914123
? SolutionKind::Error
1412014124
: SolutionKind::Solved;
@@ -15246,7 +15250,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1524615250
case FixKind::AllowAssociatedValueMismatch:
1524715251
case FixKind::GenericArgumentsMismatch:
1524815252
case FixKind::AllowConcreteTypeSpecialization:
15249-
case FixKind::AllowGenericFunctionSpecialization:
15253+
case FixKind::AllowFunctionSpecialization:
1525015254
case FixKind::IgnoreGenericSpecializationArityMismatch:
1525115255
case FixKind::IgnoreKeyPathSubscriptIndexMismatch:
1525215256
case FixKind::AllowMemberRefOnExistential: {

test/Parse/generic_disambiguation.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -verify-additional-prefix swift5-
2+
// RUN: %target-typecheck-verify-swift -swift-version 6 -verify-additional-prefix swift6-
23

34
struct A<B> { // expected-note{{generic type 'A' declared here}}
45
init(x:Int) {}
@@ -40,7 +41,9 @@ _ = (a < b, c > d)
4041
_ = a>(b)
4142
_ = a > (b)
4243

43-
generic<Int>(0) // expected-error{{cannot explicitly specialize a generic function}}
44+
generic<Int>(0)
45+
// expected-swift5-warning@-1{{cannot explicitly specialize global function 'generic'}}
46+
// expected-swift6-error@-2 {{cannot explicitly specialize global function 'generic'}}
4447

4548
A<B>.c()
4649
A<A<B>>.c()
Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -verify-additional-prefix swift5-
2+
// RUN: %target-typecheck-verify-swift -swift-version 6 -verify-additional-prefix swift6-
23

34
extension Int {
4-
func foo() -> Int {}
5+
func foo() -> Int {} // expected-note 2 {{'foo()' declared here}}
56
var bar: Int {
67
get {}
78
}
@@ -14,28 +15,53 @@ extension Int {
1415

1516
// https://github.com/swiftlang/swift/issues/74857
1617
func test(i: Int) {
17-
let _ = i.foo<Int>() // expected-error {{cannot specialize non-generic type '() -> Int'}}
18+
let _ = i.foo<Int>()
19+
// expected-swift5-warning@-1 {{cannot explicitly specialize instance method 'foo()'}}
20+
// expected-swift6-error@-2 {{cannot explicitly specialize instance method 'foo()'}}
1821

19-
let _ = i.gen<Int>() // expected-error {{cannot explicitly specialize a generic function}}
20-
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
22+
let _ = i.gen<Int>()
23+
// expected-swift5-warning@-1 {{cannot explicitly specialize instance method 'gen()'}}
24+
// expected-swift6-error@-2 {{cannot explicitly specialize instance method 'gen()'}}
25+
// expected-error@-3 {{generic parameter 'T' could not be inferred}}
2126

22-
let _ = 0.foo<Int>() // expected-error {{cannot specialize non-generic type '() -> Int'}}
27+
let _ = 0.foo<Int>()
28+
// expected-swift5-warning@-1 {{cannot explicitly specialize instance method 'foo()'}}
29+
// expected-swift6-error@-2 {{cannot explicitly specialize instance method 'foo()'}}
2330

24-
let _ = i.gen<Int> // expected-error {{cannot explicitly specialize a generic function}}
25-
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
26-
let _ = i.bar<Int> // expected-error {{cannot specialize non-generic type 'Int'}}
27-
let _ = 0.bar<Int> // expected-error {{cannot specialize non-generic type 'Int'}}
31+
let _ = i.gen<Int>
32+
// expected-swift5-warning@-1 {{cannot explicitly specialize instance method 'gen()'}}
33+
// expected-swift6-error@-2 {{cannot explicitly specialize instance method 'gen()'}}
34+
// expected-error@-3 {{generic parameter 'T' could not be inferred}}
35+
let _ = i.bar<Int>
36+
// expected-swift5-error@-1 {{cannot specialize non-generic type 'Int'}}
37+
// expected-swift6-error@-2 {{cannot specialize non-generic type 'Int'}}
38+
let _ = 0.bar<Int>
39+
// expected-swift5-error@-1 {{cannot specialize non-generic type 'Int'}}
40+
// expected-swift6-error@-2 {{cannot specialize non-generic type 'Int'}}
2841
}
2942

3043
extension Bool {
3144
func foo<T>() -> T {} // expected-note {{'foo()' declared here}}
3245
}
3346

34-
let _: () -> Bool = false.foo<Int> // expected-error {{cannot explicitly specialize a generic function}}
47+
let _: () -> Bool = false.foo<Int>
48+
// expected-swift5-warning@-1 {{cannot explicitly specialize instance method 'foo()'}}
49+
// expected-swift6-error@-2 {{cannot explicitly specialize instance method 'foo()'}}
3550

3651
func foo(_ x: Int) {
3752
_ = {
38-
_ = x<String> // expected-error {{cannot specialize non-generic type 'Int'}}
53+
_ = x<String>
54+
// expected-swift5-error@-1 {{cannot specialize non-generic type 'Int'}}
55+
// expected-swift6-error@-2 {{cannot specialize non-generic type 'Int'}}
3956
}
4057
}
4158

59+
do {
60+
struct Test<T> {
61+
init(_: (T) -> Void) {} // expected-note {{'init(_:)' declared here}}
62+
}
63+
64+
_ = Test.init<Int>({ (_: Int) -> Void in })
65+
// expected-swift5-warning@-1 {{cannot explicitly specialize initializer 'init(_:)'}}
66+
// expected-swift6-error@-2 {{cannot explicitly specialize initializer 'init(_:)'}}
67+
}

0 commit comments

Comments
 (0)