@@ -107,73 +107,84 @@ Expr *TypeChecker::substituteInputSugarTypeForResult(ApplyExpr *E) {
107
107
static PrecedenceGroupDecl *lookupPrecedenceGroupForOperator (DeclContext *DC,
108
108
Identifier name,
109
109
SourceLoc loc) {
110
- auto *op = DC->lookupInfixOperator (name).getSingleOrDiagnose (loc);
110
+ auto result = DC->lookupInfixOperator (name);
111
+ auto *op =
112
+ loc.isValid () ? result.getSingleOrDiagnose (loc) : result.getSingle ();
111
113
return op ? op->getPrecedenceGroup () : nullptr ;
112
114
}
113
115
114
116
PrecedenceGroupDecl *
115
- TypeChecker::lookupPrecedenceGroupForInfixOperator (DeclContext *DC, Expr *E) {
117
+ TypeChecker::lookupPrecedenceGroupForInfixOperator (DeclContext *DC, Expr *E,
118
+ bool diagnose) {
116
119
// / Look up the builtin precedence group with the given name.
117
120
118
121
auto getBuiltinPrecedenceGroup = [&](DeclContext *DC, Identifier name,
119
122
SourceLoc loc) -> PrecedenceGroupDecl * {
120
123
auto groups = TypeChecker::lookupPrecedenceGroup (DC, name, loc);
121
- return groups.getSingleOrDiagnose (loc, /* forBuiltin*/ true );
124
+ return loc.isValid () ? groups.getSingleOrDiagnose (loc, /* forBuiltin*/ true )
125
+ : groups.getSingle ();
122
126
};
123
127
124
128
auto &Context = DC->getASTContext ();
125
129
if (auto ifExpr = dyn_cast<IfExpr>(E)) {
126
130
// Ternary has fixed precedence.
127
131
return getBuiltinPrecedenceGroup (DC, Context.Id_TernaryPrecedence ,
128
- ifExpr->getQuestionLoc ());
132
+ diagnose ? ifExpr->getQuestionLoc ()
133
+ : SourceLoc ());
129
134
}
130
135
131
136
if (auto assignExpr = dyn_cast<AssignExpr>(E)) {
132
137
// Assignment has fixed precedence.
133
138
return getBuiltinPrecedenceGroup (DC, Context.Id_AssignmentPrecedence ,
134
- assignExpr->getEqualLoc ());
139
+ diagnose ? assignExpr->getEqualLoc ()
140
+ : SourceLoc ());
135
141
}
136
142
137
143
if (auto castExpr = dyn_cast<ExplicitCastExpr>(E)) {
138
144
// 'as' and 'is' casts have fixed precedence.
139
145
return getBuiltinPrecedenceGroup (DC, Context.Id_CastingPrecedence ,
140
- castExpr->getAsLoc ());
146
+ diagnose ? castExpr->getAsLoc ()
147
+ : SourceLoc ());
141
148
}
142
149
143
150
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
144
151
Identifier name = DRE->getDecl ()->getBaseIdentifier ();
145
- return lookupPrecedenceGroupForOperator (DC, name, DRE->getLoc ());
152
+ return lookupPrecedenceGroupForOperator (
153
+ DC, name, diagnose ? DRE->getLoc () : SourceLoc ());
146
154
}
147
155
148
156
if (auto *OO = dyn_cast<OverloadedDeclRefExpr>(E)) {
149
157
Identifier name = OO->getDecls ()[0 ]->getBaseIdentifier ();
150
- return lookupPrecedenceGroupForOperator (DC, name, OO->getLoc ());
158
+ return lookupPrecedenceGroupForOperator (
159
+ DC, name, diagnose ? OO->getLoc () : SourceLoc ());
151
160
}
152
161
153
162
if (auto arrowExpr = dyn_cast<ArrowExpr>(E)) {
154
- return getBuiltinPrecedenceGroup (DC,
155
- Context. Id_FunctionArrowPrecedence ,
156
- arrowExpr-> getArrowLoc ());
163
+ return getBuiltinPrecedenceGroup (DC, Context. Id_FunctionArrowPrecedence ,
164
+ diagnose ? arrowExpr-> getArrowLoc ()
165
+ : SourceLoc ());
157
166
}
158
167
159
168
// An already-folded binary operator comes up for non-primary use cases
160
169
// of this function.
161
170
if (auto binaryExpr = dyn_cast<BinaryExpr>(E)) {
162
- return lookupPrecedenceGroupForInfixOperator (DC, binaryExpr->getFn ());
171
+ return lookupPrecedenceGroupForInfixOperator (DC, binaryExpr->getFn (),
172
+ diagnose);
163
173
}
164
174
165
175
if (auto *DSCE = dyn_cast<DotSyntaxCallExpr>(E)) {
166
- return lookupPrecedenceGroupForInfixOperator (DC, DSCE->getFn ());
176
+ return lookupPrecedenceGroupForInfixOperator (DC, DSCE->getFn (), diagnose );
167
177
}
168
178
169
179
if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
170
180
Identifier name = MRE->getDecl ().getDecl ()->getBaseIdentifier ();
171
- return lookupPrecedenceGroupForOperator (DC, name, MRE->getLoc ());
181
+ return lookupPrecedenceGroupForOperator (
182
+ DC, name, diagnose ? MRE->getLoc () : SourceLoc ());
172
183
}
173
184
174
185
// If E is already an ErrorExpr, then we've diagnosed it as invalid already,
175
186
// otherwise emit an error.
176
- if (!isa<ErrorExpr>(E))
187
+ if (diagnose && !isa<ErrorExpr>(E))
177
188
Context.Diags .diagnose (E->getLoc (), diag::unknown_binop);
178
189
179
190
return nullptr ;
@@ -203,7 +214,7 @@ Expr *TypeChecker::findLHS(DeclContext *DC, Expr *E, Identifier name) {
203
214
continue ;
204
215
}
205
216
206
- auto left = lookupPrecedenceGroupForInfixOperator (DC, E);
217
+ auto left = lookupPrecedenceGroupForInfixOperator (DC, E, /* diagnose= */ true );
207
218
if (!left)
208
219
// LHS is not binary expression.
209
220
return E;
@@ -425,7 +436,8 @@ static Expr *foldSequence(DeclContext *DC,
425
436
Expr *op = S[0 ];
426
437
427
438
// If the operator's precedence is lower than the minimum, stop here.
428
- auto opPrecedence = TypeChecker::lookupPrecedenceGroupForInfixOperator (DC, op);
439
+ auto opPrecedence = TypeChecker::lookupPrecedenceGroupForInfixOperator (
440
+ DC, op, /* diagnose=*/ true );
429
441
if (!precedenceBound.shouldConsider (opPrecedence))
430
442
return {nullptr , nullptr };
431
443
return {op, opPrecedence};
@@ -457,7 +469,8 @@ static Expr *foldSequence(DeclContext *DC,
457
469
}
458
470
459
471
// Pull out the next binary operator.
460
- Op op2{ S[0 ], TypeChecker::lookupPrecedenceGroupForInfixOperator (DC, S[0 ]) };
472
+ Op op2{S[0 ], TypeChecker::lookupPrecedenceGroupForInfixOperator (
473
+ DC, S[0 ], /* diagnose=*/ true )};
461
474
462
475
// If the second operator's precedence is lower than the
463
476
// precedence bound, break out of the loop.
0 commit comments