1
Fork 0

Rollup merge of #92746 - estebank:question-mark-in-type, r=davidtwco

Parse `Ty?` as `Option<Ty>` and provide structured suggestion

Swift has specific syntax that desugars to `Option<T>` similar to our
`?` operator, which means that people might try to use it in Rust. Parse
it and gracefully recover.
This commit is contained in:
Matthias Krüger 2022-01-16 16:58:18 +01:00 committed by GitHub
commit 9323a0d1be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 125 additions and 37 deletions

View file

@ -1,5 +1,5 @@
use super::pat::Expected;
use super::ty::AllowPlus;
use super::ty::{AllowPlus, IsAsCast};
use super::{
BlockMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions, SemiColonMode, SeqSep,
TokenExpectType, TokenType,
@ -1032,6 +1032,34 @@ impl<'a> Parser<'a> {
}
}
/// Swift lets users write `Ty?` to mean `Option<Ty>`. Parse the construct and recover from it.
pub(super) fn maybe_recover_from_question_mark(
&mut self,
ty: P<Ty>,
is_as_cast: IsAsCast,
) -> P<Ty> {
if let IsAsCast::Yes = is_as_cast {
return ty;
}
if self.token == token::Question {
self.bump();
self.struct_span_err(self.prev_token.span, "invalid `?` in type")
.span_label(self.prev_token.span, "`?` is only allowed on expressions, not types")
.multipart_suggestion(
"if you meant to express that the type might not contain a value, use the `Option` wrapper type",
vec![
(ty.span.shrink_to_lo(), "Option<".to_string()),
(self.prev_token.span, ">".to_string()),
],
Applicability::MachineApplicable,
)
.emit();
self.mk_ty(ty.span.to(self.prev_token.span), TyKind::Err)
} else {
ty
}
}
pub(super) fn maybe_recover_from_bad_type_plus(
&mut self,
allow_plus: AllowPlus,