@@ -1768,8 +1768,14 @@ impl<'a> Parser<'a> {
1768
1768
pub ( super ) fn parse_fn_front_matter ( & mut self ) -> PResult < ' a , FnHeader > {
1769
1769
let sp_start = self . token . span ;
1770
1770
let constness = self . parse_constness ( ) ;
1771
+
1772
+ let async_start_sp = self . token . span ;
1771
1773
let asyncness = self . parse_asyncness ( ) ;
1774
+
1775
+ let unsafe_start_sp = self . token . span ;
1772
1776
let unsafety = self . parse_unsafety ( ) ;
1777
+
1778
+ let ext_start_sp = self . token . span ;
1773
1779
let ext = self . parse_extern ( ) ;
1774
1780
1775
1781
if let Async :: Yes { span, .. } = asyncness {
@@ -1784,8 +1790,35 @@ impl<'a> Parser<'a> {
1784
1790
Ok ( true ) => { }
1785
1791
Ok ( false ) => unreachable ! ( ) ,
1786
1792
Err ( mut err) => {
1793
+ // Qualifier keywords ordering check
1794
+
1795
+ // This will allow the machine fix to directly place the keyword in the correct place
1796
+ let current_qual_sp = if self . check_keyword ( kw:: Const ) {
1797
+ Some ( async_start_sp)
1798
+ } else if self . check_keyword ( kw:: Async ) {
1799
+ Some ( unsafe_start_sp)
1800
+ } else if self . check_keyword ( kw:: Unsafe ) {
1801
+ Some ( ext_start_sp)
1802
+ } else {
1803
+ None
1804
+ } ;
1805
+
1806
+ if let Some ( current_qual_sp) = current_qual_sp {
1807
+ let current_qual_sp = current_qual_sp. to ( self . prev_token . span ) ;
1808
+ if let Ok ( current_qual) = self . span_to_snippet ( current_qual_sp) {
1809
+ let invalid_qual_sp = self . token . uninterpolated_span ( ) ;
1810
+ let invalid_qual = self . span_to_snippet ( invalid_qual_sp) . unwrap ( ) ;
1811
+
1812
+ err. span_suggestion (
1813
+ current_qual_sp. to ( invalid_qual_sp) ,
1814
+ & format ! ( "`{}` must come before `{}`" , invalid_qual, current_qual) ,
1815
+ format ! ( "{} {}" , invalid_qual, current_qual) ,
1816
+ Applicability :: MachineApplicable ,
1817
+ ) . note ( "keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern`" ) ;
1818
+ }
1819
+ }
1787
1820
// Recover incorrect visibility order such as `async pub`.
1788
- if self . check_keyword ( kw:: Pub ) {
1821
+ else if self . check_keyword ( kw:: Pub ) {
1789
1822
let sp = sp_start. to ( self . prev_token . span ) ;
1790
1823
if let Ok ( snippet) = self . span_to_snippet ( sp) {
1791
1824
let vis = match self . parse_visibility ( FollowedByType :: No ) {
0 commit comments