Skip to content

Commit df2eb9d

Browse files
author
Greg Titus
committed
Feedback, round 2
1 parent 108b17c commit df2eb9d

File tree

7 files changed

+78
-38
lines changed

7 files changed

+78
-38
lines changed

include/swift/Sema/CSFix.h

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,12 @@ enum class FixKind : uint8_t {
459459
/// because its name doesn't appear in 'initializes' or 'accesses' attributes.
460460
AllowInvalidMemberReferenceInInitAccessor,
461461

462-
/// Ignore an attempt to specialize a generic function or non-generic type.
462+
/// Ignore an attempt to specialize a non-generic type.
463463
AllowConcreteTypeSpecialization,
464464

465+
/// Ignore an attempt to specialize a generic function.
466+
AllowGenericFunctionSpecialization,
467+
465468
/// Ignore an out-of-place \c then statement.
466469
IgnoreOutOfPlaceThenStmt,
467470

@@ -3705,16 +3708,41 @@ class AllowConcreteTypeSpecialization final : public ConstraintFix {
37053708
return diagnose(*commonFixes.front().first);
37063709
}
37073710

3708-
static AllowConcreteTypeSpecialization *create(ConstraintSystem &cs,
3709-
Type concreteTy,
3710-
ValueDecl *decl,
3711-
ConstraintLocator *locator);
3711+
static AllowConcreteTypeSpecialization *
3712+
create(ConstraintSystem &cs, Type concreteTy, ConstraintLocator *locator);
37123713

37133714
static bool classof(const ConstraintFix *fix) {
37143715
return fix->getKind() == FixKind::AllowConcreteTypeSpecialization;
37153716
}
37163717
};
37173718

3719+
class AllowGenericFunctionSpecialization final : public ConstraintFix {
3720+
ValueDecl *Decl;
3721+
3722+
AllowGenericFunctionSpecialization(ConstraintSystem &cs, ValueDecl *decl,
3723+
ConstraintLocator *locator)
3724+
: ConstraintFix(cs, FixKind::AllowConcreteTypeSpecialization, locator),
3725+
Decl(decl) {}
3726+
3727+
public:
3728+
std::string getName() const override {
3729+
return "allow generic function specialization";
3730+
}
3731+
3732+
bool diagnose(const Solution &solution, bool asNote = false) const override;
3733+
3734+
bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override {
3735+
return diagnose(*commonFixes.front().first);
3736+
}
3737+
3738+
static AllowGenericFunctionSpecialization *
3739+
create(ConstraintSystem &cs, ValueDecl *decl, ConstraintLocator *locator);
3740+
3741+
static bool classof(const ConstraintFix *fix) {
3742+
return fix->getKind() == FixKind::AllowGenericFunctionSpecialization;
3743+
}
3744+
};
3745+
37183746
class IgnoreOutOfPlaceThenStmt final : public ConstraintFix {
37193747
IgnoreOutOfPlaceThenStmt(ConstraintSystem &cs, ConstraintLocator *locator)
37203748
: ConstraintFix(cs, FixKind::IgnoreOutOfPlaceThenStmt, locator) {}

lib/Sema/CSDiagnostics.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9338,11 +9338,12 @@ bool InvalidMemberReferenceWithinInitAccessor::diagnoseAsError() {
93389338
}
93399339

93409340
bool ConcreteTypeSpecialization::diagnoseAsError() {
9341-
if (ConcreteType) {
9342-
emitDiagnostic(diag::not_a_generic_type, resolveType(ConcreteType));
9343-
} else {
9344-
emitDiagnostic(diag::cannot_explicitly_specialize_generic_function);
9345-
}
9341+
emitDiagnostic(diag::not_a_generic_type, resolveType(ConcreteType));
9342+
return true;
9343+
}
9344+
9345+
bool GenericFunctionSpecialization::diagnoseAsError() {
9346+
emitDiagnostic(diag::cannot_explicitly_specialize_generic_function);
93469347
return true;
93479348
}
93489349

lib/Sema/CSDiagnostics.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3121,6 +3121,17 @@ class ConcreteTypeSpecialization final : public FailureDiagnostic {
31213121
bool diagnoseAsError() override;
31223122
};
31233123

3124+
class GenericFunctionSpecialization final : public FailureDiagnostic {
3125+
ValueDecl *Decl;
3126+
3127+
public:
3128+
GenericFunctionSpecialization(const Solution &solution, ValueDecl *decl,
3129+
ConstraintLocator *locator)
3130+
: FailureDiagnostic(solution, locator), Decl(decl) {}
3131+
3132+
bool diagnoseAsError() override;
3133+
};
3134+
31243135
/// Diagnose an out-of-place ThenStmt.
31253136
class OutOfPlaceThenStmtFailure final : public FailureDiagnostic {
31263137
public:

lib/Sema/CSFix.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2599,19 +2599,23 @@ bool AllowConcreteTypeSpecialization::diagnose(const Solution &solution,
25992599

26002600
AllowConcreteTypeSpecialization *
26012601
AllowConcreteTypeSpecialization::create(ConstraintSystem &cs, Type concreteTy,
2602-
ValueDecl *decl,
26032602
ConstraintLocator *locator) {
2604-
// Check the decl and null the type to signal that the actual problem is trying to specialize a generic function
2605-
if (isa<AbstractFunctionDecl>(decl)) {
2606-
auto genericContext = decl->getAsGenericContext();
2607-
if (genericContext && genericContext->getGenericParams()) {
2608-
concreteTy = nullptr;
2609-
}
2610-
}
26112603
return new (cs.getAllocator())
26122604
AllowConcreteTypeSpecialization(cs, concreteTy, locator);
26132605
}
26142606

2607+
bool AllowGenericFunctionSpecialization::diagnose(const Solution &solution,
2608+
bool asNote) const {
2609+
GenericFunctionSpecialization failure(solution, Decl, getLocator());
2610+
return failure.diagnose(asNote);
2611+
}
2612+
2613+
AllowGenericFunctionSpecialization *AllowGenericFunctionSpecialization::create(
2614+
ConstraintSystem &cs, ValueDecl *decl, ConstraintLocator *locator) {
2615+
return new (cs.getAllocator())
2616+
AllowGenericFunctionSpecialization(cs, decl, locator);
2617+
}
2618+
26152619
bool IgnoreOutOfPlaceThenStmt::diagnose(const Solution &solution,
26162620
bool asNote) const {
26172621
OutOfPlaceThenStmtFailure failure(solution, getLocator());

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,12 +1903,11 @@ namespace {
19031903
/// introduce them as an explicit generic arguments constraint.
19041904
///
19051905
/// \returns true if resolving any of the specialization types failed.
1906-
bool addSpecializationConstraint(
1907-
ConstraintLocator *locator, Type boundType,
1908-
ArrayRef<TypeRepr *> specializationArgs) {
1906+
void addSpecializationConstraint(ConstraintLocator *locator, Type boundType,
1907+
SourceLoc lAngleLoc,
1908+
ArrayRef<TypeRepr *> specializationArgs) {
19091909
// Resolve each type.
19101910
SmallVector<Type, 2> specializationArgTypes;
1911-
bool hasError = false;
19121911
auto options =
19131912
TypeResolutionOptions(TypeResolverContext::InExpression);
19141913
for (auto specializationArg : specializationArgs) {
@@ -1927,28 +1926,23 @@ namespace {
19271926
auto &ctxt = CS.getASTContext();
19281927
auto *repr = new (ctxt) PlaceholderTypeRepr(specializationArg->getLoc());
19291928
result = PlaceholderType::get(ctxt, repr);
1930-
hasError = true;
1929+
auto &diags = CS.getASTContext().Diags;
1930+
diags.diagnose(lAngleLoc, diag::while_parsing_as_left_angle_bracket);
19311931
}
19321932
specializationArgTypes.push_back(result);
19331933
}
19341934

19351935
CS.addConstraint(
19361936
ConstraintKind::ExplicitGenericArguments, boundType,
1937-
PackType::get(CS.getASTContext(), specializationArgTypes),
1938-
locator);
1939-
return hasError;
1937+
PackType::get(CS.getASTContext(), specializationArgTypes), locator);
19401938
}
19411939

19421940
Type visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) {
19431941
auto baseTy = CS.getType(expr->getSubExpr());
19441942
auto *overloadLocator = CS.getConstraintLocator(expr->getSubExpr());
1945-
if (addSpecializationConstraint(overloadLocator, baseTy->getMetatypeInstanceType(),
1946-
expr->getUnresolvedParams())) {
1947-
// Diagnosis of failed type lookup - add a bit of context
1948-
auto &de = CS.getASTContext().Diags;
1949-
de.diagnose(expr->getLAngleLoc(),
1950-
diag::while_parsing_as_left_angle_bracket);
1951-
}
1943+
addSpecializationConstraint(
1944+
overloadLocator, baseTy->getMetatypeInstanceType(),
1945+
expr->getLAngleLoc(), expr->getUnresolvedParams());
19521946
return baseTy;
19531947
}
19541948

@@ -4062,6 +4056,7 @@ namespace {
40624056
// Add explicit generic arguments, if there were any.
40634057
if (expr->getGenericArgsRange().isValid()) {
40644058
addSpecializationConstraint(CS.getConstraintLocator(expr), macroRefType,
4059+
expr->getGenericArgsRange().Start,
40654060
expr->getGenericArgs());
40664061
}
40674062

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14023,7 +14023,7 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1402314023
auto genericParams = getGenericParams(decl);
1402414024
if (!decl->getAsGenericContext() || !genericParams) {
1402514025
return recordFix(AllowConcreteTypeSpecialization::create(
14026-
*this, type1, decl, getConstraintLocator(locator)))
14026+
*this, type1, getConstraintLocator(locator)))
1402714027
? SolutionKind::Error
1402814028
: SolutionKind::Solved;
1402914029
}
@@ -14064,8 +14064,8 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint(
1406414064
if (!shouldAttemptFixes())
1406514065
return SolutionKind::Error;
1406614066

14067-
return recordFix(AllowConcreteTypeSpecialization::create(
14068-
*this, type1, decl, getConstraintLocator(locator)))
14067+
return recordFix(AllowGenericFunctionSpecialization::create(
14068+
*this, decl, getConstraintLocator(locator)))
1406914069
? SolutionKind::Error
1407014070
: SolutionKind::Solved;
1407114071
}
@@ -15196,6 +15196,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
1519615196
case FixKind::AllowAssociatedValueMismatch:
1519715197
case FixKind::GenericArgumentsMismatch:
1519815198
case FixKind::AllowConcreteTypeSpecialization:
15199+
case FixKind::AllowGenericFunctionSpecialization:
1519915200
case FixKind::IgnoreGenericSpecializationArityMismatch:
1520015201
case FixKind::IgnoreKeyPathSubscriptIndexMismatch:
1520115202
case FixKind::AllowMemberRefOnExistential: {

test/Parse/generic_disambiguation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ _ = a < b
2727
_ = (a < b, c > d)
2828
// Parses as generic because of lparen after '>'
2929
(a < b, c > (d)) // expected-error{{cannot find type 'b' in scope}}
30-
// expected-note@-1 {{while parsing this '<' as a type parameter bracket}}
30+
// expected-note@-1 2 {{while parsing this '<' as a type parameter bracket}}
3131
// expected-error@-2 {{cannot specialize non-generic type 'Int'}}
3232
// expected-error@-3 {{cannot call value of non-function type 'Int'}}
3333
// expected-error@-4 {{cannot find type 'c' in scope}}
3434
// Parses as generic because of lparen after '>'
3535
(a<b, c>(d)) // expected-error{{cannot find type 'b' in scope}}
36-
// expected-note@-1 {{while parsing this '<' as a type parameter bracket}}
36+
// expected-note@-1 2 {{while parsing this '<' as a type parameter bracket}}
3737
// expected-error@-2 {{cannot specialize non-generic type 'Int'}}
3838
// expected-error@-3 {{cannot call value of non-function type 'Int'}}
3939
// expected-error@-4 {{cannot find type 'c' in scope}}

0 commit comments

Comments
 (0)