Skip to content

Commit 12459cf

Browse files
committed
[Diagnostics] Print 'any' in diagnostic arguments.
1 parent 7ad9d89 commit 12459cf

File tree

75 files changed

+634
-604
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+634
-604
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ ERROR(could_not_use_instance_member_on_type,none,
142142
"%select{| instance of nested}3 type %0",
143143
(Type, DeclNameRef, Type, bool))
144144
ERROR(could_not_use_member_on_existential,none,
145-
"member %1 cannot be used on value of protocol type %0; consider using a"
145+
"member %1 cannot be used on value of type %0; consider using a"
146146
" generic constraint instead",
147147
(Type, DeclNameRef))
148148
FIXIT(replace_with_type,"%0",(Type))
@@ -1945,9 +1945,8 @@ ERROR(type_cannot_conform_to_nsobject,none,
19451945
ERROR(use_of_equal_instead_of_equality,none,
19461946
"use of '=' in a boolean context, did you mean '=='?", ())
19471947
ERROR(type_cannot_conform, none,
1948-
"%select{type %1|protocol %1 as a type}0 cannot conform to "
1949-
"%select{%3|the protocol itself}2",
1950-
(bool, Type, bool, Type))
1948+
"type %0 cannot conform to %1",
1949+
(Type, Type))
19511950
NOTE(only_concrete_types_conform_to_protocols,none,
19521951
"only concrete types such as structs, enums and classes can conform to protocols",
19531952
())
@@ -3589,7 +3588,7 @@ ERROR(construct_protocol_value,none,
35893588
"value of type %0 is a protocol; it cannot be instantiated",
35903589
(Type))
35913590
ERROR(construct_protocol_by_name,none,
3592-
"protocol type %0 cannot be instantiated",
3591+
"type %0 cannot be instantiated",
35933592
(Type))
35943593

35953594
// Operators

include/swift/AST/PrintOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,13 @@ struct PrintOptions {
548548
return result;
549549
}
550550

551+
/// The print options used for formatting diagnostic arguments.
552+
static PrintOptions forDiagnosticArguments() {
553+
PrintOptions result;
554+
result.PrintExplicitAny = true;
555+
return result;
556+
}
557+
551558
/// Retrieve the set of options suitable for diagnostics printing.
552559
static PrintOptions printForDiagnostics(AccessLevel accessFilter,
553560
bool printFullConvention) {

include/swift/AST/Types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5330,7 +5330,7 @@ class ExistentialType final : public TypeBase {
53305330
ConstraintType(constraintType) {}
53315331

53325332
public:
5333-
static Type get(Type constraint);
5333+
static Type get(Type constraint, bool forceExistential = false);
53345334

53355335
Type getConstraintType() const { return ConstraintType; }
53365336

@@ -6663,9 +6663,9 @@ inline bool TypeBase::hasSimpleTypeRepr() const {
66636663
return false;
66646664

66656665
case TypeKind::Metatype:
6666-
case TypeKind::ExistentialMetatype:
66676666
return !cast<const AnyMetatypeType>(this)->hasRepresentation();
66686667

6668+
case TypeKind::ExistentialMetatype:
66696669
case TypeKind::Existential:
66706670
return false;
66716671

lib/AST/ASTContext.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4260,15 +4260,17 @@ ProtocolType::ProtocolType(ProtocolDecl *TheDecl, Type Parent,
42604260
RecursiveTypeProperties properties)
42614261
: NominalType(TypeKind::Protocol, &Ctx, TheDecl, Parent, properties) { }
42624262

4263-
Type ExistentialType::get(Type constraint) {
4263+
Type ExistentialType::get(Type constraint, bool forceExistential) {
42644264
auto &C = constraint->getASTContext();
4265-
// FIXME: Any and AnyObject don't yet use ExistentialType.
4266-
if (constraint->isAny() || constraint->isAnyObject())
4267-
return constraint;
4265+
if (!forceExistential) {
4266+
// FIXME: Any and AnyObject don't yet use ExistentialType.
4267+
if (constraint->isAny() || constraint->isAnyObject())
4268+
return constraint;
42684269

4269-
// ExistentialMetatypeType is already an existential type.
4270-
if (constraint->is<ExistentialMetatypeType>())
4271-
return constraint;
4270+
// ExistentialMetatypeType is already an existential type.
4271+
if (constraint->is<ExistentialMetatypeType>())
4272+
return constraint;
4273+
}
42724274

42734275
assert(constraint->isConstraintType());
42744276

lib/AST/ASTPrinter.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5158,6 +5158,9 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
51585158
} else if (auto existential = dyn_cast<ExistentialType>(T.getPointer())) {
51595159
if (!Options.PrintExplicitAny)
51605160
return isSimpleUnderPrintOptions(existential->getConstraintType());
5161+
} else if (auto existential = dyn_cast<ExistentialMetatypeType>(T.getPointer())) {
5162+
if (!Options.PrintExplicitAny)
5163+
return isSimpleUnderPrintOptions(existential->getInstanceType());
51615164
}
51625165
return T->hasSimpleTypeRepr();
51635166
}
@@ -5578,10 +5581,32 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
55785581
}
55795582
}
55805583

5581-
if (T->is<ExistentialMetatypeType>() && Options.PrintExplicitAny)
5582-
Printer << "any ";
5584+
Type instanceType = T->getInstanceType();
5585+
if (Options.PrintExplicitAny) {
5586+
if (T->is<ExistentialMetatypeType>()) {
5587+
Printer << "any ";
5588+
5589+
// FIXME: We need to replace nested existential metatypes so that
5590+
// we don't print duplicate 'any'. This will be unnecessary once
5591+
// ExistentialMetatypeType is split into ExistentialType(MetatypeType).
5592+
instanceType = Type(instanceType).transform([](Type type) -> Type {
5593+
if (auto existential = type->getAs<ExistentialMetatypeType>())
5594+
return MetatypeType::get(existential->getInstanceType());
5595+
5596+
return type;
5597+
});
5598+
} else if (instanceType->isAny() || instanceType->isAnyObject()) {
5599+
// FIXME: 'any' is needed to distinguish between '(any Any).Type'
5600+
// and 'any Any.Type'. However, this combined with the above hack
5601+
// to replace nested existential metatypes with metatypes causes
5602+
// a bug in printing nested existential metatypes for Any and AnyObject,
5603+
// e.g. 'any (any Any).Type.Type'. This will be fixed by using
5604+
// ExistentialType for Any and AnyObject.
5605+
instanceType = ExistentialType::get(instanceType, /*forceExistential=*/true);
5606+
}
5607+
}
55835608

5584-
printWithParensIfNotSimple(T->getInstanceType());
5609+
printWithParensIfNotSimple(instanceType);
55855610

55865611
// We spell normal metatypes of existential types as .Protocol.
55875612
if (isa<MetatypeType>(T) &&
@@ -6281,7 +6306,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
62816306
if (printNamedOpaque())
62826307
return;
62836308

6284-
visit(T->getExistentialType());
6309+
auto constraint = T->getExistentialType();
6310+
if (auto existential = constraint->getAs<ExistentialType>())
6311+
constraint = existential->getConstraintType();
6312+
6313+
visit(constraint);
62856314
return;
62866315
}
62876316
case PrintOptions::OpaqueReturnTypePrintingMode::StableReference: {

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -670,10 +670,8 @@ static void formatDiagnosticArgument(StringRef Modifier,
670670
Type type;
671671
bool needsQualification = false;
672672

673-
// TODO: We should use PrintOptions::printForDiagnostic here, or we should
674-
// rename that method.
675-
PrintOptions printOptions{};
676-
673+
// Compute the appropriate print options for this argument.
674+
auto printOptions = PrintOptions::forDiagnosticArguments();
677675
if (Arg.getKind() == DiagnosticArgumentKind::Type) {
678676
type = Arg.getAsType()->getWithoutParens();
679677
if (type.isNull()) {

lib/Sema/CSDiagnostics.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,7 @@ bool MissingConformanceFailure::diagnoseTypeCannotConform(
568568
constraintType = existential->getConstraintType();
569569

570570
emitDiagnostic(diag::type_cannot_conform,
571-
nonConformingType->isExistentialType(),
572-
nonConformingType,
573-
constraintType->isEqual(protocolType),
574-
protocolType);
571+
nonConformingType, protocolType);
575572

576573
bool emittedSpecializedNote = false;
577574
if (auto protoType = protocolType->getAs<ProtocolType>()) {
@@ -2369,9 +2366,7 @@ bool ContextualFailure::diagnoseAsError() {
23692366
if (auto existential = constraintType->getAs<ExistentialType>())
23702367
constraintType = existential->getConstraintType();
23712368

2372-
emitDiagnostic(diag::type_cannot_conform,
2373-
/*isExistentialType=*/true, fromType,
2374-
constraintType->isEqual(toType), toType);
2369+
emitDiagnostic(diag::type_cannot_conform, fromType, toType);
23752370
emitDiagnostic(diag::only_concrete_types_conform_to_protocols);
23762371
return true;
23772372
}
@@ -3123,7 +3118,7 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
31233118
// Emit a diagnostic to inform the user that they need to conform to the
31243119
// missing protocols.
31253120
auto conformanceDiag =
3126-
emitDiagnostic(diag::assign_protocol_conformance_fix_it, unwrappedToType,
3121+
emitDiagnostic(diag::assign_protocol_conformance_fix_it, constraint,
31273122
nominal->getDescriptiveKind(), fromType);
31283123
if (nominal->getInherited().size() > 0) {
31293124
auto lastInherited = nominal->getInherited().back().getLoc();
@@ -3231,7 +3226,7 @@ bool ContextualFailure::isIntegerToStringIndexConversion() const {
32313226
Optional<Diag<Type, Type>>
32323227
ContextualFailure::getDiagnosticFor(ContextualTypePurpose context,
32333228
Type contextualType) {
3234-
auto forProtocol = contextualType->isExistentialType();
3229+
auto forProtocol = contextualType->isConstraintType();
32353230
switch (context) {
32363231
case CTP_Initialization: {
32373232
if (contextualType->isAnyObject())

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5371,9 +5371,8 @@ void swift::diagnoseConformanceFailure(Type T,
53715371
Type constraintType = T;
53725372
if (auto existential = T->getAs<ExistentialType>())
53735373
constraintType = existential->getConstraintType();
5374-
diags.diagnose(ComplainLoc, diag::type_cannot_conform, true,
5375-
T, constraintType->isEqual(Proto->getDeclaredInterfaceType()),
5376-
Proto->getDeclaredInterfaceType());
5374+
diags.diagnose(ComplainLoc, diag::type_cannot_conform,
5375+
T, Proto->getDeclaredInterfaceType());
53775376
diags.diagnose(ComplainLoc,
53785377
diag::only_concrete_types_conform_to_protocols);
53795378
return;

test/AutoDiff/Sema/differentiable_attr_type_checking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func invalidDiffWrtClass(_ x: Class) -> Class {
9393
}
9494

9595
protocol Proto {}
96-
// expected-error @+1 {{can only differentiate functions with results that conform to 'Differentiable', but 'Proto' does not conform to 'Differentiable'}}
96+
// expected-error @+1 {{can only differentiate functions with results that conform to 'Differentiable', but 'any Proto' does not conform to 'Differentiable'}}
9797
@differentiable(reverse, wrt: x)
9898
func invalidDiffWrtExistential(_ x: Proto) -> Proto {
9999
return x

test/ClangImporter/Dispatch_test.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func test2(_ queue: DispatchQueue) {
1616

1717
// Make sure the dispatch types are actually distinct types!
1818
let _ = queue as DispatchSource // expected-error {{cannot convert value of type 'DispatchQueue' to type 'DispatchSource' in coercion}}
19-
let _ = base as DispatchSource // expected-error {{'NSObjectProtocol' is not convertible to 'DispatchSource'}}
19+
let _ = base as DispatchSource // expected-error {{'any NSObjectProtocol' is not convertible to 'DispatchSource'}}
2020
// expected-note@-1 {{did you mean to use 'as!' to force downcast?}} {{16-18=as!}}
2121
}
2222

0 commit comments

Comments
 (0)