@@ -342,320 +342,6 @@ void constraints::simplifyLocator(Expr *&anchor,
342
342
}
343
343
}
344
344
345
- // / Simplify the given locator down to a specific anchor expression,
346
- // / if possible.
347
- // /
348
- // / \returns the anchor expression if it fully describes the locator, or
349
- // / null otherwise.
350
- static Expr *simplifyLocatorToAnchor (ConstraintSystem &cs,
351
- ConstraintLocator *locator) {
352
- if (!locator || !locator->getAnchor ())
353
- return nullptr ;
354
-
355
- SourceRange range;
356
- locator = simplifyLocator (cs, locator, range);
357
- if (!locator->getAnchor () || !locator->getPath ().empty ())
358
- return nullptr ;
359
-
360
- return locator->getAnchor ();
361
- }
362
-
363
-
364
-
365
-
366
- // / \brief Determine the number of distinct overload choices in the
367
- // / provided set.
368
- static unsigned countDistinctOverloads (ArrayRef<OverloadChoice> choices) {
369
- llvm::SmallPtrSet<void *, 4 > uniqueChoices;
370
- unsigned result = 0 ;
371
- for (auto choice : choices) {
372
- if (uniqueChoices.insert (choice.getOpaqueChoiceSimple ()).second )
373
- ++result;
374
- }
375
- return result;
376
- }
377
-
378
- // / \brief Determine the name of the overload in a set of overload choices.
379
- static DeclName getOverloadChoiceName (ArrayRef<OverloadChoice> choices) {
380
- DeclName name;
381
- for (auto choice : choices) {
382
- if (!choice.isDecl ())
383
- continue ;
384
-
385
- DeclName nextName = choice.getDecl ()->getFullName ();
386
- if (!name) {
387
- name = nextName;
388
- continue ;
389
- }
390
-
391
- if (name != nextName) {
392
- // Assume all choices have the same base name and only differ in
393
- // argument labels. This may not be a great assumption, but we don't
394
- // really have a way to recover for diagnostics otherwise.
395
- return name.getBaseName ();
396
- }
397
- }
398
-
399
- return name;
400
- }
401
-
402
- // / Returns true if any diagnostics were emitted.
403
- static bool
404
- tryDiagnoseTrailingClosureAmbiguity (TypeChecker &tc,
405
- const Expr *expr,
406
- const Expr *anchor,
407
- ArrayRef<OverloadChoice> choices) {
408
- auto *callExpr = dyn_cast<CallExpr>(expr);
409
- if (!callExpr)
410
- return false ;
411
- if (!callExpr->hasTrailingClosure ())
412
- return false ;
413
- if (callExpr->getFn () != anchor)
414
- return false ;
415
-
416
- llvm::SmallMapVector<Identifier, const ValueDecl *, 8 > choicesByLabel;
417
- for (const OverloadChoice &choice : choices) {
418
- auto *callee = dyn_cast<AbstractFunctionDecl>(choice.getDecl ());
419
- if (!callee)
420
- return false ;
421
-
422
- const ParameterList *paramList = callee->getParameters ();
423
- const ParamDecl *param = paramList->getArray ().back ();
424
-
425
- // Sanity-check that the trailing closure corresponds to this parameter.
426
- if (!param->hasValidSignature () ||
427
- !param->getInterfaceType ()->is <AnyFunctionType>())
428
- return false ;
429
-
430
- Identifier trailingClosureLabel = param->getArgumentName ();
431
- auto &choiceForLabel = choicesByLabel[trailingClosureLabel];
432
-
433
- // FIXME: Cargo-culted from diagnoseAmbiguity: apparently the same decl can
434
- // appear more than once?
435
- if (choiceForLabel == callee)
436
- continue ;
437
-
438
- // If just providing the trailing closure label won't solve the ambiguity,
439
- // don't bother offering the fix-it.
440
- if (choiceForLabel != nullptr )
441
- return false ;
442
-
443
- choiceForLabel = callee;
444
- }
445
-
446
- // If we got here, then all of the choices have unique labels. Offer them in
447
- // order.
448
- for (const auto &choicePair : choicesByLabel) {
449
- auto diag = tc.diagnose (expr->getLoc (),
450
- diag::ambiguous_because_of_trailing_closure,
451
- choicePair.first .empty (),
452
- choicePair.second ->getFullName ());
453
- swift::fixItEncloseTrailingClosure (tc, diag, callExpr, choicePair.first );
454
- }
455
-
456
- return true ;
457
- }
458
-
459
- bool ConstraintSystem::diagnoseAmbiguityWithFixes (
460
- Expr *expr, ArrayRef<Solution> solutions) {
461
- if (solutions.empty ())
462
- return false ;
463
-
464
- auto getOverloadDecl = [&](SelectedOverload &overload) -> ValueDecl * {
465
- auto &choice = overload.choice ;
466
- return choice.isDecl () ? choice.getDecl () : nullptr ;
467
- };
468
-
469
- // Problems related to fixes forming ambiguous solution set
470
- // could only be diagnosed (at the moment), if all of the fixes
471
- // are attached to the same anchor, which means they fix
472
- // different overloads of the same declaration.
473
- Expr *commonAnchor = nullptr ;
474
- SmallPtrSet<ValueDecl *, 4 > distinctChoices;
475
- SmallVector<std::pair<const Solution *, const ConstraintFix *>, 4 >
476
- viableSolutions;
477
-
478
- bool diagnosable = llvm::all_of (solutions, [&](const Solution &solution) {
479
- ArrayRef<ConstraintFix *> fixes = solution.Fixes ;
480
-
481
- // Currently only support a single fix in a solution,
482
- // but ultimately should be able to deal with multiple.
483
- if (fixes.size () != 1 )
484
- return false ;
485
-
486
- const auto *fix = fixes.front ();
487
- if (commonAnchor && commonAnchor != fix->getAnchor ())
488
- return false ;
489
-
490
- commonAnchor = fix->getAnchor ();
491
-
492
- SmallVector<SelectedOverload, 2 > overloads;
493
- solution.getOverloadChoices (commonAnchor, overloads);
494
- // There is unfortunately no way, at the moment, to figure out
495
- // what declaration the fix is attached to, so we have to make
496
- // sure that there is only one declaration associated with common
497
- // anchor to be sure that the right problem is being diagnosed.
498
- if (overloads.size () != 1 )
499
- return false ;
500
-
501
- auto *decl = getOverloadDecl (overloads.front ());
502
- if (!decl)
503
- return false ;
504
-
505
- // If this declaration is distinct, let's record this solution
506
- // as viable, otherwise we'd produce the same diagnostic multiple
507
- // times, which means that actual problem is elsewhere.
508
- if (distinctChoices.insert (decl).second )
509
- viableSolutions.push_back ({&solution, fix});
510
- return true ;
511
- });
512
-
513
- if (!diagnosable || viableSolutions.size () < 2 )
514
- return false ;
515
-
516
- auto *decl = *distinctChoices.begin ();
517
- assert (solverState);
518
-
519
- bool diagnosed = true ;
520
- {
521
- DiagnosticTransaction transaction (TC.Diags );
522
-
523
- TC.diagnose (commonAnchor->getLoc (), diag::ambiguous_reference_to_decl,
524
- decl->getDescriptiveKind (), decl->getFullName ());
525
-
526
- for (const auto &viable : viableSolutions) {
527
- // Create scope so each applied solution is rolled back.
528
- ConstraintSystem::SolverScope scope (*this );
529
- applySolution (*viable.first );
530
- // All of the solutions supposed to produce a "candidate" note.
531
- diagnosed &= viable.second ->diagnose (expr, /* asNote*/ true );
532
- }
533
-
534
- // If not all of the fixes produced a note, we can't diagnose this.
535
- if (!diagnosed)
536
- transaction.abort ();
537
- }
538
-
539
- return diagnosed;
540
- }
541
-
542
- bool ConstraintSystem::diagnoseAmbiguity (Expr *expr,
543
- ArrayRef<Solution> solutions) {
544
- // Produce a diff of the solutions.
545
- SolutionDiff diff (solutions);
546
-
547
- // Find the locators which have the largest numbers of distinct overloads.
548
- Optional<unsigned > bestOverload;
549
- // Overloads are scored by lexicographical comparison of (# of distinct
550
- // overloads, depth, *reverse* of the index). N.B. - cannot be used for the
551
- // reversing: the score version of index == 0 should be > than that of 1, but
552
- // -0 == 0 < UINT_MAX == -1, whereas ~0 == UINT_MAX > UINT_MAX - 1 == ~1.
553
- auto score = [](unsigned distinctOverloads, unsigned depth, unsigned index) {
554
- return std::make_tuple (distinctOverloads, depth, ~index);
555
- };
556
- auto bestScore = score (0 , 0 , std::numeric_limits<unsigned >::max ());
557
-
558
- // Get a map of expressions to their depths and post-order traversal indices.
559
- // Heuristically, all other things being equal, we should complain about the
560
- // ambiguous expression that (1) has the most overloads, (2) is deepest, or
561
- // (3) comes earliest in the expression.
562
- auto depthMap = expr->getDepthMap ();
563
- auto indexMap = expr->getPreorderIndexMap ();
564
-
565
- for (unsigned i = 0 , n = diff.overloads .size (); i != n; ++i) {
566
- auto &overload = diff.overloads [i];
567
-
568
- // If we can't resolve the locator to an anchor expression with no path,
569
- // we can't diagnose this well.
570
- auto *anchor = simplifyLocatorToAnchor (*this , overload.locator );
571
- if (!anchor)
572
- continue ;
573
- auto it = indexMap.find (anchor);
574
- if (it == indexMap.end ())
575
- continue ;
576
- unsigned index = it->second ;
577
- it = depthMap.find (anchor);
578
- if (it == depthMap.end ())
579
- continue ;
580
- unsigned depth = it->second ;
581
-
582
- // If we don't have a name to hang on to, it'll be hard to diagnose this
583
- // overload.
584
- if (!getOverloadChoiceName (overload.choices ))
585
- continue ;
586
-
587
- unsigned distinctOverloads = countDistinctOverloads (overload.choices );
588
-
589
- // We need at least two overloads to make this interesting.
590
- if (distinctOverloads < 2 )
591
- continue ;
592
-
593
- // If we have more distinct overload choices for this locator than for
594
- // prior locators, just keep this locator.
595
- auto thisScore = score (distinctOverloads, depth, index);
596
- if (thisScore > bestScore) {
597
- bestScore = thisScore;
598
- bestOverload = i;
599
- continue ;
600
- }
601
-
602
- // We have better results. Ignore this one.
603
- }
604
-
605
- // FIXME: Should be able to pick the best locator, e.g., based on some
606
- // depth-first numbering of expressions.
607
- if (bestOverload) {
608
- auto &overload = diff.overloads [*bestOverload];
609
- auto name = getOverloadChoiceName (overload.choices );
610
- auto anchor = simplifyLocatorToAnchor (*this , overload.locator );
611
-
612
- // Emit the ambiguity diagnostic.
613
- auto &tc = getTypeChecker ();
614
- tc.diagnose (anchor->getLoc (),
615
- name.isOperator () ? diag::ambiguous_operator_ref
616
- : diag::ambiguous_decl_ref,
617
- name);
618
-
619
- if (tryDiagnoseTrailingClosureAmbiguity (tc, expr, anchor, overload.choices ))
620
- return true ;
621
-
622
- // Emit candidates. Use a SmallPtrSet to make sure only emit a particular
623
- // candidate once. FIXME: Why is one candidate getting into the overload
624
- // set multiple times? (See also tryDiagnoseTrailingClosureAmbiguity.)
625
- SmallPtrSet<Decl*, 8 > EmittedDecls;
626
- for (auto choice : overload.choices ) {
627
- switch (choice.getKind ()) {
628
- case OverloadChoiceKind::Decl:
629
- case OverloadChoiceKind::DeclViaDynamic:
630
- case OverloadChoiceKind::DeclViaBridge:
631
- case OverloadChoiceKind::DeclViaUnwrappedOptional:
632
- // FIXME: show deduced types, etc, etc.
633
- if (EmittedDecls.insert (choice.getDecl ()).second )
634
- tc.diagnose (choice.getDecl (), diag::found_candidate);
635
- break ;
636
-
637
- case OverloadChoiceKind::KeyPathApplication:
638
- case OverloadChoiceKind::DynamicMemberLookup:
639
- // Skip key path applications and dynamic member lookups, since we don't
640
- // want them to noise up unrelated subscript diagnostics.
641
- break ;
642
-
643
- case OverloadChoiceKind::BaseType:
644
- case OverloadChoiceKind::TupleIndex:
645
- // FIXME: Actually diagnose something here.
646
- break ;
647
- }
648
- }
649
-
650
- return true ;
651
- }
652
-
653
- // FIXME: If we inferred different types for literals (for example),
654
- // could diagnose ambiguity that way as well.
655
-
656
- return false ;
657
- }
658
-
659
345
// / Given an expression that has a non-lvalue type, dig into it until we find
660
346
// / the part of the expression that prevents the entire subexpression from being
661
347
// / mutable. For example, in a sequence like "x.v.v = 42" we want to complain
0 commit comments