@@ -107,18 +107,22 @@ 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 diagnose ? groups.getSingleOrDiagnose (loc, /* forBuiltin*/ true )
125
+ : groups.getSingle ();
122
126
};
123
127
124
128
auto &Context = DC->getASTContext ();
@@ -142,12 +146,14 @@ TypeChecker::lookupPrecedenceGroupForInfixOperator(DeclContext *DC, Expr *E) {
142
146
143
147
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
144
148
Identifier name = DRE->getDecl ()->getBaseIdentifier ();
145
- return lookupPrecedenceGroupForOperator (DC, name, DRE->getLoc ());
149
+ return lookupPrecedenceGroupForOperator (
150
+ DC, name, diagnose ? DRE->getLoc () : SourceLoc ());
146
151
}
147
152
148
153
if (auto *OO = dyn_cast<OverloadedDeclRefExpr>(E)) {
149
154
Identifier name = OO->getDecls ()[0 ]->getBaseIdentifier ();
150
- return lookupPrecedenceGroupForOperator (DC, name, OO->getLoc ());
155
+ return lookupPrecedenceGroupForOperator (
156
+ DC, name, diagnose ? OO->getLoc () : SourceLoc ());
151
157
}
152
158
153
159
if (auto arrowExpr = dyn_cast<ArrowExpr>(E)) {
@@ -159,21 +165,23 @@ TypeChecker::lookupPrecedenceGroupForInfixOperator(DeclContext *DC, Expr *E) {
159
165
// An already-folded binary operator comes up for non-primary use cases
160
166
// of this function.
161
167
if (auto binaryExpr = dyn_cast<BinaryExpr>(E)) {
162
- return lookupPrecedenceGroupForInfixOperator (DC, binaryExpr->getFn ());
168
+ return lookupPrecedenceGroupForInfixOperator (DC, binaryExpr->getFn (),
169
+ diagnose);
163
170
}
164
171
165
172
if (auto *DSCE = dyn_cast<DotSyntaxCallExpr>(E)) {
166
- return lookupPrecedenceGroupForInfixOperator (DC, DSCE->getFn ());
173
+ return lookupPrecedenceGroupForInfixOperator (DC, DSCE->getFn (), diagnose );
167
174
}
168
175
169
176
if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
170
177
Identifier name = MRE->getDecl ().getDecl ()->getBaseIdentifier ();
171
- return lookupPrecedenceGroupForOperator (DC, name, MRE->getLoc ());
178
+ return lookupPrecedenceGroupForOperator (
179
+ DC, name, diagnose ? MRE->getLoc () : SourceLoc ());
172
180
}
173
181
174
182
// If E is already an ErrorExpr, then we've diagnosed it as invalid already,
175
183
// otherwise emit an error.
176
- if (!isa<ErrorExpr>(E))
184
+ if (diagnose && !isa<ErrorExpr>(E))
177
185
Context.Diags .diagnose (E->getLoc (), diag::unknown_binop);
178
186
179
187
return nullptr ;
@@ -203,7 +211,7 @@ Expr *TypeChecker::findLHS(DeclContext *DC, Expr *E, Identifier name) {
203
211
continue ;
204
212
}
205
213
206
- auto left = lookupPrecedenceGroupForInfixOperator (DC, E);
214
+ auto left = lookupPrecedenceGroupForInfixOperator (DC, E, /* diagnose= */ true );
207
215
if (!left)
208
216
// LHS is not binary expression.
209
217
return E;
@@ -425,7 +433,8 @@ static Expr *foldSequence(DeclContext *DC,
425
433
Expr *op = S[0 ];
426
434
427
435
// If the operator's precedence is lower than the minimum, stop here.
428
- auto opPrecedence = TypeChecker::lookupPrecedenceGroupForInfixOperator (DC, op);
436
+ auto opPrecedence = TypeChecker::lookupPrecedenceGroupForInfixOperator (
437
+ DC, op, /* diagnose=*/ true );
429
438
if (!precedenceBound.shouldConsider (opPrecedence))
430
439
return {nullptr , nullptr };
431
440
return {op, opPrecedence};
@@ -457,7 +466,8 @@ static Expr *foldSequence(DeclContext *DC,
457
466
}
458
467
459
468
// Pull out the next binary operator.
460
- Op op2{ S[0 ], TypeChecker::lookupPrecedenceGroupForInfixOperator (DC, S[0 ]) };
469
+ Op op2{S[0 ], TypeChecker::lookupPrecedenceGroupForInfixOperator (
470
+ DC, S[0 ], /* diagnose=*/ true )};
461
471
462
472
// If the second operator's precedence is lower than the
463
473
// precedence bound, break out of the loop.
0 commit comments