|
18 | 18 |
|
19 | 19 | #include "CodeSynthesis.h" |
20 | 20 | #include "DerivedConformances.h" |
21 | | -#include "TypeChecker.h" |
| 21 | +#include "MiscDiagnostics.h" |
22 | 22 | #include "TypeCheckAccess.h" |
| 23 | +#include "TypeCheckAvailability.h" |
23 | 24 | #include "TypeCheckConcurrency.h" |
24 | 25 | #include "TypeCheckDecl.h" |
25 | | -#include "TypeCheckAvailability.h" |
26 | 26 | #include "TypeCheckObjC.h" |
27 | 27 | #include "TypeCheckType.h" |
28 | | -#include "MiscDiagnostics.h" |
29 | | -#include "swift/AST/AccessNotes.h" |
30 | | -#include "swift/AST/AccessScope.h" |
| 28 | +#include "TypeChecker.h" |
31 | 29 | #include "swift/AST/ASTPrinter.h" |
32 | 30 | #include "swift/AST/ASTVisitor.h" |
33 | 31 | #include "swift/AST/ASTWalker.h" |
| 32 | +#include "swift/AST/AccessNotes.h" |
| 33 | +#include "swift/AST/AccessScope.h" |
34 | 34 | #include "swift/AST/ExistentialLayout.h" |
35 | 35 | #include "swift/AST/Expr.h" |
36 | 36 | #include "swift/AST/ForeignErrorConvention.h" |
|
42 | 42 | #include "swift/AST/PropertyWrappers.h" |
43 | 43 | #include "swift/AST/ProtocolConformance.h" |
44 | 44 | #include "swift/AST/SourceFile.h" |
| 45 | +#include "swift/AST/TypeCheckRequests.h" |
| 46 | +#include "swift/AST/TypeDifferenceVisitor.h" |
45 | 47 | #include "swift/AST/TypeWalker.h" |
| 48 | +#include "swift/Basic/Defer.h" |
46 | 49 | #include "swift/Basic/Statistic.h" |
47 | 50 | #include "swift/Parse/Lexer.h" |
48 | 51 | #include "swift/Parse/Parser.h" |
49 | 52 | #include "swift/Serialization/SerializedModuleLoader.h" |
50 | 53 | #include "swift/Strings.h" |
51 | | -#include "swift/AST/NameLookupRequests.h" |
52 | | -#include "swift/AST/TypeCheckRequests.h" |
53 | | -#include "swift/Basic/Defer.h" |
54 | 54 | #include "llvm/ADT/APFloat.h" |
55 | 55 | #include "llvm/ADT/APInt.h" |
56 | 56 | #include "llvm/ADT/APSInt.h" |
@@ -967,11 +967,65 @@ static void checkInheritedDefaultValueRestrictions(ParamDecl *PD) { |
967 | 967 | } |
968 | 968 | } |
969 | 969 |
|
| 970 | +void TypeChecker::notePlaceholderReplacementTypes(Type writtenType, |
| 971 | + Type inferredType) { |
| 972 | + assert(writtenType && inferredType && |
| 973 | + "Must provide both written and inferred types"); |
| 974 | + assert(writtenType->hasPlaceholder() && "Written type has no placeholder?"); |
| 975 | + |
| 976 | + class PlaceholderNotator |
| 977 | + : public CanTypeDifferenceVisitor<PlaceholderNotator> { |
| 978 | + public: |
| 979 | + bool visitDifferentComponentTypes(CanType t1, CanType t2) { |
| 980 | + // Never replace anything the user wrote with an error type. |
| 981 | + if (t2->hasError() || t2->hasUnresolvedType()) { |
| 982 | + return false; |
| 983 | + } |
| 984 | + |
| 985 | + auto *placeholder = t1->getAs<PlaceholderType>(); |
| 986 | + if (!placeholder) { |
| 987 | + return false; |
| 988 | + } |
| 989 | + |
| 990 | + if (auto *origRepr = |
| 991 | + placeholder->getOriginator().dyn_cast<PlaceholderTypeRepr *>()) { |
| 992 | + t1->getASTContext() |
| 993 | + .Diags |
| 994 | + .diagnose(origRepr->getLoc(), |
| 995 | + diag::replace_placeholder_with_inferred_type, t2) |
| 996 | + .fixItReplace(origRepr->getSourceRange(), t2.getString()); |
| 997 | + } |
| 998 | + return false; |
| 999 | + } |
| 1000 | + |
| 1001 | + bool check(Type t1, Type t2) { |
| 1002 | + return !visit(t1->getCanonicalType(), t2->getCanonicalType()); |
| 1003 | + }; |
| 1004 | + }; |
| 1005 | + |
| 1006 | + PlaceholderNotator().check(writtenType, inferredType); |
| 1007 | +} |
| 1008 | + |
970 | 1009 | /// Check the default arguments that occur within this pattern. |
971 | 1010 | static void checkDefaultArguments(ParameterList *params) { |
972 | 1011 | // Force the default values in case they produce diagnostics. |
973 | | - for (auto *param : *params) |
974 | | - (void)param->getTypeCheckedDefaultExpr(); |
| 1012 | + for (auto *param : *params) { |
| 1013 | + auto ifacety = param->getInterfaceType(); |
| 1014 | + auto *expr = param->getTypeCheckedDefaultExpr(); |
| 1015 | + if (!ifacety->hasPlaceholder()) { |
| 1016 | + continue; |
| 1017 | + } |
| 1018 | + |
| 1019 | + // Placeholder types are banned for all parameter decls. We try to use the |
| 1020 | + // freshly-checked default expression's contextual type to suggest a |
| 1021 | + // reasonable type to insert. |
| 1022 | + param->diagnose(diag::placeholder_type_not_allowed_in_parameter) |
| 1023 | + .highlight(param->getSourceRange()); |
| 1024 | + if (expr && !expr->getType()->hasError()) { |
| 1025 | + TypeChecker::notePlaceholderReplacementTypes( |
| 1026 | + ifacety, expr->getType()->mapTypeOutOfContext()); |
| 1027 | + } |
| 1028 | + } |
975 | 1029 | } |
976 | 1030 |
|
977 | 1031 | Expr *DefaultArgumentExprRequest::evaluate(Evaluator &evaluator, |
|
0 commit comments