Implement .use keyword as an alias of clone
This commit is contained in:
parent
0cf8dbc96c
commit
05c516446a
36 changed files with 247 additions and 24 deletions
|
@ -38,8 +38,8 @@ use crate::errors::{
|
|||
DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
|
||||
GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
|
||||
HelpIdentifierStartsWithNumber, HelpUseLatestEdition, InInTypo, IncorrectAwait,
|
||||
IncorrectSemicolon, IncorrectUseOfAwait, PatternMethodParamWithoutBody, QuestionMarkInType,
|
||||
QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
|
||||
IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse, PatternMethodParamWithoutBody,
|
||||
QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
|
||||
StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg,
|
||||
SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator,
|
||||
UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
|
||||
|
@ -1991,7 +1991,7 @@ impl<'a> Parser<'a> {
|
|||
self.parse_expr()
|
||||
}
|
||||
.map_err(|mut err| {
|
||||
err.span_label(await_sp, "while parsing this incorrect await expression");
|
||||
err.span_label(await_sp, format!("while parsing this incorrect await expression"));
|
||||
err
|
||||
})?;
|
||||
Ok((expr.span, expr, is_question))
|
||||
|
@ -2030,6 +2030,21 @@ impl<'a> Parser<'a> {
|
|||
self.dcx().emit_err(IncorrectUseOfAwait { span });
|
||||
}
|
||||
}
|
||||
///
|
||||
/// If encountering `x.use()`, consumes and emits an error.
|
||||
pub(super) fn recover_from_use(&mut self) {
|
||||
if self.token == token::OpenDelim(Delimiter::Parenthesis)
|
||||
&& self.look_ahead(1, |t| t == &token::CloseDelim(Delimiter::Parenthesis))
|
||||
{
|
||||
// var.use()
|
||||
let lo = self.token.span;
|
||||
self.bump(); // (
|
||||
let span = lo.to(self.token.span);
|
||||
self.bump(); // )
|
||||
|
||||
self.dcx().emit_err(IncorrectUseOfUse { span });
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
|
||||
let is_try = self.token.is_keyword(kw::Try);
|
||||
|
|
|
@ -778,6 +778,7 @@ impl<'a> Parser<'a> {
|
|||
ExprKind::MethodCall(_) => "a method call",
|
||||
ExprKind::Call(_, _) => "a function call",
|
||||
ExprKind::Await(_, _) => "`.await`",
|
||||
ExprKind::Use(_, _) => "`.use`",
|
||||
ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
|
||||
ExprKind::Err(_) => return Ok(with_postfix),
|
||||
_ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
|
||||
|
@ -1296,6 +1297,12 @@ impl<'a> Parser<'a> {
|
|||
return Ok(self.mk_await_expr(self_arg, lo));
|
||||
}
|
||||
|
||||
if self.eat_keyword(exp!(Use)) {
|
||||
let use_span = self.prev_token.span;
|
||||
self.psess.gated_spans.gate(sym::ergonomic_clones, use_span);
|
||||
return Ok(self.mk_use_expr(self_arg, lo));
|
||||
}
|
||||
|
||||
// Post-fix match
|
||||
if self.eat_keyword(exp!(Match)) {
|
||||
let match_span = self.prev_token.span;
|
||||
|
@ -3818,6 +3825,13 @@ impl<'a> Parser<'a> {
|
|||
await_expr
|
||||
}
|
||||
|
||||
fn mk_use_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> {
|
||||
let span = lo.to(self.prev_token.span);
|
||||
let use_expr = self.mk_expr(span, ExprKind::Use(self_arg, self.prev_token.span));
|
||||
self.recover_from_use();
|
||||
use_expr
|
||||
}
|
||||
|
||||
pub(crate) fn mk_expr_with_attrs(&self, span: Span, kind: ExprKind, attrs: AttrVec) -> P<Expr> {
|
||||
P(Expr { kind, span, attrs, id: DUMMY_NODE_ID, tokens: None })
|
||||
}
|
||||
|
@ -3966,6 +3980,7 @@ impl MutVisitor for CondChecker<'_> {
|
|||
}
|
||||
ExprKind::Unary(_, _)
|
||||
| ExprKind::Await(_, _)
|
||||
| ExprKind::Use(_, _)
|
||||
| ExprKind::AssignOp(_, _, _)
|
||||
| ExprKind::Range(_, _, _)
|
||||
| ExprKind::Try(_)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue