Skip to content

Commit 8dad22d

Browse files
estebankcuviper
authored andcommitted
Do not recover from Ty? in macro parsing
Follow up to #92746. Address #94510. (cherry picked from commit 004f2ed)
1 parent ac796ac commit 8dad22d

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::pat::Expected;
2-
use super::ty::{AllowPlus, IsAsCast};
2+
use super::ty::{AllowPlus, RecoverQuestionMark};
33
use super::{
44
BlockMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions, SemiColonMode, SeqSep,
55
TokenExpectType, TokenType,
@@ -1037,9 +1037,9 @@ impl<'a> Parser<'a> {
10371037
pub(super) fn maybe_recover_from_question_mark(
10381038
&mut self,
10391039
ty: P<Ty>,
1040-
is_as_cast: IsAsCast,
1040+
recover_question_mark: RecoverQuestionMark,
10411041
) -> P<Ty> {
1042-
if let IsAsCast::Yes = is_as_cast {
1042+
if let RecoverQuestionMark::No = recover_question_mark {
10431043
return ty;
10441044
}
10451045
if self.token == token::Question {

compiler/rustc_parse/src/parser/nonterminal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl<'a> Parser<'a> {
140140
}
141141

142142
NonterminalKind::Ty => {
143-
token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_ty())?)
143+
token::NtTy(self.collect_tokens_no_attrs(|this| this.parse_no_question_mark_recover())?)
144144
}
145145
// this could be handled like a token, since it is one
146146
NonterminalKind::Ident

compiler/rustc_parse/src/parser/ty.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub(super) enum RecoverQPath {
4444
No,
4545
}
4646

47-
pub(super) enum IsAsCast {
47+
pub(super) enum RecoverQuestionMark {
4848
Yes,
4949
No,
5050
}
@@ -105,7 +105,7 @@ impl<'a> Parser<'a> {
105105
RecoverQPath::Yes,
106106
RecoverReturnSign::Yes,
107107
None,
108-
IsAsCast::No,
108+
RecoverQuestionMark::Yes,
109109
)
110110
}
111111

@@ -119,7 +119,7 @@ impl<'a> Parser<'a> {
119119
RecoverQPath::Yes,
120120
RecoverReturnSign::Yes,
121121
Some(ty_params),
122-
IsAsCast::No,
122+
RecoverQuestionMark::Yes,
123123
)
124124
}
125125

@@ -133,7 +133,7 @@ impl<'a> Parser<'a> {
133133
RecoverQPath::Yes,
134134
RecoverReturnSign::Yes,
135135
None,
136-
IsAsCast::No,
136+
RecoverQuestionMark::Yes,
137137
)
138138
}
139139

@@ -150,7 +150,7 @@ impl<'a> Parser<'a> {
150150
RecoverQPath::Yes,
151151
RecoverReturnSign::Yes,
152152
None,
153-
IsAsCast::No,
153+
RecoverQuestionMark::Yes,
154154
)
155155
}
156156

@@ -163,9 +163,21 @@ impl<'a> Parser<'a> {
163163
RecoverQPath::Yes,
164164
RecoverReturnSign::Yes,
165165
None,
166-
IsAsCast::Yes,
166+
RecoverQuestionMark::No,
167167
)
168168
}
169+
170+
pub(super) fn parse_no_question_mark_recover(&mut self) -> PResult<'a, P<Ty>> {
171+
self.parse_ty_common(
172+
AllowPlus::Yes,
173+
AllowCVariadic::No,
174+
RecoverQPath::Yes,
175+
RecoverReturnSign::Yes,
176+
None,
177+
RecoverQuestionMark::No,
178+
)
179+
}
180+
169181
/// Parse a type without recovering `:` as `->` to avoid breaking code such as `where fn() : for<'a>`
170182
pub(super) fn parse_ty_for_where_clause(&mut self) -> PResult<'a, P<Ty>> {
171183
self.parse_ty_common(
@@ -174,7 +186,7 @@ impl<'a> Parser<'a> {
174186
RecoverQPath::Yes,
175187
RecoverReturnSign::OnlyFatArrow,
176188
None,
177-
IsAsCast::No,
189+
RecoverQuestionMark::Yes,
178190
)
179191
}
180192

@@ -193,7 +205,7 @@ impl<'a> Parser<'a> {
193205
recover_qpath,
194206
recover_return_sign,
195207
None,
196-
IsAsCast::No,
208+
RecoverQuestionMark::Yes,
197209
)?;
198210
FnRetTy::Ty(ty)
199211
} else if recover_return_sign.can_recover(&self.token.kind) {
@@ -214,7 +226,7 @@ impl<'a> Parser<'a> {
214226
recover_qpath,
215227
recover_return_sign,
216228
None,
217-
IsAsCast::No,
229+
RecoverQuestionMark::Yes,
218230
)?;
219231
FnRetTy::Ty(ty)
220232
} else {
@@ -229,7 +241,7 @@ impl<'a> Parser<'a> {
229241
recover_qpath: RecoverQPath,
230242
recover_return_sign: RecoverReturnSign,
231243
ty_generics: Option<&Generics>,
232-
is_as_cast: IsAsCast,
244+
recover_question_mark: RecoverQuestionMark,
233245
) -> PResult<'a, P<Ty>> {
234246
let allow_qpath_recovery = recover_qpath == RecoverQPath::Yes;
235247
maybe_recover_from_interpolated_ty_qpath!(self, allow_qpath_recovery);
@@ -305,7 +317,7 @@ impl<'a> Parser<'a> {
305317
// Try to recover from use of `+` with incorrect priority.
306318
self.maybe_report_ambiguous_plus(allow_plus, impl_dyn_multi, &ty);
307319
self.maybe_recover_from_bad_type_plus(allow_plus, &ty)?;
308-
let ty = self.maybe_recover_from_question_mark(ty, is_as_cast);
320+
let ty = self.maybe_recover_from_question_mark(ty, recover_question_mark);
309321
self.maybe_recover_from_bad_qpath(ty, allow_qpath_recovery)
310322
}
311323

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
macro_rules! fn_expr {
2+
($return_type:ty : $body:expr) => {
3+
(|| -> $return_type { $body })()
4+
};
5+
($body:expr) => {
6+
(|| $body)()
7+
};
8+
}
9+
10+
11+
fn main() {
12+
fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) };
13+
//~^ ERROR cannot find value `o` in this scope
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0425]: cannot find value `o` in this scope
2+
--> $DIR/trailing-question-in-macro-type.rs:12:15
3+
|
4+
LL | fn_expr!{ o?.when(|&i| i > 0)?.when(|&i| i%2 == 0) };
5+
| ^ not found in this scope
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)