Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2932,6 +2932,16 @@ return Right.is(TT_TemplateCloser) && Left.is(TT_TemplateCloser) && (Style.Standard < FormatStyle::LS_Cpp11 || Style.SpacesInAngles); } + + // Deduction guides add a space around the arrow "...) -> A". + if (Left.is(tok::r_paren) && + Right.startsSequence(tok::arrow, TT_TrailingAnnotation, + TT_TemplateOpener)) + return true; + if (Left.is(tok::arrow) && + Right.startsSequence(TT_TrailingAnnotation, TT_TemplateOpener)) + return true; + if (Right.isOneOf(tok::arrow, tok::arrowstar, tok::periodstar) || Left.isOneOf(tok::arrow, tok::period, tok::arrowstar, tok::periodstar) || (Right.is(tok::period) && Right.isNot(TT_DesignatedInitializerPeriod))) Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -4977,6 +4977,15 @@ verifyFormat("void f() { auto a = b->c(); }"); } +TEST_F(FormatTest, DeductionGuides) { + verifyFormat("template A(const T &, const T &) -> A;"); + verifyFormat("template explicit A(T &, T &&) -> A;"); + verifyFormat("template S(Ts...) -> S;"); + verifyFormat( + "template \n" + "array(T &&... t) -> array, sizeof...(T)>;"); +} + TEST_F(FormatTest, BreaksFunctionDeclarationsWithTrailingTokens) { // Avoid breaking before trailing 'const' or other trailing annotations, if // they are not function-like.