}
}
+ pub(super) fn try_macro_suggestion(&mut self) -> DiagnosticBuilder<'a> {
+ let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for !
+ let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(token::Paren)); //check for (
+
+ if is_questionmark && is_open {
+ let lo = self.token.span;
+ self.bump(); //remove try
+ self.bump(); //remove !
+ let try_span = lo.to(self.token.span); //we take the try!( span
+ self.bump(); //remove (
+ let is_empty = self.token == token::CloseDelim(token::Paren); //check if the block is empty
+ self.consume_block(token::Paren, ConsumeClosingDelim::No); //eat the block
+ let hi = self.token.span;
+ self.bump(); //remove )
+ let mut err = self.struct_span_err(lo.to(hi), "use of deprecated `try` macro");
+ err.note("in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated");
+ if !is_empty {
+ err.multipart_suggestion(
+ "you can use the `?` operator instead",
+ vec![(try_span, "".to_owned()), (hi, "?".to_owned())],
+ Applicability::MachineApplicable,
+ );
+ err.span_suggestion(lo.shrink_to_lo(), "alternatively, you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax", "r#".to_string(), Applicability::MachineApplicable);
+ } else {
+ //if the try! macro is empty, it isn't possible to suggest something using the `?` operator
+ err.span_suggestion(lo.shrink_to_lo(), "you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax", "r#".to_string(), Applicability::MachineApplicable);
+ }
+ err
+ } else {
+ self.expected_expression_found() // The user isn't trying to invoke the try! macro
+ }
+ }
+
/// Recovers a situation like `for ( $pat in $expr )`
/// and suggest writing `for $pat in $expr` instead.
///
fn parse_lit_expr(&mut self, attrs: AttrVec) -> PResult<'a, P<Expr>> {
let lo = self.token.span;
+ let is_try = self.token.is_keyword(kw::Try);
match self.parse_opt_lit() {
Some(literal) => {
let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(literal), attrs);
self.maybe_recover_from_bad_qpath(expr, true)
}
+ None if is_try => Err(self.try_macro_suggestion()),
None => Err(self.expected_expression_found()),
}
}
--- /dev/null
+error: use of deprecated `try` macro
+ --> $DIR/try-macro-suggestion.rs:3:8
+ |
+LL | Ok(try!());
+ | ^^^^^^
+ |
+ = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
+help: you can still access the deprecated `try!()` macro using the "raw identifier" syntax
+ |
+LL | Ok(r#try!());
+ | ^^
+
+error: use of deprecated `try` macro
+ --> $DIR/try-macro-suggestion.rs:4:8
+ |
+LL | Ok(try!(Ok(())))
+ | ^^^^^^^^^^^^
+ |
+ = note: in the 2018 edition `try` is a reserved keyword, and the `try!()` macro is deprecated
+help: you can use the `?` operator instead
+ |
+LL | Ok(Ok(())?)
+ | -- ^
+help: alternatively, you can still access the deprecated `try!()` macro using the "raw identifier" syntax
+ |
+LL | Ok(r#try!(Ok(())))
+ | ^^
+
+error: aborting due to 2 previous errors
+