@@ -1752,10 +1752,17 @@ class FunctionArgApplyInfo {
1752
1752
// / func bar(_ v: Int) { foo(v) } // `Int` is not convertible to `String`
1753
1753
// / ```
1754
1754
class ArgumentMismatchFailure : public ContextualFailure {
1755
+ // FIXME: Currently ArgumentMismatchFailure can be used from CSDiag, in which
1756
+ // case it's possible we're not able to resolve the arg apply info. Once
1757
+ // the CSDiag logic has been removed, we should be able to store Info
1758
+ // unwrapped.
1759
+ Optional<FunctionArgApplyInfo> Info;
1760
+
1755
1761
public:
1756
1762
ArgumentMismatchFailure (Expr *root, ConstraintSystem &cs, Type argType,
1757
1763
Type paramType, ConstraintLocator *locator)
1758
- : ContextualFailure(root, cs, argType, paramType, locator) {}
1764
+ : ContextualFailure(root, cs, argType, paramType, locator),
1765
+ Info (getFunctionArgApplyInfo(getLocator())) {}
1759
1766
1760
1767
bool diagnoseAsError () override ;
1761
1768
bool diagnoseAsNote () override ;
@@ -1772,6 +1779,84 @@ class ArgumentMismatchFailure : public ContextualFailure {
1772
1779
bool diagnoseUseOfReferenceEqualityOperator () const ;
1773
1780
1774
1781
protected:
1782
+ // / \returns The position of the argument being diagnosed, starting at 1.
1783
+ unsigned getArgPosition () const { return Info->getArgPosition (); }
1784
+
1785
+ // / \returns The position of the parameter being diagnosed, starting at 1.
1786
+ unsigned getParamPosition () const { return Info->getParamPosition (); }
1787
+
1788
+ // / Returns the argument expression being diagnosed.
1789
+ // /
1790
+ // / Note this may differ from \c getAnchor(), which will return a smaller
1791
+ // / sub-expression if the failed constraint is for a sub-expression within
1792
+ // / an argument. For example, in an argument conversion from (T, U) to (U, U),
1793
+ // / the conversion from T to U may fail. In this case, \c getArgExpr() will
1794
+ // / return the (T, U) expression, whereas \c getAnchor() will return the T
1795
+ // / expression.
1796
+ Expr *getArgExpr () const { return Info->getArgExpr (); }
1797
+
1798
+ // / Returns the argument type for the conversion being diagnosed.
1799
+ // /
1800
+ // / \param withSpecifier Whether to keep the inout or @lvalue specifier of
1801
+ // / the argument, if any.
1802
+ // /
1803
+ // / Note this may differ from \c getFromType(), which will give the source
1804
+ // / type of a failed constraint for the argument conversion. For example in
1805
+ // / an argument conversion from T? to U?, the conversion from T to U may fail.
1806
+ // / In this case, \c getArgType() will return T?, whereas \c getFromType()
1807
+ // / will return T.
1808
+ Type getArgType (bool withSpecifier = false ) const {
1809
+ return Info->getArgType (withSpecifier);
1810
+ }
1811
+
1812
+ // / \returns The interface type for the function being applied.
1813
+ Type getFnInterfaceType () const { return Info->getFnInterfaceType (); }
1814
+
1815
+ // / \returns The function type being applied, including any generic
1816
+ // / substitutions.
1817
+ FunctionType *getFnType () const { return Info->getFnType (); }
1818
+
1819
+ // / \returns The callee for the argument conversion, if any.
1820
+ const ValueDecl *getCallee () const {
1821
+ return Info ? Info->getCallee () : nullptr ;
1822
+ }
1823
+
1824
+ // / \returns The full name of the callee, or a null decl name if there is no
1825
+ // / callee.
1826
+ DeclName getCalleeFullName () const {
1827
+ return getCallee () ? getCallee ()->getFullName () : DeclName ();
1828
+ }
1829
+
1830
+ // / Returns the type of the parameter involved in the mismatch, including any
1831
+ // / generic substitutions.
1832
+ // /
1833
+ // / \param lookThroughAutoclosure Whether an @autoclosure () -> T parameter
1834
+ // / should be treated as being of type T.
1835
+ // /
1836
+ // / Note this may differ from \c getToType(), see the note on \c getArgType().
1837
+ Type getParamType (bool lookThroughAutoclosure = true ) const {
1838
+ return Info->getParamType (lookThroughAutoclosure);
1839
+ }
1840
+
1841
+ // / Returns the type of the parameter involved in the mismatch.
1842
+ // /
1843
+ // / \param lookThroughAutoclosure Whether an @autoclosure () -> T parameter
1844
+ // / should be treated as being of type T.
1845
+ // /
1846
+ // / Note this may differ from \c getToType(), see the note on \c getArgType().
1847
+ Type getParamInterfaceType (bool lookThroughAutoclosure = true ) const {
1848
+ return Info->getParamInterfaceType (lookThroughAutoclosure);
1849
+ }
1850
+
1851
+ // / \returns The flags of the parameter involved in the mismatch.
1852
+ ParameterTypeFlags getParameterFlags () const {
1853
+ return Info->getParameterFlags ();
1854
+ }
1855
+
1856
+ // / \returns The flags of a parameter at a given index.
1857
+ ParameterTypeFlags getParameterFlagsAtIndex (unsigned idx) const {
1858
+ return Info->getParameterFlagsAtIndex (idx);
1859
+ }
1775
1860
1776
1861
// / Situations like this:
1777
1862
// /
@@ -1783,15 +1868,6 @@ class ArgumentMismatchFailure : public ContextualFailure {
1783
1868
bool diagnoseMisplacedMissingArgument () const ;
1784
1869
1785
1870
SourceLoc getLoc () const { return getAnchor ()->getLoc (); }
1786
-
1787
- ValueDecl *getDecl () const {
1788
- auto selectedOverload = getChoiceFor (getLocator ());
1789
- if (!selectedOverload)
1790
- return nullptr ;
1791
-
1792
- auto choice = selectedOverload->choice ;
1793
- return choice.getDeclOrNull ();
1794
- }
1795
1871
};
1796
1872
1797
1873
} // end namespace constraints
0 commit comments