@@ -257,12 +257,6 @@ static DeclTy *findNamedWitnessImpl(TypeChecker &tc, DeclContext *dc, Type type,
257
257
conformance->getWitness (requirement, &tc).getDecl ());
258
258
}
259
259
260
- static VarDecl *findNamedPropertyWitness (TypeChecker &tc, DeclContext *dc,
261
- Type type, ProtocolDecl *proto,
262
- Identifier name, Diag<> diag) {
263
- return findNamedWitnessImpl<VarDecl>(tc, dc, type, proto, name, diag);
264
- }
265
-
266
260
static bool shouldAccessStorageDirectly (Expr *base, VarDecl *member,
267
261
DeclContext *DC) {
268
262
// This only matters for stored properties.
@@ -6277,20 +6271,10 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
6277
6271
6278
6272
// If we didn't manage to resolve directly to an expression, we don't
6279
6273
// have a great diagnostic to give, so bail.
6280
- if (!resolved || !resolved->getAnchor ())
6274
+ if (!resolved || !resolved->getAnchor () ||
6275
+ !resolved->getPath ().empty ())
6281
6276
return false ;
6282
6277
6283
- if (!resolved->getPath ().empty ()) {
6284
- // We allow OptionalToBoolean fixes with an opened type to refer to the
6285
- // Boolean conformance.
6286
- if (fix.first .getKind () == FixKind::OptionalToBoolean &&
6287
- resolved->getPath ().size () == 1 &&
6288
- resolved->getPath ()[0 ].getKind () == ConstraintLocator::OpenedGeneric)
6289
- ; /* ok */
6290
- else
6291
- return false ;
6292
- }
6293
-
6294
6278
Expr *affected = resolved->getAnchor ();
6295
6279
6296
6280
switch (fix.first .getKind ()) {
@@ -6381,74 +6365,6 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
6381
6365
return true ;
6382
6366
}
6383
6367
6384
- case FixKind::OptionalToBoolean: {
6385
- // If we're implicitly trying to treat an optional type as a boolean,
6386
- // let the user know that they should be testing for a value manually
6387
- // instead.
6388
- Expr *errorExpr = expr;
6389
- StringRef prefix = " ((" ;
6390
- StringRef suffix = " ) != nil)" ;
6391
-
6392
- // In the common case of a !x, post the error against the inner
6393
- // expression as an == comparison.
6394
- if (auto PUE =
6395
- dyn_cast<PrefixUnaryExpr>(errorExpr->getSemanticsProvidingExpr ())){
6396
- bool isNot = false ;
6397
- if (auto *D = PUE->getCalledValue ())
6398
- isNot = D->getNameStr () == " !" ;
6399
- else if (auto *ODR = dyn_cast<OverloadedDeclRefExpr>(PUE->getFn ()))
6400
- isNot = ODR->getDecls ()[0 ]->getNameStr () == " !" ;
6401
-
6402
- if (isNot) {
6403
- suffix = " ) == nil)" ;
6404
- errorExpr = PUE->getArg ();
6405
-
6406
- // Check if we need the inner parentheses.
6407
- // Technically we only need them if there's something in 'expr' with
6408
- // lower precedence than '!=', but the code actually comes out nicer
6409
- // in most cases with parens on anything non-trivial.
6410
- if (errorExpr->canAppendCallParentheses ()) {
6411
- prefix = prefix.drop_back ();
6412
- suffix = suffix.drop_front ();
6413
- }
6414
- // FIXME: The outer parentheses may be superfluous too.
6415
-
6416
-
6417
- TC.diagnose (errorExpr->getLoc (),diag::optional_used_as_true_boolean,
6418
- simplifyType (errorExpr->getType ())->getRValueType ())
6419
- .fixItRemove (PUE->getLoc ())
6420
- .fixItInsert (errorExpr->getStartLoc (), prefix)
6421
- .fixItInsertAfter (errorExpr->getEndLoc (), suffix);
6422
- return true ;
6423
- }
6424
- }
6425
-
6426
- // If we can, post the fix-it to the sub-expression if it's a better
6427
- // fit.
6428
- if (auto ifExpr = dyn_cast<IfExpr>(errorExpr))
6429
- errorExpr = ifExpr->getCondExpr ();
6430
- if (auto prefixUnaryExpr = dyn_cast<PrefixUnaryExpr>(errorExpr))
6431
- errorExpr = prefixUnaryExpr->getArg ();
6432
-
6433
-
6434
- // Check if we need the inner parentheses.
6435
- // Technically we only need them if there's something in 'expr' with
6436
- // lower precedence than '!=', but the code actually comes out nicer
6437
- // in most cases with parens on anything non-trivial.
6438
- if (errorExpr->canAppendCallParentheses ()) {
6439
- prefix = prefix.drop_back ();
6440
- suffix = suffix.drop_front ();
6441
- }
6442
- // FIXME: The outer parentheses may be superfluous too.
6443
-
6444
- TC.diagnose (errorExpr->getLoc (), diag::optional_used_as_boolean,
6445
- simplifyType (errorExpr->getType ())->getRValueType ())
6446
- .fixItInsert (errorExpr->getStartLoc (), prefix)
6447
- .fixItInsertAfter (errorExpr->getEndLoc (), suffix);
6448
-
6449
- return true ;
6450
- }
6451
-
6452
6368
case FixKind::CoerceToCheckedCast: {
6453
6369
if (auto *coerceExpr = dyn_cast<CoerceExpr>(locator->getAnchor ())) {
6454
6370
Expr *subExpr = coerceExpr->getSubExpr ();
@@ -6745,25 +6661,16 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
6745
6661
// / conforms to the give \c protocol.
6746
6662
// / \param expr The expression to convert.
6747
6663
// / \param locator The locator describing where the conversion occurs.
6748
- // / \param protocol The protocol to use for conversion.
6749
- // / \param generalName The name of the protocol method to use for the
6750
- // / conversion.
6751
6664
// / \param builtinName The name of the builtin method to use for the
6752
6665
// / last step of the conversion.
6753
- // / \param brokenProtocolDiag Diagnostic to emit if the protocol
6754
- // / definition is missing.
6755
6666
// / \param brokenBuiltinDiag Diagnostic to emit if the builtin definition
6756
6667
// / is broken.
6757
6668
// /
6758
6669
// / \returns the converted expression.
6759
- static Expr *convertViaBuiltinProtocol (const Solution &solution,
6760
- Expr *expr,
6761
- ConstraintLocator *locator,
6762
- ProtocolDecl *protocol,
6763
- Identifier generalName,
6764
- Identifier builtinName,
6765
- Diag<> brokenProtocolDiag,
6766
- Diag<> brokenBuiltinDiag) {
6670
+ static Expr *convertViaMember (const Solution &solution, Expr *expr,
6671
+ ConstraintLocator *locator,
6672
+ Identifier builtinName,
6673
+ Diag<> brokenBuiltinDiag) {
6767
6674
auto &cs = solution.getConstraintSystem ();
6768
6675
6769
6676
// FIXME: Cache name.
@@ -6776,66 +6683,17 @@ static Expr *convertViaBuiltinProtocol(const Solution &solution,
6776
6683
NameLookupOptions lookupOptions = defaultMemberLookupOptions;
6777
6684
if (isa<AbstractFunctionDecl>(cs.DC ))
6778
6685
lookupOptions |= NameLookupFlags::KnownPrivate;
6779
- auto witnesses = tc.lookupMember (cs.DC , type->getRValueType (), builtinName,
6686
+ auto members = tc.lookupMember (cs.DC , type->getRValueType (), builtinName,
6780
6687
lookupOptions);
6781
- if (!witnesses) {
6782
- auto protocolType = protocol->getType ()->
6783
- getAs<MetatypeType>()->getInstanceType ();
6784
-
6785
- // Find the witness we need to use.
6786
- ValueDecl *witness = nullptr ;
6787
-
6788
- if (!protocolType->isEqual (type)) {
6789
- witness = findNamedPropertyWitness (tc, cs.DC , type -> getRValueType (),
6790
- protocol, generalName,
6791
- brokenProtocolDiag);
6792
- } else {
6793
- // If the expression is already typed to the protocol, lookup the protocol
6794
- // method directly.
6795
- witnesses = tc.lookupMember (cs.DC , type->getRValueType (), generalName,
6796
- lookupOptions);
6797
- if (!witnesses) {
6798
- tc.diagnose (protocol->getLoc (), brokenProtocolDiag);
6799
- return nullptr ;
6800
- }
6801
- witness = witnesses[0 ];
6802
- }
6803
-
6804
- // Form a reference to this member.
6805
- Expr *memberRef = new (ctx) MemberRefExpr (expr, expr->getStartLoc (),
6806
- witness,
6807
- DeclNameLoc (expr->getEndLoc ()),
6808
- /* Implicit=*/ true );
6809
- bool failed = tc.typeCheckExpressionShallow (memberRef, cs.DC );
6810
- if (failed) {
6811
- // If the member reference expression failed to type check, the Expr's
6812
- // type does not conform to the given protocol.
6813
- tc.diagnose (expr->getLoc (),
6814
- diag::type_does_not_conform,
6815
- type,
6816
- protocol->getType ());
6817
- return nullptr ;
6818
- }
6819
- expr = memberRef;
6820
-
6821
- // At this point, we must have a type with the builtin member.
6822
- type = expr->getType ();
6823
- witnesses = tc.lookupMember (cs.DC , type->getRValueType (), builtinName,
6824
- lookupOptions);
6825
- if (!witnesses) {
6826
- tc.diagnose (protocol->getLoc (), brokenProtocolDiag);
6827
- return nullptr ;
6828
- }
6829
- }
6830
-
6688
+
6831
6689
// Find the builtin method.
6832
- if (witnesses .size () != 1 ) {
6833
- tc.diagnose (protocol ->getLoc (), brokenBuiltinDiag);
6690
+ if (members .size () != 1 ) {
6691
+ tc.diagnose (expr ->getLoc (), brokenBuiltinDiag);
6834
6692
return nullptr ;
6835
6693
}
6836
- FuncDecl *builtinMethod = dyn_cast<FuncDecl>(witnesses [0 ].Decl );
6694
+ FuncDecl *builtinMethod = dyn_cast<FuncDecl>(members [0 ].Decl );
6837
6695
if (!builtinMethod) {
6838
- tc.diagnose (protocol ->getLoc (), brokenBuiltinDiag);
6696
+ tc.diagnose (expr ->getLoc (), brokenBuiltinDiag);
6839
6697
return nullptr ;
6840
6698
6841
6699
}
@@ -6864,15 +6722,9 @@ Expr *
6864
6722
Solution::convertBooleanTypeToBuiltinI1 (Expr *expr, ConstraintLocator *locator) const {
6865
6723
auto &tc = getConstraintSystem ().getTypeChecker ();
6866
6724
6867
- // FIXME: Cache names.
6868
- auto result = convertViaBuiltinProtocol (
6869
- *this , expr, locator,
6870
- tc.getProtocol (expr->getLoc (),
6871
- KnownProtocolKind::Boolean),
6872
- tc.Context .Id_boolValue ,
6873
- tc.Context .Id_getBuiltinLogicValue ,
6874
- diag::condition_broken_proto,
6875
- diag::broken_bool);
6725
+ auto result = convertViaMember (*this , expr, locator,
6726
+ tc.Context .Id_getBuiltinLogicValue ,
6727
+ diag::broken_bool);
6876
6728
if (result && !result->getType ()->isBuiltinIntegerType (1 )) {
6877
6729
tc.diagnose (expr->getLoc (), diag::broken_bool);
6878
6730
return nullptr ;
0 commit comments