1
Fork 0

Implement .use keyword as an alias of clone

This commit is contained in:
Santiago Pastorino 2024-10-02 16:35:37 -03:00
parent 0cf8dbc96c
commit 05c516446a
No known key found for this signature in database
GPG key ID: 8131A24E0C79EFAF
36 changed files with 247 additions and 24 deletions

View file

@ -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);

View file

@ -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(_)