Skip to content

Commit 4b9eeca

Browse files
authored
Rollup merge of #71243 - Duddino:Fix2, r=estebank
Account for use of `try!()` in 2018 edition and guide users in the right direction fixes #71155
2 parents 6a140a3 + 79abac8 commit 4b9eeca

File tree

4 files changed

+73
-1
lines changed

4 files changed

+73
-1
lines changed

src/librustc_parse/parser/diagnostics.rs

+33
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,39 @@ impl<'a> Parser<'a> {
10541054
}
10551055
}
10561056

1057+
pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
1058+
let is_try = self.token.is_keyword(kw::Try);
1059+
let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for !
1060+
let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(token::Paren)); //check for (
1061+
1062+
if is_try && is_questionmark && is_open {
1063+
let lo = self.token.span;
1064+
self.bump(); //remove try
1065+
self.bump(); //remove !
1066+
let try_span = lo.to(self.token.span); //we take the try!( span
1067+
self.bump(); //remove (
1068+
let is_empty = self.token == token::CloseDelim(token::Paren); //check if the block is empty
1069+
self.consume_block(token::Paren, ConsumeClosingDelim::No); //eat the block
1070+
let hi = self.token.span;
1071+
self.bump(); //remove )
1072+
let mut err = self.struct_span_err(lo.to(hi), "use of deprecated `try` macro");
1073+
err.note("in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated");
1074+
let prefix = if is_empty { "" } else { "alternatively, " };
1075+
if !is_empty {
1076+
err.multipart_suggestion(
1077+
"you can use the `?` operator instead",
1078+
vec![(try_span, "".to_owned()), (hi, "?".to_owned())],
1079+
Applicability::MachineApplicable,
1080+
);
1081+
}
1082+
err.span_suggestion(lo.shrink_to_lo(), &format!("{}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax", prefix), "r#".to_string(), Applicability::MachineApplicable);
1083+
err.emit();
1084+
Ok(self.mk_expr_err(lo.to(hi)))
1085+
} else {
1086+
Err(self.expected_expression_found()) // The user isn't trying to invoke the try! macro
1087+
}
1088+
}
1089+
10571090
/// Recovers a situation like `for ( $pat in $expr )`
10581091
/// and suggest writing `for $pat in $expr` instead.
10591092
///

src/librustc_parse/parser/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ impl<'a> Parser<'a> {
10061006
let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs);
10071007
self.maybe_recover_from_bad_qpath(expr, true)
10081008
}
1009-
None => Err(self.expected_expression_found()),
1009+
None => self.try_macro_suggestion(),
10101010
}
10111011
}
10121012

src/test/ui/try-macro-suggestion.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// compile-flags: --edition 2018
2+
fn foo() -> Result<(), ()> {
3+
Ok(try!()); //~ ERROR use of deprecated `try` macro
4+
Ok(try!(Ok(()))) //~ ERROR use of deprecated `try` macro
5+
}
6+
7+
fn main() {
8+
let _ = foo();
9+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
error: use of deprecated `try` macro
2+
--> $DIR/try-macro-suggestion.rs:3:8
3+
|
4+
LL | Ok(try!());
5+
| ^^^^^^
6+
|
7+
= note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
8+
help: you can still access the deprecated `try!()` macro using the "raw identifier" syntax
9+
|
10+
LL | Ok(r#try!());
11+
| ^^
12+
13+
error: use of deprecated `try` macro
14+
--> $DIR/try-macro-suggestion.rs:4:8
15+
|
16+
LL | Ok(try!(Ok(())))
17+
| ^^^^^^^^^^^^
18+
|
19+
= note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
20+
help: you can use the `?` operator instead
21+
|
22+
LL | Ok(Ok(())?)
23+
| -- ^
24+
help: alternatively, you can still access the deprecated `try!()` macro using the "raw identifier" syntax
25+
|
26+
LL | Ok(r#try!(Ok(())))
27+
| ^^
28+
29+
error: aborting due to 2 previous errors
30+

0 commit comments

Comments
 (0)