mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Merge #4254
4254: Put ? back in place r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
3c96de5380
9 changed files with 63 additions and 30 deletions
|
@ -203,6 +203,10 @@ impl ExprCollector<'_> {
|
||||||
|
|
||||||
self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
|
self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
|
||||||
}
|
}
|
||||||
|
ast::Expr::TryBlockExpr(e) => {
|
||||||
|
let body = self.collect_block_opt(e.body());
|
||||||
|
self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
|
||||||
|
}
|
||||||
ast::Expr::BlockExpr(e) => self.collect_block(e),
|
ast::Expr::BlockExpr(e) => self.collect_block(e),
|
||||||
ast::Expr::LoopExpr(e) => {
|
ast::Expr::LoopExpr(e) => {
|
||||||
let body = self.collect_block_opt(e.loop_body());
|
let body = self.collect_block_opt(e.loop_body());
|
||||||
|
|
|
@ -101,6 +101,9 @@ pub enum Expr {
|
||||||
Try {
|
Try {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
},
|
},
|
||||||
|
TryBlock {
|
||||||
|
body: ExprId,
|
||||||
|
},
|
||||||
Cast {
|
Cast {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
type_ref: TypeRef,
|
type_ref: TypeRef,
|
||||||
|
@ -236,6 +239,7 @@ impl Expr {
|
||||||
f(*expr);
|
f(*expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Expr::TryBlock { body } => f(*body),
|
||||||
Expr::Loop { body } => f(*body),
|
Expr::Loop { body } => f(*body),
|
||||||
Expr::While { condition, body } => {
|
Expr::While { condition, body } => {
|
||||||
f(*condition);
|
f(*condition);
|
||||||
|
|
|
@ -73,6 +73,11 @@ impl<'a> InferenceContext<'a> {
|
||||||
self.coerce_merge_branch(&then_ty, &else_ty)
|
self.coerce_merge_branch(&then_ty, &else_ty)
|
||||||
}
|
}
|
||||||
Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
|
Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
|
||||||
|
Expr::TryBlock { body } => {
|
||||||
|
let _inner = self.infer_expr(*body, expected);
|
||||||
|
// FIXME should be std::result::Result<{inner}, _>
|
||||||
|
Ty::Unknown
|
||||||
|
}
|
||||||
Expr::Loop { body } => {
|
Expr::Loop { body } => {
|
||||||
self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
|
self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
|
||||||
// FIXME handle break with value
|
// FIXME handle break with value
|
||||||
|
|
|
@ -84,7 +84,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
|
||||||
T![box] => box_expr(p, None),
|
T![box] => box_expr(p, None),
|
||||||
T![for] => for_expr(p, None),
|
T![for] => for_expr(p, None),
|
||||||
T![while] => while_expr(p, None),
|
T![while] => while_expr(p, None),
|
||||||
T![try] => try_expr(p, None),
|
T![try] => try_block_expr(p, None),
|
||||||
LIFETIME if la == T![:] => {
|
LIFETIME if la == T![:] => {
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
label(p);
|
label(p);
|
||||||
|
@ -134,7 +134,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let blocklike = match done.kind() {
|
let blocklike = match done.kind() {
|
||||||
IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_EXPR => {
|
IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => {
|
||||||
BlockLike::Block
|
BlockLike::Block
|
||||||
}
|
}
|
||||||
_ => BlockLike::NotBlock,
|
_ => BlockLike::NotBlock,
|
||||||
|
@ -532,7 +532,7 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
|
||||||
// fn foo() {
|
// fn foo() {
|
||||||
// let _ = try {};
|
// let _ = try {};
|
||||||
// }
|
// }
|
||||||
fn try_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||||
assert!(p.at(T![try]));
|
assert!(p.at(T![try]));
|
||||||
let m = m.unwrap_or_else(|| p.start());
|
let m = m.unwrap_or_else(|| p.start());
|
||||||
// Special-case `try!` as macro.
|
// Special-case `try!` as macro.
|
||||||
|
|
|
@ -191,6 +191,7 @@ pub enum SyntaxKind {
|
||||||
RECORD_LIT,
|
RECORD_LIT,
|
||||||
RECORD_FIELD_LIST,
|
RECORD_FIELD_LIST,
|
||||||
RECORD_FIELD,
|
RECORD_FIELD,
|
||||||
|
TRY_BLOCK_EXPR,
|
||||||
BOX_EXPR,
|
BOX_EXPR,
|
||||||
CALL_EXPR,
|
CALL_EXPR,
|
||||||
INDEX_EXPR,
|
INDEX_EXPR,
|
||||||
|
|
|
@ -16,9 +16,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
expr_extensions::{
|
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
|
||||||
ArrayExprKind, BinOp, BlockModifier, ElseBranch, LiteralKind, PrefixOp, RangeOp,
|
|
||||||
},
|
|
||||||
extensions::{
|
extensions::{
|
||||||
AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
|
AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
|
||||||
StructKind, TypeBoundKind, VisibilityKind,
|
StructKind, TypeBoundKind, VisibilityKind,
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl ast::Expr {
|
||||||
| ast::Expr::WhileExpr(_)
|
| ast::Expr::WhileExpr(_)
|
||||||
| ast::Expr::BlockExpr(_)
|
| ast::Expr::BlockExpr(_)
|
||||||
| ast::Expr::MatchExpr(_)
|
| ast::Expr::MatchExpr(_)
|
||||||
| ast::Expr::TryExpr(_) => true,
|
| ast::Expr::TryBlockExpr(_) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,22 +359,7 @@ impl ast::Literal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum BlockModifier {
|
|
||||||
Async(SyntaxToken),
|
|
||||||
Unsafe(SyntaxToken),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ast::BlockExpr {
|
impl ast::BlockExpr {
|
||||||
pub fn modifier(&self) -> Option<BlockModifier> {
|
|
||||||
if let Some(token) = self.async_token() {
|
|
||||||
return Some(BlockModifier::Async(token));
|
|
||||||
}
|
|
||||||
if let Some(token) = self.unsafe_token() {
|
|
||||||
return Some(BlockModifier::Unsafe(token));
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// false if the block is an intrinsic part of the syntax and can't be
|
/// false if the block is an intrinsic part of the syntax and can't be
|
||||||
/// replaced with arbitrary expression.
|
/// replaced with arbitrary expression.
|
||||||
///
|
///
|
||||||
|
@ -383,15 +368,15 @@ impl ast::BlockExpr {
|
||||||
/// const FOO: () = { stand_alone };
|
/// const FOO: () = { stand_alone };
|
||||||
/// ```
|
/// ```
|
||||||
pub fn is_standalone(&self) -> bool {
|
pub fn is_standalone(&self) -> bool {
|
||||||
if self.modifier().is_some() {
|
if self.unsafe_token().is_some() || self.async_token().is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let parent = match self.syntax().parent() {
|
let kind = match self.syntax().parent() {
|
||||||
Some(it) => it,
|
|
||||||
None => return true,
|
None => return true,
|
||||||
|
Some(it) => it.kind(),
|
||||||
};
|
};
|
||||||
match parent.kind() {
|
match kind {
|
||||||
FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR => false,
|
FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,6 +475,16 @@ impl LoopExpr {
|
||||||
pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) }
|
pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct TryBlockExpr {
|
||||||
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
}
|
||||||
|
impl ast::AttrsOwner for TryBlockExpr {}
|
||||||
|
impl TryBlockExpr {
|
||||||
|
pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) }
|
||||||
|
pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct ForExpr {
|
pub struct ForExpr {
|
||||||
pub(crate) syntax: SyntaxNode,
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
@ -1467,6 +1477,7 @@ pub enum Expr {
|
||||||
FieldExpr(FieldExpr),
|
FieldExpr(FieldExpr),
|
||||||
AwaitExpr(AwaitExpr),
|
AwaitExpr(AwaitExpr),
|
||||||
TryExpr(TryExpr),
|
TryExpr(TryExpr),
|
||||||
|
TryBlockExpr(TryBlockExpr),
|
||||||
CastExpr(CastExpr),
|
CastExpr(CastExpr),
|
||||||
RefExpr(RefExpr),
|
RefExpr(RefExpr),
|
||||||
PrefixExpr(PrefixExpr),
|
PrefixExpr(PrefixExpr),
|
||||||
|
@ -1949,6 +1960,17 @@ impl AstNode for LoopExpr {
|
||||||
}
|
}
|
||||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||||
}
|
}
|
||||||
|
impl AstNode for TryBlockExpr {
|
||||||
|
fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_BLOCK_EXPR }
|
||||||
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
|
if Self::can_cast(syntax.kind()) {
|
||||||
|
Some(Self { syntax })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||||
|
}
|
||||||
impl AstNode for ForExpr {
|
impl AstNode for ForExpr {
|
||||||
fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR }
|
fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR }
|
||||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||||
|
@ -3290,6 +3312,9 @@ impl From<AwaitExpr> for Expr {
|
||||||
impl From<TryExpr> for Expr {
|
impl From<TryExpr> for Expr {
|
||||||
fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) }
|
fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) }
|
||||||
}
|
}
|
||||||
|
impl From<TryBlockExpr> for Expr {
|
||||||
|
fn from(node: TryBlockExpr) -> Expr { Expr::TryBlockExpr(node) }
|
||||||
|
}
|
||||||
impl From<CastExpr> for Expr {
|
impl From<CastExpr> for Expr {
|
||||||
fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) }
|
fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) }
|
||||||
}
|
}
|
||||||
|
@ -3320,8 +3345,9 @@ impl AstNode for Expr {
|
||||||
TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
|
TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
|
||||||
| LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
|
| LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
|
||||||
| BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
|
| BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
|
||||||
| METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | CAST_EXPR | REF_EXPR
|
| METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR
|
||||||
| PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL | BOX_EXPR => true,
|
| CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL
|
||||||
|
| BOX_EXPR => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3349,6 +3375,7 @@ impl AstNode for Expr {
|
||||||
FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
|
FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
|
||||||
AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
|
AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
|
||||||
TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
|
TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
|
||||||
|
TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }),
|
||||||
CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
|
CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
|
||||||
REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
|
REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
|
||||||
PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
|
PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
|
||||||
|
@ -3385,6 +3412,7 @@ impl AstNode for Expr {
|
||||||
Expr::FieldExpr(it) => &it.syntax,
|
Expr::FieldExpr(it) => &it.syntax,
|
||||||
Expr::AwaitExpr(it) => &it.syntax,
|
Expr::AwaitExpr(it) => &it.syntax,
|
||||||
Expr::TryExpr(it) => &it.syntax,
|
Expr::TryExpr(it) => &it.syntax,
|
||||||
|
Expr::TryBlockExpr(it) => &it.syntax,
|
||||||
Expr::CastExpr(it) => &it.syntax,
|
Expr::CastExpr(it) => &it.syntax,
|
||||||
Expr::RefExpr(it) => &it.syntax,
|
Expr::RefExpr(it) => &it.syntax,
|
||||||
Expr::PrefixExpr(it) => &it.syntax,
|
Expr::PrefixExpr(it) => &it.syntax,
|
||||||
|
@ -3865,6 +3893,11 @@ impl std::fmt::Display for LoopExpr {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl std::fmt::Display for TryBlockExpr {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
|
}
|
||||||
|
}
|
||||||
impl std::fmt::Display for ForExpr {
|
impl std::fmt::Display for ForExpr {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
std::fmt::Display::fmt(self.syntax(), f)
|
std::fmt::Display::fmt(self.syntax(), f)
|
||||||
|
|
|
@ -162,6 +162,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
|
||||||
"RECORD_LIT",
|
"RECORD_LIT",
|
||||||
"RECORD_FIELD_LIST",
|
"RECORD_FIELD_LIST",
|
||||||
"RECORD_FIELD",
|
"RECORD_FIELD",
|
||||||
|
"TRY_BLOCK_EXPR",
|
||||||
"BOX_EXPR",
|
"BOX_EXPR",
|
||||||
// postfix
|
// postfix
|
||||||
"CALL_EXPR",
|
"CALL_EXPR",
|
||||||
|
@ -439,6 +440,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
|
||||||
}
|
}
|
||||||
struct IfExpr: AttrsOwner { T![if], Condition }
|
struct IfExpr: AttrsOwner { T![if], Condition }
|
||||||
struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
|
struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
|
||||||
|
struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr }
|
||||||
struct ForExpr: AttrsOwner, LoopBodyOwner {
|
struct ForExpr: AttrsOwner, LoopBodyOwner {
|
||||||
T![for],
|
T![for],
|
||||||
Pat,
|
Pat,
|
||||||
|
@ -720,6 +722,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
|
||||||
FieldExpr,
|
FieldExpr,
|
||||||
AwaitExpr,
|
AwaitExpr,
|
||||||
TryExpr,
|
TryExpr,
|
||||||
|
TryBlockExpr,
|
||||||
CastExpr,
|
CastExpr,
|
||||||
RefExpr,
|
RefExpr,
|
||||||
PrefixExpr,
|
PrefixExpr,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue