Skip to content

Commit 1d21b4e

Browse files
committed
Add a bit and some diagnostics logic to help with the ongoing id-as-any project.
This is NFC because nothing sets the bit yet, it is just to aid an ongoing investigation.
1 parent 99437b4 commit 1d21b4e

File tree

3 files changed

+42
-3
lines changed

3 files changed

+42
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2097,7 +2097,11 @@ ERROR(discard_expr_outside_of_assignment,none,
20972097
())
20982098
ERROR(inout_expr_outside_of_call,none,
20992099
"'&' can only appear immediately in a call argument list", ())
2100-
2100+
ERROR(collection_literal_heterogenous,none,
2101+
"heterogenous collection literal could only be inferred to %0; add"
2102+
" explicit type annotation if this is intentional", (Type))
2103+
ERROR(collection_literal_empty,none,
2104+
"empty collection literal requires an explicit type", ())
21012105

21022106
ERROR(unresolved_member_no_inference,none,
21032107
"reference to member %0 cannot be resolved without a contextual type",

include/swift/AST/Expr.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,6 +2140,10 @@ class CollectionExpr : public Expr {
21402140

21412141
Expr *SemanticExpr = nullptr;
21422142

2143+
/// True if the type of this collection expr was inferred by the collection
2144+
/// fallback type, like [Any].
2145+
bool IsTypeDefaulted = false;
2146+
21432147
protected:
21442148
CollectionExpr(ExprKind Kind, SourceLoc LBracketLoc,
21452149
MutableArrayRef<Expr*> Elements,
@@ -2157,6 +2161,9 @@ class CollectionExpr : public Expr {
21572161
void setElement(unsigned i, Expr *E) { Elements[i] = E; }
21582162
unsigned getNumElements() const { return Elements.size(); }
21592163

2164+
bool isTypeDefaulted() const { return IsTypeDefaulted; }
2165+
void setIsTypeDefaulted(bool value = true) { IsTypeDefaulted = true; }
2166+
21602167
SourceLoc getLBracketLoc() const { return LBracketLoc; }
21612168
SourceLoc getRBracketLoc() const { return RBracketLoc; }
21622169
SourceRange getSourceRange() const {

lib/Sema/MiscDiagnostics.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ static void diagSelfAssignment(TypeChecker &TC, const Expr *E) {
9999
/// - 'self.init' and 'super.init' cannot be wrapped in a larger expression
100100
/// or statement.
101101
/// - Warn about promotions to optional in specific syntactic forms.
102+
/// - Error about collection literals that default to Any collections in
103+
/// invalid positions.
102104
///
103105
static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
104106
const DeclContext *DC,
@@ -238,10 +240,13 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
238240
while (auto Conv = dyn_cast<ImplicitConversionExpr>(Base))
239241
Base = Conv->getSubExpr();
240242

243+
if (auto collection = dyn_cast<CollectionExpr>(E))
244+
if (collection->isTypeDefaulted())
245+
checkTypeDefaultedCollectionExpr(collection);
246+
241247
// Record call arguments.
242-
if (auto Call = dyn_cast<CallExpr>(Base)) {
248+
if (auto Call = dyn_cast<CallExpr>(Base))
243249
CallArgs.insert(Call->getArg());
244-
}
245250

246251
if (auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
247252
// Verify metatype uses.
@@ -381,6 +386,29 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
381386
return E;
382387
}
383388

389+
/// We have a collection literal with a defaulted type, e.g. of [Any]. Emit
390+
/// an error if it was inferred to this type in an invalid context, which is
391+
/// one in which the parent expression is not itself a collection literal.
392+
void checkTypeDefaultedCollectionExpr(CollectionExpr *c) {
393+
if (auto *ParentExpr = Parent.getAsExpr())
394+
if (isa<CollectionExpr>(ParentExpr))
395+
return;
396+
397+
// If the parent is a non-expression, or is not itself a literal, then
398+
// produce an error with a fixit to add the type as an explicit
399+
// annotation.
400+
if (c->getNumElements() == 0)
401+
TC.diagnose(c->getLoc(), diag::collection_literal_empty)
402+
.highlight(c->getSourceRange());
403+
else {
404+
TC.diagnose(c->getLoc(), diag::collection_literal_heterogenous,
405+
c->getType())
406+
.highlight(c->getSourceRange())
407+
.fixItInsertAfter(c->getEndLoc(), " as " + c->getType()->getString());
408+
}
409+
}
410+
411+
384412
/// Scout out the specified destination of an AssignExpr to recursively
385413
/// identify DiscardAssignmentExpr in legal places. We can only allow them
386414
/// in simple pattern-like expressions, so we reject anything complex here.

0 commit comments

Comments
 (0)