Skip to content

Commit ce271fa

Browse files
committed
[GSB] Downgrade "neither type in same-type has a generic param" error to warning.
There is nothing specifically wrong with uttering a same-type constraint in a where clause where both sides are concrete types. Downgrade this to a warning; we'll check that the concrete types match (of course), and such a well-formed constraint will simply be canonicalized away. This aids the migration of IndexDistance from an associated type to Int. (cherry picked from commit 879b180)
1 parent 0238a50 commit ce271fa

File tree

4 files changed

+24
-33
lines changed

4 files changed

+24
-33
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,10 +1686,11 @@ ERROR(requires_not_suitable_archetype,none,
16861686
"type %0 in conformance requirement does not refer to a "
16871687
"generic parameter or associated type",
16881688
(TypeLoc))
1689-
ERROR(requires_no_same_type_archetype,none,
1690-
"neither type in same-type refers to a generic parameter or "
1691-
"associated type",
1692-
())
1689+
WARNING(requires_no_same_type_archetype,none,
1690+
"neither type in same-type constraint (%0 or %1) refers to a "
1691+
"generic parameter or associated type",
1692+
(Type, Type))
1693+
16931694
ERROR(requires_generic_params_made_equal,none,
16941695
"same-type requirement makes generic parameters %0 and %1 equivalent",
16951696
(Type, Type))

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4131,19 +4131,6 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirement(
41314131
diagnoseMismatch);
41324132
}
41334133

4134-
/// Determine whether the given type has a type parameter or directly
4135-
/// references a deprecated typealias.
4136-
static bool hasTypeParameterOrIsDeprecatedTypealias(Type type){
4137-
if (type->hasTypeParameter()) return true;
4138-
4139-
if (auto typeAlias = dyn_cast<NameAliasType>(type.getPointer())) {
4140-
return typeAlias->getDecl()->getAttrs().getDeprecated(
4141-
type->getASTContext());
4142-
}
4143-
4144-
return false;
4145-
}
4146-
41474134
ConstraintResult GenericSignatureBuilder::addSameTypeRequirementDirect(
41484135
ResolvedType type1, ResolvedType type2,
41494136
FloatingRequirementSource source,
@@ -4298,21 +4285,16 @@ ConstraintResult GenericSignatureBuilder::addRequirement(
42984285
}
42994286

43004287
case RequirementReprKind::SameType: {
4301-
// Require that at least one side of the requirement contain a type
4302-
// parameter or directly reference a deprecated declaration.
4303-
if (!hasTypeParameterOrIsDeprecatedTypealias(Req->getFirstType()) &&
4304-
!hasTypeParameterOrIsDeprecatedTypealias(Req->getSecondType())) {
4305-
if (!Req->getFirstType()->hasError() &&
4306-
!Req->getSecondType()->hasError()) {
4307-
Impl->HadAnyError = true;
4308-
4309-
Diags.diagnose(Req->getEqualLoc(),
4310-
diag::requires_no_same_type_archetype)
4311-
.highlight(Req->getFirstTypeLoc().getSourceRange())
4312-
.highlight(Req->getSecondTypeLoc().getSourceRange());
4313-
}
4314-
4315-
return ConstraintResult::Concrete;
4288+
// Warn if neither side of the requirement contains a type parameter.
4289+
if (!Req->getFirstType()->hasTypeParameter() &&
4290+
!Req->getSecondType()->hasTypeParameter() &&
4291+
!Req->getFirstType()->hasError() &&
4292+
!Req->getSecondType()->hasError()) {
4293+
Diags.diagnose(Req->getEqualLoc(),
4294+
diag::requires_no_same_type_archetype,
4295+
Req->getFirstType(), Req->getSecondType())
4296+
.highlight(Req->getFirstTypeLoc().getSourceRange())
4297+
.highlight(Req->getSecondTypeLoc().getSourceRange());
43164298
}
43174299

43184300
auto firstType = subst(Req->getFirstType());

test/Generics/same_type_constraints.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,10 @@ struct StructTakingP1<T: P1> { }
371371
func resultTypeSuppress<T: P1>() -> StructTakingP1<T> {
372372
return StructTakingP1()
373373
}
374+
375+
// Check directly-concrete same-type constraints
376+
typealias NotAnInt = Double
377+
378+
extension X11 where NotAnInt == Int { }
379+
// expected-warning@-1{{neither type in same-type constraint ('NotAnInt' (aka 'Double') or 'Int') refers to a generic parameter or associated type}}
380+
// expected-error@-2{{generic signature requires types 'NotAnInt' (aka 'Double') and 'Int' to be the same}}

test/decl/typealias/protocol.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ extension P10 {
268268
typealias U = Float
269269
}
270270

271-
extension P10 where T == Int { } // expected-error{{neither type in same-type refers to a generic parameter or associated type}}
271+
extension P10 where T == Int { } // expected-warning{{neither type in same-type constraint ('P10.T' (aka 'Int') or 'Int') refers to a generic parameter or associated type}}
272272

273273
extension P10 where A == X<T> { }
274274

@@ -277,3 +277,4 @@ extension P10 where A == X<U> { } // expected-error{{use of undeclared type 'U'}
277277
extension P10 where A == X<Self.U> { }
278278

279279
extension P10 where V == Int { } // expected-warning 3{{'V' is deprecated: just use Int, silly}}
280+
// expected-warning@-1{{neither type in same-type constraint ('P10.V' (aka 'Int') or 'Int') refers to a generic parameter or associated type}}

0 commit comments

Comments
 (0)