From 1e20467c3a62f0b8a65605938a2ddb7babcfd8bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 1 May 2020 15:29:03 +0300 Subject: Bump deps --- crates/ra_syntax/src/parsing/lexer.rs | 37 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs index f450ef4a2..1a5a6dc06 100644 --- a/crates/ra_syntax/src/parsing/lexer.rs +++ b/crates/ra_syntax/src/parsing/lexer.rs @@ -180,7 +180,7 @@ fn rustc_token_kind_to_syntax_kind( return (syntax_kind, None); fn match_literal_kind(kind: &rustc_lexer::LiteralKind) -> (SyntaxKind, Option<&'static str>) { - use rustc_lexer::LiteralKind as LK; + use rustc_lexer::{LexRawStrError, LiteralKind as LK}; #[rustfmt::skip] let syntax_kind = match *kind { @@ -215,21 +215,28 @@ fn rustc_token_kind_to_syntax_kind( return (BYTE_STRING, Some("Missing trailing `\"` symbol to terminate the byte string literal")) } - LK::RawStr { started: true, terminated: true, .. } => RAW_STRING, - LK::RawStr { started: true, terminated: false, .. } => { - return (RAW_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw string literal")) - } - LK::RawStr { started: false, .. } => { - return (RAW_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw string literal")) - } + LK::RawStr(str) => match str.validate() { + Ok(_) => RAW_STRING, + Err(LexRawStrError::InvalidStarter) => return (RAW_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw string literal")), + Err(LexRawStrError::NoTerminator { expected, found, .. }) => if expected == found { + return (RAW_STRING, Some("Missing trailing `\"` to terminate the raw string literal")) + } else { + return (RAW_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw string literal")) + + }, + Err(LexRawStrError::TooManyDelimiters { .. }) => return (RAW_STRING, Some("Too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols")), + }, + LK::RawByteStr(str) => match str.validate() { + Ok(_) => RAW_BYTE_STRING, + Err(LexRawStrError::InvalidStarter) => return (RAW_BYTE_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw byte string literal")), + Err(LexRawStrError::NoTerminator { expected, found, .. }) => if expected == found { + return (RAW_BYTE_STRING, Some("Missing trailing `\"` to terminate the raw byte string literal")) + } else { + return (RAW_BYTE_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw byte string literal")) - LK::RawByteStr { started: true, terminated: true, .. } => RAW_BYTE_STRING, - LK::RawByteStr { started: true, terminated: false, .. } => { - return (RAW_BYTE_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw byte string literal")) - } - LK::RawByteStr { started: false, .. } => { - return (RAW_BYTE_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw byte string literal")) - } + }, + Err(LexRawStrError::TooManyDelimiters { .. }) => return (RAW_BYTE_STRING, Some("Too many `#` symbols: raw byte strings may be delimited by up to 65535 `#` symbols")), + }, }; (syntax_kind, None) -- cgit v1.2.3 From 3bb46042fb5b8ee421e350c54079cb68b4edc996 Mon Sep 17 00:00:00 2001 From: John Renner Date: Fri, 1 May 2020 08:59:24 -0700 Subject: Validate uses of self and super --- crates/ra_syntax/src/ast/generated/nodes.rs | 2 + crates/ra_syntax/src/validation.rs | 119 +++++++++++++++++----------- 2 files changed, 73 insertions(+), 48 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index d2253d4af..2096f12f1 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs @@ -1251,6 +1251,8 @@ pub struct PathSegment { impl PathSegment { pub fn coloncolon_token(&self) -> Option { support::token(&self.syntax, T![::]) } pub fn crate_token(&self) -> Option { support::token(&self.syntax, T![crate]) } + pub fn self_token(&self) -> Option { support::token(&self.syntax, T![self]) } + pub fn super_token(&self) -> Option { support::token(&self.syntax, T![super]) } pub fn l_angle_token(&self) -> Option { support::token(&self.syntax, T![<]) } pub fn name_ref(&self) -> Option { support::child(&self.syntax) } pub fn type_arg_list(&self) -> Option { support::child(&self.syntax) } diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index f0b3dec63..e075cd801 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs @@ -96,7 +96,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec { ast::RecordField(it) => validate_numeric_name(it.name_ref(), &mut errors), ast::Visibility(it) => validate_visibility(it, &mut errors), ast::RangeExpr(it) => validate_range_expr(it, &mut errors), - ast::PathSegment(it) => validate_crate_keyword_in_path_segment(it, &mut errors), + ast::PathSegment(it) => validate_path_keywords(it, &mut errors), _ => (), } } @@ -224,59 +224,82 @@ fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec) { } } -fn validate_crate_keyword_in_path_segment( - segment: ast::PathSegment, - errors: &mut Vec, -) { - const ERR_MSG: &str = "The `crate` keyword is only allowed as the first segment of a path"; +fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec) { + use ast::PathSegmentKind; - let crate_token = match segment.crate_token() { - None => return, - Some(it) => it, - }; + let path = segment.parent_path(); + let is_path_start = segment.coloncolon_token().is_none() && path.qualifier().is_none(); + + if let Some(token) = segment.self_token() { + if !is_path_start { + errors.push(SyntaxError::new( + "The `self` keyword is only allowed as the first segment of a path", + token.text_range(), + )); + } + } else if let Some(token) = segment.crate_token() { + if !is_path_start || use_prefix(path).is_some() { + errors.push(SyntaxError::new( + "The `crate` keyword is only allowed as the first segment of a path", + token.text_range(), + )); + } + } else if let Some(token) = segment.super_token() { + if !all_supers(&path) { + errors.push(SyntaxError::new( + "The `super` keyword may only be preceded by other `super`s", + token.text_range(), + )); + return; + } - // Disallow both ::crate and foo::crate - let mut path = segment.parent_path(); - if segment.coloncolon_token().is_some() || path.qualifier().is_some() { - errors.push(SyntaxError::new(ERR_MSG, crate_token.text_range())); - return; + let mut curr_path = path; + while let Some(prefix) = use_prefix(curr_path) { + if !all_supers(&prefix) { + errors.push(SyntaxError::new( + "The `super` keyword may only be preceded by other `super`s", + token.text_range(), + )); + return; + } + curr_path = prefix; + } } - // For expressions and types, validation is complete, but we still have - // to handle invalid UseItems like this: - // - // use foo:{crate::bar::baz}; - // - // To handle this we must inspect the parent `UseItem`s and `UseTree`s - // but right now we're looking deep inside the nested `Path` nodes because - // `Path`s are left-associative: - // - // ((crate)::bar)::baz) - // ^ current value of path - // - // So we need to climb to the top - while let Some(parent) = path.parent_path() { - path = parent; + fn use_prefix(mut path: ast::Path) -> Option { + for node in path.syntax().ancestors().skip(1) { + match_ast! { + match node { + ast::UseTree(it) => if let Some(tree_path) = it.path() { + // Even a top-level path exists within a `UseTree` so we must explicitly + // allow our path but disallow anything else + if tree_path != path { + return Some(tree_path); + } + }, + ast::UseTreeList(_it) => continue, + ast::Path(parent) => path = parent, + _ => return None, + } + }; + } + return None; } - // Now that we've found the whole path we need to see if there's a prefix - // somewhere in the UseTree hierarchy. This check is arbitrarily deep - // because rust allows arbitrary nesting like so: - // - // use {foo::{{{{crate::bar::baz}}}}}; - for node in path.syntax().ancestors().skip(1) { - match_ast! { - match node { - ast::UseTree(it) => if let Some(tree_path) = it.path() { - // Even a top-level path exists within a `UseTree` so we must explicitly - // allow our path but disallow anything else - if tree_path != path { - errors.push(SyntaxError::new(ERR_MSG, crate_token.text_range())); - } - }, - ast::UseTreeList(_it) => continue, - _ => return, - } + fn all_supers(path: &ast::Path) -> bool { + let segment = match path.segment() { + Some(it) => it, + None => return false, }; + + if segment.kind() != Some(PathSegmentKind::SuperKw) { + return false; + } + + if let Some(ref subpath) = path.qualifier() { + return all_supers(subpath); + } + + return true; } } -- cgit v1.2.3 From 375dd18dc0cc258f4e8c99a91b88030d32147965 Mon Sep 17 00:00:00 2001 From: Diana <5275194+DianaNites@users.noreply.github.com> Date: Fri, 1 May 2020 12:09:47 -0400 Subject: Fix pub(self) visibility? Clippy complained about it and it seems wrong --- crates/ra_syntax/src/ast/extensions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index f2ea5088e..45e3dd2d3 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs @@ -407,7 +407,7 @@ impl ast::Visibility { } else if self.super_token().is_some() { VisibilityKind::PubSuper } else if self.self_token().is_some() { - VisibilityKind::PubSuper + VisibilityKind::PubSelf } else { VisibilityKind::Pub } -- cgit v1.2.3 From fd030f9450ed6910677e30f8fa65b06e71fcffa2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 01:12:37 +0200 Subject: Revert "Merge #4233" This reverts commit a5f2b16366f027ad60c58266a66eb7fbdcbda9f9, reversing changes made to c96b2180c1c4206a0a98c280b4d30897eb116336. --- crates/ra_syntax/src/ast.rs | 4 +--- crates/ra_syntax/src/ast/expr_extensions.rs | 27 +++++---------------- crates/ra_syntax/src/ast/generated/nodes.rs | 37 +++++++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 26 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 521ca8ab8..a716e525b 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -16,9 +16,7 @@ use crate::{ }; pub use self::{ - expr_extensions::{ - ArrayExprKind, BinOp, BlockModifier, ElseBranch, LiteralKind, PrefixOp, RangeOp, - }, + expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp}, extensions::{ AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind, diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index 352c0d2c5..ecf74fd36 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs @@ -16,7 +16,7 @@ impl ast::Expr { | ast::Expr::WhileExpr(_) | ast::Expr::BlockExpr(_) | ast::Expr::MatchExpr(_) - | ast::Expr::TryExpr(_) => true, + | ast::Expr::TryBlockExpr(_) => true, _ => false, } } @@ -359,22 +359,7 @@ impl ast::Literal { } } -pub enum BlockModifier { - Async(SyntaxToken), - Unsafe(SyntaxToken), -} - impl ast::BlockExpr { - pub fn modifier(&self) -> Option { - 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 /// replaced with arbitrary expression. /// @@ -383,15 +368,15 @@ impl ast::BlockExpr { /// const FOO: () = { stand_alone }; /// ``` pub fn is_standalone(&self) -> bool { - if self.modifier().is_some() { + if self.unsafe_token().is_some() || self.async_token().is_some() { return false; } - let parent = match self.syntax().parent() { - Some(it) => it, + let kind = match self.syntax().parent() { None => return true, + Some(it) => it.kind(), }; - match parent.kind() { - FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR => false, + match kind { + FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false, _ => true, } } diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index 3f16592b6..2096f12f1 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs @@ -475,6 +475,16 @@ impl LoopExpr { pub fn loop_token(&self) -> Option { 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 { support::token(&self.syntax, T![try]) } + pub fn body(&self) -> Option { support::child(&self.syntax) } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ForExpr { pub(crate) syntax: SyntaxNode, @@ -1467,6 +1477,7 @@ pub enum Expr { FieldExpr(FieldExpr), AwaitExpr(AwaitExpr), TryExpr(TryExpr), + TryBlockExpr(TryBlockExpr), CastExpr(CastExpr), RefExpr(RefExpr), PrefixExpr(PrefixExpr), @@ -1949,6 +1960,17 @@ impl AstNode for LoopExpr { } 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 { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for ForExpr { fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR } fn cast(syntax: SyntaxNode) -> Option { @@ -3290,6 +3312,9 @@ impl From for Expr { impl From for Expr { fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) } } +impl From for Expr { + fn from(node: TryBlockExpr) -> Expr { Expr::TryBlockExpr(node) } +} impl From for Expr { 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 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | 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 - | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL | BOX_EXPR => true, + | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR + | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL + | BOX_EXPR => true, _ => false, } } @@ -3349,6 +3375,7 @@ impl AstNode for Expr { FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }), AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }), TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), + TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }), CAST_EXPR => Expr::CastExpr(CastExpr { syntax }), REF_EXPR => Expr::RefExpr(RefExpr { syntax }), PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }), @@ -3385,6 +3412,7 @@ impl AstNode for Expr { Expr::FieldExpr(it) => &it.syntax, Expr::AwaitExpr(it) => &it.syntax, Expr::TryExpr(it) => &it.syntax, + Expr::TryBlockExpr(it) => &it.syntax, Expr::CastExpr(it) => &it.syntax, Expr::RefExpr(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) } } +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 { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) -- cgit v1.2.3 From 4f2134cc33f07c09fe166cec42971828843bc0ef Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 2 May 2020 01:18:19 +0200 Subject: Introduce EffectExpr --- crates/ra_syntax/src/ast.rs | 2 +- crates/ra_syntax/src/ast/edit.rs | 2 +- crates/ra_syntax/src/ast/expr_extensions.rs | 40 ++++++++++++---- crates/ra_syntax/src/ast/generated/nodes.rs | 74 ++++++++++------------------- crates/ra_syntax/src/ast/make.rs | 4 +- crates/ra_syntax/src/lib.rs | 7 ++- crates/ra_syntax/src/validation/block.rs | 20 ++++---- 7 files changed, 73 insertions(+), 76 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index a716e525b..1876afe95 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -16,7 +16,7 @@ use crate::{ }; pub use self::{ - expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp}, + expr_extensions::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, extensions::{ AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind, diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs index 26e4576ff..c507dc683 100644 --- a/crates/ra_syntax/src/ast/edit.rs +++ b/crates/ra_syntax/src/ast/edit.rs @@ -28,7 +28,7 @@ impl ast::BinExpr { impl ast::FnDef { #[must_use] - pub fn with_body(&self, body: ast::Block) -> ast::FnDef { + pub fn with_body(&self, body: ast::BlockExpr) -> ast::FnDef { let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() { old_body.syntax().clone().into() diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index ecf74fd36..7ee36e60c 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs @@ -16,7 +16,7 @@ impl ast::Expr { | ast::Expr::WhileExpr(_) | ast::Expr::BlockExpr(_) | ast::Expr::MatchExpr(_) - | ast::Expr::TryBlockExpr(_) => true, + | ast::Expr::EffectExpr(_) => true, _ => false, } } @@ -359,6 +359,33 @@ impl ast::Literal { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Effect { + Async(SyntaxToken), + Unsafe(SyntaxToken), + Try(SyntaxToken), + // Very much not an effect, but we stuff it into this node anyway + Label(ast::Label), +} + +impl ast::EffectExpr { + pub fn effect(&self) -> Effect { + if let Some(token) = self.async_token() { + return Effect::Async(token); + } + if let Some(token) = self.unsafe_token() { + return Effect::Unsafe(token); + } + if let Some(token) = self.try_token() { + return Effect::Try(token); + } + if let Some(label) = self.label() { + return Effect::Label(label); + } + unreachable!("ast::EffectExpr without Effect") + } +} + impl ast::BlockExpr { /// false if the block is an intrinsic part of the syntax and can't be /// replaced with arbitrary expression. @@ -368,15 +395,12 @@ impl ast::BlockExpr { /// const FOO: () = { stand_alone }; /// ``` pub fn is_standalone(&self) -> bool { - if self.unsafe_token().is_some() || self.async_token().is_some() { - return false; - } - let kind = match self.syntax().parent() { + let parent = match self.syntax().parent() { + Some(it) => it, None => return true, - Some(it) => it.kind(), }; - match kind { - FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false, + match parent.kind() { + FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | EFFECT_EXPR => false, _ => true, } } diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index 2096f12f1..5e844d5ae 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs @@ -476,13 +476,16 @@ impl LoopExpr { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TryBlockExpr { +pub struct EffectExpr { pub(crate) syntax: SyntaxNode, } -impl ast::AttrsOwner for TryBlockExpr {} -impl TryBlockExpr { +impl ast::AttrsOwner for EffectExpr {} +impl EffectExpr { + pub fn label(&self) -> Option