@@ -44,6 +44,11 @@ pub(super) enum RecoverQPath {
4444 No ,
4545}
4646
47+ pub ( super ) enum IsAsCast {
48+ Yes ,
49+ No ,
50+ }
51+
4752/// Signals whether parsing a type should recover `->`.
4853///
4954/// More specifically, when parsing a function like:
@@ -100,6 +105,7 @@ impl<'a> Parser<'a> {
100105 RecoverQPath :: Yes ,
101106 RecoverReturnSign :: Yes ,
102107 None ,
108+ IsAsCast :: No ,
103109 )
104110 }
105111
@@ -113,6 +119,7 @@ impl<'a> Parser<'a> {
113119 RecoverQPath :: Yes ,
114120 RecoverReturnSign :: Yes ,
115121 Some ( ty_params) ,
122+ IsAsCast :: No ,
116123 )
117124 }
118125
@@ -126,6 +133,7 @@ impl<'a> Parser<'a> {
126133 RecoverQPath :: Yes ,
127134 RecoverReturnSign :: Yes ,
128135 None ,
136+ IsAsCast :: No ,
129137 )
130138 }
131139
@@ -142,9 +150,22 @@ impl<'a> Parser<'a> {
142150 RecoverQPath :: Yes ,
143151 RecoverReturnSign :: Yes ,
144152 None ,
153+ IsAsCast :: No ,
145154 )
146155 }
147156
157+ /// Parses a type following an `as` cast. Similar to `parse_ty_no_plus`, but signaling origin
158+ /// for better diagnostics involving `?`.
159+ pub ( super ) fn parse_as_cast_ty ( & mut self ) -> PResult < ' a , P < Ty > > {
160+ self . parse_ty_common (
161+ AllowPlus :: No ,
162+ AllowCVariadic :: No ,
163+ RecoverQPath :: Yes ,
164+ RecoverReturnSign :: Yes ,
165+ None ,
166+ IsAsCast :: Yes ,
167+ )
168+ }
148169 /// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
149170 pub ( super ) fn parse_ty_for_where_clause ( & mut self ) -> PResult < ' a , P < Ty > > {
150171 self . parse_ty_common (
@@ -153,6 +174,7 @@ impl<'a> Parser<'a> {
153174 RecoverQPath :: Yes ,
154175 RecoverReturnSign :: OnlyFatArrow ,
155176 None ,
177+ IsAsCast :: No ,
156178 )
157179 }
158180
@@ -171,6 +193,7 @@ impl<'a> Parser<'a> {
171193 recover_qpath,
172194 recover_return_sign,
173195 None ,
196+ IsAsCast :: No ,
174197 ) ?;
175198 FnRetTy :: Ty ( ty)
176199 } else if recover_return_sign. can_recover ( & self . token . kind ) {
@@ -191,6 +214,7 @@ impl<'a> Parser<'a> {
191214 recover_qpath,
192215 recover_return_sign,
193216 None ,
217+ IsAsCast :: No ,
194218 ) ?;
195219 FnRetTy :: Ty ( ty)
196220 } else {
@@ -205,6 +229,7 @@ impl<'a> Parser<'a> {
205229 recover_qpath : RecoverQPath ,
206230 recover_return_sign : RecoverReturnSign ,
207231 ty_generics : Option < & Generics > ,
232+ is_as_cast : IsAsCast ,
208233 ) -> PResult < ' a , P < Ty > > {
209234 let allow_qpath_recovery = recover_qpath == RecoverQPath :: Yes ;
210235 maybe_recover_from_interpolated_ty_qpath ! ( self , allow_qpath_recovery) ;
@@ -280,6 +305,7 @@ impl<'a> Parser<'a> {
280305 // Try to recover from use of `+` with incorrect priority.
281306 self . maybe_report_ambiguous_plus ( allow_plus, impl_dyn_multi, & ty) ;
282307 self . maybe_recover_from_bad_type_plus ( allow_plus, & ty) ?;
308+ let ty = self . maybe_recover_from_question_mark ( ty, is_as_cast) ;
283309 self . maybe_recover_from_bad_qpath ( ty, allow_qpath_recovery)
284310 }
285311
0 commit comments